src/points.lisp @ 29b2d3f28208

Episode 20: More Bezier Curves (A)
author Steve Losh <steve@stevelosh.com>
date Mon, 09 May 2016 00:18:57 +0000
parents 7a40282385de
children 564d579c018b
(in-package #:coding-math.points)

(defun quadratic-bezier (from to control n)
  (vec-lerp (vec-lerp from control n)
            (vec-lerp control to n)
            n))

(defun fast-quadratic-bezier (from to control n
                              &optional (destination (make-vec)))
  (with-vecs ((fx fy) from
              (tx ty) to
              (cx cy) control)
    (setf (vec-x destination)
          (+ (* (square (- 1 n)) fx)
             (* 2 (- 1 n) n cx)
             (* n n tx))
          (vec-y destination)
          (+ (* (square (- 1 n)) fy)
             (* 2 (- 1 n) n cy)
             (* n n ty))))
  destination)


(defun cubic-bezier (from to control-1 control-2 n)
  (vec-lerp (vec-lerp (vec-lerp from control-1 n)
                      (vec-lerp control-1 control-2 n)
                      n)
            (vec-lerp (vec-lerp control-1 control-2 n)
                      (vec-lerp control-2 to n)
                      n)
            n))


(declaim (inline draw-function))
(defun draw-function (fn &key (start 0.0) (end 1.0))
  (let ((steps (sketch::pen-curve-steps (sketch::env-pen sketch::*env*))))
    (apply #'polyline
           (mapcan (compose (rcurry #'coerce 'list) fn)
                   (iota (1+ steps)
                         :start 0.0
                         :step (/ (- end start) steps))))))

(defun quadratic-bezier-curve (from to control)
  (draw-function (curry #'fast-quadratic-bezier from to control)))


; (defun multicurve (points)
;   (loop :for (p0 p1 . remaining) :on points
;         :when remaining
;         :for midx = (/ (+ (vec-x p0) (vec-x p1)) 2)
;         :for midy = (/ (+ (vec-y p0) (vec-y p1)) 2)
;         )
  
;   )