diff --git a/README.md b/README.md index fe9c8b8d..0896426f 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,6 @@ Too many dependencies? Because OpenSCAD doesn't provide namespace management, I - [hull_polyline2d](https://openhome.cc/eGossip/OpenSCAD/lib-hull_polyline2d.html) - [hexagons](https://openhome.cc/eGossip/OpenSCAD/lib-hexagons.html) - [polytransversals](https://openhome.cc/eGossip/OpenSCAD/lib-polytransversals.html) - - [path_extend](https://openhome.cc/eGossip/OpenSCAD/lib-path_extend.html) - 3D - [rounded_cube](https://openhome.cc/eGossip/OpenSCAD/lib-rounded_cube.html) @@ -87,7 +86,8 @@ Too many dependencies? Because OpenSCAD doesn't provide namespace management, I - [shape_trapezium](https://openhome.cc/eGossip/OpenSCAD/lib-shape_trapezium.html) - [shape_cyclicpolygon](https://openhome.cc/eGossip/OpenSCAD/lib-shape_cyclicpolygon.html) - [shape_pentagram](https://openhome.cc/eGossip/OpenSCAD/lib-shape_pentagram.html) - - [shape_superformula](https://openhome.cc/eGossip/OpenSCAD/lib-shape_superformula.html) + - [shape_superformula](https://openhome.cc/eGossip/OpenSCAD/lib-shape_superformula.html) + - [shape_path_extend](https://openhome.cc/eGossip/OpenSCAD/lib-shape_path_extend.html) - 2D Shape Extrusion - [path_extrude](https://openhome.cc/eGossip/OpenSCAD/lib-path_extrude.html) diff --git a/docs/images/lib-path_extend-1.JPG b/docs/images/lib-shape_path_extend-1.JPG similarity index 100% rename from docs/images/lib-path_extend-1.JPG rename to docs/images/lib-shape_path_extend-1.JPG diff --git a/docs/lib-path_extend.md b/docs/lib-shape_path_extend.md similarity index 55% rename from docs/lib-path_extend.md rename to docs/lib-shape_path_extend.md index 6b76847d..dcf3a5ad 100644 --- a/docs/lib-path_extend.md +++ b/docs/lib-shape_path_extend.md @@ -1,10 +1,10 @@ -# path_extend +# shape_path_extend -It extends a 2D stroke along a path. This module is suitable for a path created by a continuous function. +It extends a 2D stroke along a path to create a 2D shape. This module is suitable for a path created by a continuous function. The returned points can be used with xxx_extrude modules of dotSCAD. The shape points can be also used with the built-in polygon module. -It depends on the rotate_p function and the polytransversals module. Remember to include "rotate_p.scad" and "polytransversals.scad". +When using this module, you should use points to represent the 2D stroke. -When using this module, you should use points to represent the 2D stroke. +It depends on the `rotate_p` function. Remember to include "rotate_p.scad" and "polytransversals.scad". ## Parameters @@ -16,8 +16,7 @@ When using this module, you should use points to represent the 2D stroke. ## Examples include ; - include ; - include ; + include ; include ; include ; @@ -25,7 +24,10 @@ When using this module, you should use points to represent the 2D stroke. stroke1 = [[-5, 2.5], [-2.5, 0], [0, 2.5], [2.5, 0], [5, 2.5]]; path_pts1 = circle_path(50, 60); - path_extend(stroke1, path_pts1); + polygon( + shape_path_extend(stroke1, path_pts1) + ); + stroke2 = [[-4, 0], [0, 4], [4, 0]]; pts_angles = archimedean_spiral( @@ -36,9 +38,11 @@ When using this module, you should use points to represent the 2D stroke. ); translate([120, 0, 0]) - path_extend( - stroke2, - [for(pa = pts_angles) pa[0]] - ); + polygon( + shape_path_extend( + stroke2, + [for(pa = pts_angles) pa[0]] + ) + ); -![path_extend](images/lib-path_extend-1.JPG) \ No newline at end of file +![path_extend](images/lib-shape_path_extend-1.JPG) \ No newline at end of file diff --git a/src/path_extend.scad b/src/path_extend.scad deleted file mode 100644 index 17946e4b..00000000 --- a/src/path_extend.scad +++ /dev/null @@ -1,71 +0,0 @@ -/** -* path_extend.scad -* -* It extends a 2D stroke along a path. -* This module is suitable for a path created by a continuous function. -* It depends on the rotate_p function and the polytransversals module. -* Remember to include "rotate_p.scad" and "polytransversals.scad". -* -* @copyright Justin Lin, 2017 -* @license https://opensource.org/licenses/lgpl-3.0.html -* -* @see https://openhome.cc/eGossip/OpenSCAD/lib-path_extend.html -* -**/ - -include <__private__/__to3d.scad>; -include <__private__/__length_between.scad>; - -module path_extend(stroke_pts, path_pts, scale = 1.0, closed = false) { - - function az(p1, p2) = - let( - x1 = p1[0], - y1 = p1[1], - x2 = p2[0], - y2 = p2[1] - ) -90 + atan2((y2 - y1), (x2 - x1)); - - leng_path_pts = len(path_pts); - - scale_step = (scale - 1) / (leng_path_pts - 1); - - function first_stroke() = - let( - p1 = path_pts[0], - p2 = path_pts[1], - a = az(p1, p2) - ) - [ - for(p = stroke_pts) - rotate_p(p, a) + p1 - ]; - - function stroke(p1, p2, i) = - let( - leng = __length_between(__to3d(p1), __to3d(p2)), - a = az(p1, p2) - ) - [ - for(p = stroke_pts) - rotate_p(p * (1 + scale_step * i) + [0, leng], a) + p1 - ]; - - function path_extend_inner(index) = - index == leng_path_pts ? [] : - concat( - [stroke(path_pts[index - 1], path_pts[index], index)], - path_extend_inner(index + 1) - ); - - if(closed && path_pts[0] == path_pts[leng_path_pts - 1]) { - strokes = path_extend_inner(1); - polytransversals( - concat(strokes, [strokes[0]]) - ); - } else { - polytransversals( - concat([first_stroke()], path_extend_inner(1)) - ); - } -} diff --git a/src/shape_path_extend.scad b/src/shape_path_extend.scad new file mode 100644 index 00000000..161f94ab --- /dev/null +++ b/src/shape_path_extend.scad @@ -0,0 +1,82 @@ +/** +* shape_path_extend.scad +* +* It extends a 2D stroke along a path. +* This module is suitable for a path created by a continuous function. +* It depends on the rotate_p function and the polytransversals module. +* Remember to include "rotate_p.scad" and "polytransversals.scad". +* +* @copyright Justin Lin, 2017 +* @license https://opensource.org/licenses/lgpl-3.0.html +* +* @see https://openhome.cc/eGossip/OpenSCAD/lib-path_extend.html +* +**/ + +include <__private__/__to3d.scad>; +include <__private__/__length_between.scad>; +include <__private__/__polytransversals.scad>; +include <__private__/__reverse.scad>; + +function _shape_path_extend_az(p1, p2) = + let( + x1 = p1[0], + y1 = p1[1], + x2 = p2[0], + y2 = p2[1] + ) -90 + atan2((y2 - y1), (x2 - x1)); + +function _shape_path_first_stroke(stroke_pts, path_pts) = + let( + p1 = path_pts[0], + p2 = path_pts[1], + a = _shape_path_extend_az(p1, p2) + ) + [ + for(p = stroke_pts) + rotate_p(p, a) + p1 + ]; + +function _shape_path_extend_stroke(stroke_pts, p1, p2, scale_step, i) = + let( + leng = __length_between(__to3d(p1), __to3d(p2)), + a = _shape_path_extend_az(p1, p2) + ) + [ + for(p = stroke_pts) + rotate_p(p * (1 + scale_step * i) + [0, leng], a) + p1 + ]; + +function _shape_path_extend_inner(stroke_pts, path_pts, leng_path_pts, scale_step, index) = + index == leng_path_pts ? [] : + concat( + [ + _shape_path_extend_stroke( + stroke_pts, + path_pts[index - 1], + path_pts[index], + scale_step, + index + ) + ], + _shape_path_extend_inner( + stroke_pts, + path_pts, + leng_path_pts, + scale_step, + index + 1 + ) + ); + +function shape_path_extend(stroke_pts, path_pts, scale = 1.0, closed = false) = + let( + leng_path_pts = len(path_pts), + scale_step = (scale - 1) / (leng_path_pts - 1), + strokes = _shape_path_extend_inner(stroke_pts, path_pts, leng_path_pts, scale_step, 1) + ) + closed && path_pts[0] == path_pts[leng_path_pts - 1] ? + __polytransversals(concat(strokes, [strokes[0]])) : + __polytransversals( + concat([_shape_path_first_stroke(stroke_pts, path_pts)], strokes) + ); +