Skip to content

Instantly share code, notes, and snippets.

@toomasv toomasv/bezier.red

Last active Mar 23, 2018
Embed
What would you like to do?
Digging deeper into curves
Red [
Author: "Toomas Vooglaid"
Date: 2018-03-19
Inspiration: https://pomax.github.io/bezierinfo
]
lut: [[1][1 1][1 2 1][1 3 3 1][1 4 6 4 1][1 5 10 10 5 1][1 6 15 20 15 6 1]]
binomial: func [n k /local s nextRow i prev][
while [
n > s: length? lut
][
nextRow: make block! s + 1
prev: s - 1
repeat i prev [
append nextRow lut/:s/:i + lut/:s/(i + 1)
]
append/only lut append insert nextRow 1 1
]
lut/:n/:k
]
bezier2a: func [t /local t2 mt mt2][
t2: t * t
mt: 1 - t
mt2: mt * mt
return mt2 + 2 * mt * t + t2
]
;probe points: collect [repeat i 11 [keep reduce [as-pair (i - 1 * 10) 100 - (100 * bezier2a i - 1 / 10.0)]]]
;[0x100 10x73 20x53 30x38 40x27 50x18 60x12 70x7 80x3 90x0 100x0]
;view compose/deep [box 150x150 draw [box 0x0 100x100 pen red spline (points)]]
;bezier: func [n t w /local sum k][sum: 0 repeat k n [sum: sum + (w/:k * (binomial n k) * ((1 - t) ** (n - k)) * (t ** k))] sum]
bezier: func [t w /local sum-x sum-y k n][
n: length? w
sum-x: 0 sum-y: 0
repeat k n [
sum-x: sum-x + (w/:k/x * (binomial n k) * ((1 - t) ** (n - k)) * (t ** (k - 1)))
sum-y: sum-y + (w/:k/y * (binomial n k) * ((1 - t) ** (n - k)) * (t ** (k - 1)))
]
as-pair sum-x sum-y
]
bezier2: func [t w /local t2 mt mt2][
t2: t * t
mt: 1 - t
mt2: mt * mt
as-pair
(w/1/x * mt2) + (2 * w/2/x * mt * t) + (w/3/x * t2)
(w/1/y * mt2) + (2 * w/2/y * mt * t) + (w/3/y * t2)
]
bezier3: func [t w /local t2 t3 mt mt2 mt3][
t2: t * t
t3: t2 * t
mt: 1 - t
mt2: mt * mt
mt3: mt2 * mt
as-pair
(w/1/x * mt3) + (3 * w/2/x * mt2 * t) + (3 * w/3/x * mt * t2) + (w/4/x * t3)
(w/1/y * mt3) + (3 * w/2/y * mt2 * t) + (3 * w/3/y * mt * t2) + (w/4/y * t3)
]
;comment [
;Example
points: [130x50 200x50 400x700 800x150 400x-1200 150x1200 -50x150 50x50 130x50];[0x0 100x200 200x0];[120x160 35x200 220x260 220x40]
tick: 0
view/tight compose/deep [
box 500x300 rate 50 draw [
pen off
line (points)
;line-width 2 pen black
; curve (points)
line-width 1.75 pen brick
c1: circle (points/1) 15
fill-pen brick
c2: circle (points/1) 6
c3: rotate (points/1) 0 [circle (points/1 + 0x-15) 2]
]
on-time [
tick: tick + 1
c1/2: c2/2: c3/3: bezier tick % 360 / 360.0 points
c3/4/2: c3/3 + 0x-15
c3/2: tick % 360 * 3
]
]
;]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.