2017-12-03

# hints for programming bezier curve calculations

cubic: two control points

alternatives: cubic hermite, centripetal catmull-rom, b-spline

animated-bezier interactive animations

bezierinfo explanations

bezierjs interactive examples for various bezier curve related calculations

curved-paths shows some caveats with practical usage

tinyspline c library for nurbs, b-splines and bezier curves

# example implementations in scheme

## using the "de casteljau" algorithm

```(define (bezier-curve n . points)
"number:0..1 #(number ...) ... -> #(number ...)
get a point for a bezier curve at fractional offset n.
no limit on the number of control points.
no limit on the dimension of point vectors.
at least one point must be given.
uses the \"de casteljau\" algorithm"
(if (null? (tail points)) (first points)
(let ((left n) (right (- 1 n)))
; length of points is reduced by one for each recursive call
(apply bezier-curve n
(pair-fold-right
(l (a result)
; ignore last point
(if (null? (tail a)) result
(let ((p1 (first a)) (p2 (second a)))
(pair
(vector-map
; map all point dimensions
(l (p1-d p2-d)
(+ (* right p1-d) (* left p2-d)))
p1 p2)
result))))
null points)))))```

to generate the first point

`(bezier-curve 0 (vector 0 10) (vector 10 50) (vector 5 20) (vector 8 20))`

## optimised for only cubic bezier curves

```(define (cubic-bezier-curve n p1 p2 p3 p4)
"number vector ... -> vector
return coordinates for one point of a cubic 4-point bezier curve at fractional offset n.
the intermediate points between p1 and p4 are the control points.
there is no limit on the dimensions of point vectors"
(let*
( (left n)
(right (- 1 n))
(l-square (* left left))
(r-square (* right right))
(l-cube (* left l-square))
(r-cube (* right r-square))
(l-square (* 3 right l-square))
(r-square (* 3 left r-square)))
(apply vector-map
; map all point dimensions
(l (d1 d2 d3 d4)
(+ (* r-cube d1) (* l-square d2) (* r-square d3) (* l-cube d4)))
p1 p2 p3 p4)))```

# example implementation in coffeescript / javascript

```cubic_bezier_curve = (n, p1, p2, p3, p4) ->
# number [number, number] ... -> [number, number]
# return coordinates for one point of a cubic bezier curve at fractional offset n
left = n
right = 1 - left
l_cube = Math.pow left, 3
r_cube = Math.pow right, 3
l_square = 3 * right * Math.pow(left, 2)
r_square = 3 * left * Math.pow(right, 2)
x =
r_cube * p1[0] +
l_square * p2[0] +
r_square * p3[0] +
l_cube * p4[0]
y =
r_cube * p1[1] +
l_square * p2[1] +
r_square * p3[1] +
l_cube * p4[1]
[x, y]```
`cubic_bezier_curve 0, 100, [0, 10], [10, 50], [5, 20], [8, 20]`

tags: programming scheme start document guide example computer bezier curve