diff --git a/docs/lib-golden_spiral.md b/docs/lib-golden_spiral.md new file mode 100644 index 00000000..204925e8 --- /dev/null +++ b/docs/lib-golden_spiral.md @@ -0,0 +1,68 @@ +# golden_spiral + +Gets all points and angles on the path of a golden spiral. The distance between two points is almost constant. + +It returns a vector of `[[x, y], angle]`. + +## Parameters + +- `from` : If any ray from the origin intersects two successive turnings of the spiral, we'll have two points. The `arm_distance` is the distance between these two points. +- `to` : In polar coordinates `(r, θ)` Archimedean spiral can be described by the equation `r = bθ ` where `θ` is measured in radians. For being consistent with OpenSCAD, the function here use degrees. The `init_angle` is which angle the first point want to start. +- `point_distance` : Distance between two points on the path. +- `rt_dir` : `"CT_CLK"` for counterclockwise. `"CLK"` for clockwise. The default value is `"CT_CLK"`. + +## Examples + + include ; + include ; + + points_angles = archimedean_spiral( + arm_distance = 10, + init_angle = 180, + point_distance = 5, + num_of_points = 100 + ); + + points = [for(pa = points_angles) pa[0]]; + + polyline2d(points, width = 1); + + +![archimedean_spiral](images/lib-archimedean_spiral-1.JPG) + + include ; + + points_angles = archimedean_spiral( + arm_distance = 10, + init_angle = 180, + point_distance = 5, + num_of_points = 100 + ); + + for(pa = points_angles) { + translate(pa[0]) + circle(2); + } + +![archimedean_spiral](images/lib-archimedean_spiral-2.JPG) + + include ; + + t = "3.141592653589793238462643383279502884197169399375105820974944592307816406286"; + + points = archimedean_spiral( + arm_distance = 15, + init_angle = 450, + point_distance = 12, + num_of_points = len(t) + ); + + for(i = [0: len(points) - 1]) { + translate(points[i][0]) + rotate(points[i][1] + 90) + text(t[i], valign = "center", halign = "center"); + } + +![archimedean_spiral](images/lib-archimedean_spiral-3.JPG) + + diff --git a/src/golden_spiral.scad b/src/golden_spiral.scad index 028ce448..11a1553d 100644 --- a/src/golden_spiral.scad +++ b/src/golden_spiral.scad @@ -33,34 +33,43 @@ function _remove_same_pts(pts1, pts2) = concat(pts1, [for(i = [1:len(pts2) - 1]) pts2[i]]) : concat(pts1, pts2); -function _golden_spiral_from_ls_or_eql_to(from, to, point_distance ) = +function _golden_spiral_from_ls_or_eql_to(from, to, point_distance, rt_dir) = let( f1 = _fast_fibonacci(from), f2 = _fast_fibonacci(from + 1), fn = floor(f1 * 6.28312 / point_distance), $fn = fn + 4 - (fn % 4), circle_pts = circle_path(radius = f1, n = $fn / 4 + 1), - a_step = 360 / $fn, - arc_points_angles = [ - for(i = [0:len(circle_pts) - 1]) + len_pts = len(circle_pts), + a_step = 360 / $fn * rt_dir, + arc_points_angles = (rt_dir == 1 ? [ + for(i = [0:len_pts - 1]) // to 3D points because of rotate_p [[circle_pts[i][0], circle_pts[i][1], 0], a_step * i] - ], + ] : [ + for(i = [0:len_pts - 1]) let(idx = len_pts - i - 1) + // to 3D points because of rotate_p + [[circle_pts[idx][0], circle_pts[idx][1], 0], a_step * i] + ]), offset = f2 - f1 ) _remove_same_pts( arc_points_angles, [ - for(pt_a = _golden_spiral(from + 1, to, point_distance)) - [rotate_p(pt_a[0], [0, 0, 90]) + [0, -offset, 0], pt_a[1] + 90] - ] + for(pt_a = _golden_spiral(from + 1, to, point_distance, rt_dir)) + [ + rotate_p(pt_a[0], [0, 0, 90 * rt_dir]) + + (rt_dir == 1 ? [0, -offset, 0] : [-offset, 0, 0]), + pt_a[1] + 90 * rt_dir + ] + ] ); -function _golden_spiral(from, to, point_distance) = +function _golden_spiral(from, to, point_distance, rt_dir) = from <= to ? - _golden_spiral_from_ls_or_eql_to(from, to, point_distance) : []; + _golden_spiral_from_ls_or_eql_to(from, to, point_distance, rt_dir) : []; -function golden_spiral(from, to, point_distance) = +function golden_spiral(from, to, point_distance, rt_dir = "CT_CLK") = [ - for(pt_a = _golden_spiral(from, to, point_distance)) + for(pt_a = _golden_spiral(from, to, point_distance, (rt_dir == "CT_CLK" ? 1 : -1))) [[pt_a[0][0], pt_a[0][1]], pt_a[1]] // to 2D points ]; \ No newline at end of file