diff options
author | Christian Hodgden <chrhodgden@gmail.com> | 2024-07-26 13:31:50 -0500 |
---|---|---|
committer | Christian Hodgden <chrhodgden@gmail.com> | 2024-07-26 13:31:50 -0500 |
commit | 090e8411056636780ecc3be25dce46cdb31457ca (patch) | |
tree | 718c236faf8bc9b3a7ed2fa00c011b51538a5190 | |
parent | 229cb6ff49be32fd09c439fbf61e4b81b4965c5d (diff) |
discovered De Castlejau's algorithm
The recusion prevents the need for using the Bernstein polynomial.
-rw-r--r-- | chess/bezier.scad | 20 | ||||
-rw-r--r-- | chess/demo.scad | 19 |
2 files changed, 21 insertions, 18 deletions
diff --git a/chess/bezier.scad b/chess/bezier.scad index 4a75cb6..4566d71 100644 --- a/chess/bezier.scad +++ b/chess/bezier.scad @@ -30,17 +30,27 @@ function bezier_p0(point, degree, index, t) = binomial_coefficient(degree, index) * ((1 - t) ^ (degree - index)) * (t ^ index) * point; function bezier_p(points, t) = - [for (i=[1:len(points[0])]) sum(bezier_p0(points[i], len(points) - 1, i, t))]; + [for (i=[1:len(points)-1]) sum(bezier_p0(points[i], len(points)-1, i, t))]; function bezier_p_debug(points, t) = - [for (i=[1:len(points[0])]) sum(bezier_p0(points[i], len(points) - 1, i, t))]; + [for (i=[1:len(points)-2]) sum(bezier_p0(points[i], len(points)+1, i, t))]; +function de_casteljau(points, t) = + len(points) == 1 ? + points[0] : + de_casteljau( + [for (i = [0:len(points)-2]) (1 - t) * points[i] + t * points[i + 1]], + t + ) ; + +function bezier_curve(points, $fn=$fn) = + [for (i = [0:$fn]) de_casteljau(points, i / $fn)] ; + p0 = [0, 0]; p1 = [10, 0]; pb = [1, 5]; pn = [0, 10]; - points = $fn; points_list = [for (i=[0:points]) bezier_3(p0, p1, pn, i/points)]; @@ -57,9 +67,9 @@ translate([20, 0, 0]) p_set_1 = [p0, p1, pn]; p_set_2 = [p0, p1, pb, pn]; -points_list_p1 = [for (i=[0:$fn]) bezier_p(p_set_1, i/$fn)]; +points_list_p1 = bezier_curve(p_set_1); points_list_p2 = [for (i=[0:$fn]) bezier_p(p_set_2, i/$fn)]; -points_list_p2d = [for (i=[0:$fn]) bezier_p_debug(p_set_2, i/$fn)]; +points_list_p2d = bezier_curve(p_set_2); for (i=[0:$fn]) { echo("i", i, bezier_p(p_set_2, i/$fn)); diff --git a/chess/demo.scad b/chess/demo.scad index 7820f67..ec80514 100644 --- a/chess/demo.scad +++ b/chess/demo.scad @@ -3,19 +3,12 @@ function bezier(points, t) = bezier([for (i = [0:len(points)-2]) (1 - t) * points[i] + t * points[i + 1]], t); -function bezier_curve(points, steps) = - [for (i = [0:steps]) bezier(points, i / steps)]; +function bezier_curve(points, $fn=$fn) = + [for (i = [0:$fn]) bezier(points, i / $fn)]; -points = [[0, 0], [10, 0], [1, 5], [0, 10]]; -steps = 100; -curve = bezier_curve(points, steps); +points = [[0, 0], [10, 0], [1, 5], [20, 1], [0, 10]]; +$fn = 100; + +curve = bezier_curve(points); polygon(curve); - -// alt - -points2 = [[0, 0, 0], [10, 0, 5], [1, 5, 10], [0, 10, 15]]; -// steps = 100; -curve2 = bezier_curve(points2, steps); - -polyhedron(points=curve2, faces=[[for (i=[0:len(curve2)-2]) [i, i+1]]]); |