aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorColin Okay <colin@cicadas.surf>2022-07-18 08:45:21 -0500
committerColin Okay <colin@cicadas.surf>2022-07-18 08:45:21 -0500
commita1bfda1b34afffaf3ea757c3720bbc1762c6cd99 (patch)
tree6562eb4f0b579e941ce9d4cf798399f3f8f78d6d /src
parent9c70ea0c20a61f9192e74ce537a4976e39e663d9 (diff)
[add] bezier curve surrport
Diffstat (limited to 'src')
-rw-r--r--src/grid-geometry.lisp12
-rw-r--r--src/utils.lisp34
2 files changed, 46 insertions, 0 deletions
diff --git a/src/grid-geometry.lisp b/src/grid-geometry.lisp
index 218cdf2..b23b207 100644
--- a/src/grid-geometry.lisp
+++ b/src/grid-geometry.lisp
@@ -99,3 +99,15 @@ top right corners of the bounding box for POLY "
(loop for ,y from (- ,sy ,rad) to (+ ,sy ,rad) do
(when (,comparator ,rad (round (euclidean-dist ,x ,y ,sx ,sy)))
,@body)))))))
+
+
+(defmacro with-grid-bezier
+ ((x y) (control-pts &key (step 0.001)) &body body)
+ (with-gensyms (fn points a)
+ `(let* ((,points
+ ,control-pts)
+ (,fn
+ (apply #'bezier-lambda ,points)))
+ (loop for ,a from 0.0 to 1.0 by ,step
+ for (,x ,y) = (mapcar #'round (funcall ,fn ,a))
+ do ,@body))))
diff --git a/src/utils.lisp b/src/utils.lisp
index 7b68e3d..4a35aee 100644
--- a/src/utils.lisp
+++ b/src/utils.lisp
@@ -116,3 +116,37 @@ the path."
(let ((dx (- x2 x1))
(dy (- y2 y1)))
(sqrt (+ (* dx dx) (* dy dy)))))
+
+(let ((cache
+ (make-array 100 :adjustable t :initial-element nibbles:)))
+ (defun factorial (n)
+ (cond
+ ((zerop n) 1)
+ ((< n (length cache))
+ (or (aref cache n)
+ (setf (aref cache n)
+ (* n (factorial (1- n))))))
+ ((>= n (length cache))
+ (setf cache (adjust-array cache (* 2 (length cache))))
+ (factorial n)))))
+
+(defun binomial-coefficient (n k)
+ (/ (factorial n)
+ (* (factorial k) (factorial (- n k)))))
+
+(defun bezier-lambda (&rest points)
+ (let* ((n
+ (1- (length points)))
+ (bin-coeffs
+ (loop for i from 0 to n collect (binomial-coefficient n i))))
+ (lambda (a)
+ (loop for (x y) in points
+ for i from 0
+ for bin-coeff in bin-coeffs
+ for coeff = (* bin-coeff
+ (expt (- 1 a) (- n i))
+ (expt a i))
+ sum (* coeff x) into bx
+ sum (* coeff y) into by
+ finally (return (list bx by))))))
+