mirror of
https://github.com/JustinSDK/dotSCAD.git
synced 2025-01-17 14:18:13 +01:00
added archimedean_spiral
This commit is contained in:
parent
077ee6dd74
commit
4edecfe0c6
@ -27,6 +27,7 @@ I've been using OpenSCAD for years and created some funny things. Some of them i
|
||||
- [circle_path](https://openhome.cc/eGossip/OpenSCAD/lib-circle_path.html)
|
||||
- [bezier](https://openhome.cc/eGossip/OpenSCAD/lib-bezier.html)
|
||||
- [cylinder_spiral](https://openhome.cc/eGossip/OpenSCAD/lib-cylinder_spiral.html)
|
||||
- [archimedean_spiral](https://openhome.cc/eGossip/OpenSCAD/lib-archimedean_spiral.html)
|
||||
|
||||
- Other
|
||||
- [box_extrude](https://openhome.cc/eGossip/OpenSCAD/lib-box_extrude.html)
|
BIN
docs/images/lib-archimedean_spiral-1.JPG
Normal file
BIN
docs/images/lib-archimedean_spiral-1.JPG
Normal file
Binary file not shown.
After Width: | Height: | Size: 44 KiB |
BIN
docs/images/lib-archimedean_spiral-2.JPG
Normal file
BIN
docs/images/lib-archimedean_spiral-2.JPG
Normal file
Binary file not shown.
After Width: | Height: | Size: 49 KiB |
BIN
docs/images/lib-archimedean_spiral-3.JPG
Normal file
BIN
docs/images/lib-archimedean_spiral-3.JPG
Normal file
Binary file not shown.
After Width: | Height: | Size: 60 KiB |
65
docs/lib-archimedean_spiral.md
Normal file
65
docs/lib-archimedean_spiral.md
Normal file
@ -0,0 +1,65 @@
|
||||
# archimedean_spiral
|
||||
|
||||
Get all points and angles on the path of an archimedean_spiral. The distance between two points is almost constant.
|
||||
|
||||
It returns a vector of `[[x, y], angle]`.
|
||||
|
||||
An `init_angle` less than 180 degrees is not recommended because the function uses an approximate approach. If you really want an `init_angle` less than 180 degrees, a larger `arm_distance` is required. To reduce the error value at the calculated distance between two points, you may try a smaller `point_distance`.
|
||||
|
||||
## Parameters
|
||||
|
||||
- `arm_distance` : 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.
|
||||
- `init_angle` : 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.
|
||||
- `num_of_points` : How many points do you want?
|
||||
|
||||
## Examples
|
||||
|
||||
include <polyline2d.scad>;
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
|
55
src/archimedean_spiral.scad
Normal file
55
src/archimedean_spiral.scad
Normal file
@ -0,0 +1,55 @@
|
||||
/**
|
||||
* archimedean_spiral.scad
|
||||
*
|
||||
* Get all points and angles on the path of an archimedean_spiral. The distance between two points is almost constant.
|
||||
*
|
||||
* It returns a vector of [[x, y], angle].
|
||||
*
|
||||
* In polar coordinates (r, £c) Archimedean spiral can be described by the equation r = b£c where
|
||||
* £c is measured in radians. For being consistent with OpenSCAD, the function here use degrees.
|
||||
*
|
||||
* An init_angle less than 180 degrees is not recommended because the function uses an approximate
|
||||
* approach. If you really want an init_angle less than 180 degrees, a larger arm_distance
|
||||
* is required. To avoid a small error value at the calculated distance between two points, you
|
||||
* may try a smaller point_distance.
|
||||
*
|
||||
* @copyright Justin Lin, 2017
|
||||
* @license https://opensource.org/licenses/lgpl-3.0.html
|
||||
*
|
||||
* @see https://openhome.cc/eGossip/OpenSCAD/lib-archimedean_spiral.html
|
||||
*
|
||||
**/
|
||||
|
||||
function _radian_step(b, theta, l) =
|
||||
let(r_square = pow(b * theta, 2))
|
||||
acos((2 * r_square - pow(l, 2)) / (2 * r_square)) / 180 * 3.14159;
|
||||
|
||||
function _find_radians(b, point_distance, radians, n, count = 1) =
|
||||
let(pre_radians = radians[count - 1])
|
||||
count == n ? radians : (
|
||||
_find_radians(
|
||||
b,
|
||||
point_distance,
|
||||
concat(
|
||||
radians,
|
||||
[pre_radians + _radian_step(b, pre_radians, point_distance)]
|
||||
),
|
||||
n,
|
||||
count + 1)
|
||||
);
|
||||
|
||||
/*
|
||||
In polar coordinates (r, £c) Archimedean spiral can be described by the equation r = b£c where
|
||||
£c is measured in radians. For being consistent with OpenSCAD, the function here use degrees.
|
||||
An init_angle angle less than 180 degrees is not recommended because the function uses an
|
||||
approximate approach. If you really want an angle less than 180 degrees, a larger arm_distance
|
||||
is required. To avoid a small error value at the calculated distance between two points, you
|
||||
may try a smaller point_distance.
|
||||
*/
|
||||
function archimedean_spiral(arm_distance, init_angle, point_distance, num_of_points) =
|
||||
let(b = arm_distance / 6.28318, init_radian = init_angle *3.14159 / 180)
|
||||
[
|
||||
for(theta = _find_radians(b, point_distance, [init_radian], num_of_points))
|
||||
let(r = b * theta, a = theta * 57.2958)
|
||||
[[r * cos(a), r * sin(a)], a]
|
||||
];
|
Loading…
x
Reference in New Issue
Block a user