diff --git a/README.md b/README.md index b75d0910..6146c085 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,9 @@ Some modules may depend on other modules. For example, the `polyline2d` module d - [hollow_out](https://openhome.cc/eGossip/OpenSCAD/lib-hollow_out.html) - [bend](https://openhome.cc/eGossip/OpenSCAD/lib-bend.html) +- Functon + - [rotate_p](https://openhome.cc/eGossip/OpenSCAD/lib-rotate_p.html) + - Path - [circle_path](https://openhome.cc/eGossip/OpenSCAD/lib-circle_path.html) - [bezier](https://openhome.cc/eGossip/OpenSCAD/lib-bezier.html) diff --git a/docs/images/lib-rotate_p-1.JPG b/docs/images/lib-rotate_p-1.JPG new file mode 100644 index 00000000..e1b91901 Binary files /dev/null and b/docs/images/lib-rotate_p-1.JPG differ diff --git a/docs/images/lib-rotate_p-2.JPG b/docs/images/lib-rotate_p-2.JPG new file mode 100644 index 00000000..c1f1f971 Binary files /dev/null and b/docs/images/lib-rotate_p-2.JPG differ diff --git a/docs/lib-rotate_p.md b/docs/lib-rotate_p.md new file mode 100644 index 00000000..c7149ae6 --- /dev/null +++ b/docs/lib-rotate_p.md @@ -0,0 +1,57 @@ +# rotate_p + +Rotates a point `a` degrees around an arbitrary axis. The rotation is applied in the following order: `x`, `y`, `z`. + +## Parameters + +- `point` : The point `[x, y, z]`. +- `a` : An array `[deg_x, deg_y, deg_z]`. The same as the `a` parameter of the built-in `rotate`. + +## Examples + +You can use the code below to create a line. + + hull() { + sphere(1); + rotate([0, -45, 45]) + translate([20, 0, 0]) + sphere(1); + } + +The following code have the same effect. + + point = [20, 0, 0]; + a = [0, -45, 45]; + + hull() { + sphere(1); + translate(rotate_p(point, a)) + rotate(a) + sphere(1); + } + +![rotate_p](images/lib-rotate_p-1.JPG) + +The `rotate_p` function is useful in some situations. For examples, you probably want to get all points on the path of a spiral around a sphere. + + radius = 40; + step_angle = 10; + z_circles = 20; + + points_angles = [for(a = [0:step_angle:90 * z_circles]) + rotate_p( + [radius, 0, 0], + [0, -90 + 2 * a / z_circles, a] + ) + ]; + + // Once you get all points on the path, you can place anything at each point. + // I just place a sphere as a simple demonstration. + for(pa = points_angles) { + translate(pa[0]) + sphere(1); + } + + %sphere(radius); + +![rotate_p](images/lib-rotate_p-2.JPG) \ No newline at end of file diff --git a/src/rotate_p.scad b/src/rotate_p.scad new file mode 100644 index 00000000..9e0b61ad --- /dev/null +++ b/src/rotate_p.scad @@ -0,0 +1,50 @@ +/** +* rotate_p.scad +* +* Rotates a point 'a' degrees around an arbitrary axis. +* The rotation is applied in the following order: x, y, z. +* +* @copyright Justin Lin, 2017 +* @license https://opensource.org/licenses/lgpl-3.0.html +* +* @see https://openhome.cc/eGossip/OpenSCAD/lib-rotate_p.html +* +**/ + +module arc(radius, angles, width, width_mode = "LINE_CROSS") { + w_offset = width_mode == "LINE_CROSS" ? [width / 2, -width / 2] : ( + width_mode == "LINE_INWARD" ? [0, -width] : [width, 0] + ); + + difference() { + circular_sector(radius + w_offset[0], angles); + circular_sector(radius + w_offset[1], angles); + } +} + +function _rotx(pt, a) = + let(cosa = cos(a), sina = sin(a)) + [ + pt[0], + pt[1] * cosa - pt[2] * sina, + pt[1] * sina + pt[2] * cosa + ]; + +function _roty(pt, a) = + let(cosa = cos(a), sina = sin(a)) + [ + pt[0] * cosa + pt[2] * sina, + pt[1], + -pt[0] * sina + pt[2] * cosa, + ]; + +function _rotz(pt, a) = + let(cosa = cos(a), sina = sin(a)) + [ + pt[0] * cosa - pt[1] * sina, + pt[0] * sina + pt[1] * cosa, + pt[2] + ]; + +function rotate_p(point, a) = + _rotz(_roty(_rotx(point, a[0]), a[1]), a[2]); \ No newline at end of file