diff --git a/geometry.scad b/geometry.scad index 0dd5502..498be1c 100644 --- a/geometry.scad +++ b/geometry.scad @@ -1839,7 +1839,7 @@ function is_polygon_clockwise(poly) = // poly = The list of 2D path points for the perimeter of the polygon. function clockwise_polygon(poly) = assert(is_path(poly,dim=2), "Input should be a 2d polygon") - polygon_area(poly, signed=true)<0 ? poly : reverse_polygon(poly); + is_polygon_clockwise(poly) ? poly : reverse_polygon(poly); // Function: ccw_polygon() @@ -1853,7 +1853,7 @@ function clockwise_polygon(poly) = // poly = The list of 2D path points for the perimeter of the polygon. function ccw_polygon(poly) = assert(is_path(poly,dim=2), "Input should be a 2d polygon") - polygon_area(poly, signed=true)<0 ? reverse_polygon(poly) : poly; + is_polygon_clockwise(poly) ? reverse_polygon(poly) : poly; // Function: reverse_polygon() diff --git a/lists.scad b/lists.scad index 07356e9..8947b7f 100644 --- a/lists.scad +++ b/lists.scad @@ -970,9 +970,17 @@ function pair(list, wrap=false) = // See Also: idx(), enumerate(), pair(), combinations(), permutations() // Description: // Takes a list, and returns a list of adjacent triplets from it, optionally wrapping back to the front. +// If you set `wrap` to true then the first triplet is the one centered on the first list element, so it includes +// the last element and the first two elements. If the list has fewer than three elements then the empty list is returned. +// Arguments: +// list = list to produce triplets from +// wrap = if true, wrap triplets around the list. Default: false // Example: -// l = ["A","B","C","D","E"]; -// echo([for (p=triplet(l)) str(p.z,p.y,p.x)]); // Outputs: ["CBA", "DCB", "EDC"] +// list = [0,1,2,3,4]; +// a = triplet(list); // Returns [[0,1,2],[1,2,3],[2,3,4]] +// b = triplet(list,wrap=true); // Returns [[4,0,1],[0,1,2],[1,2,3],[2,3,4],[3,4,0]] +// letters = ["A","B","C","D","E"]; +// [for (p=triplet(letters)) str(p.z,p.y,p.x)]; // Returns: ["CBA", "DCB", "EDC"] // Example(2D): // path = [for (i=[0:24]) polar_to_xy(i*2, i*360/12)]; // for (t = triplet(path)) { @@ -984,11 +992,13 @@ function pair(list, wrap=false) = function triplet(list, wrap=false) = assert(is_list(list)||is_string(list), "Invalid input." ) assert(is_bool(wrap)) - let( - ll = len(list) - ) wrap - ? [for (i=[0:1:ll-1]) [ list[i], list[(i+1)%ll], list[(i+2)%ll] ]] - : [for (i=[0:1:ll-3]) [ list[i], list[i+1], list[i+2] ]]; + let(L=len(list)) + [ + if(wrap) [list[L-1], list[0], list[1]], + for (i=[0:1:L-3]) [list[i],list[i+1],list[i+2]], + if(wrap) [list[L-2], list[L-1], list[0]] + ]; + // Function: combinations() diff --git a/mutators.scad b/mutators.scad index 63e22c4..88836a2 100644 --- a/mutators.scad +++ b/mutators.scad @@ -524,7 +524,7 @@ module path_extrude2d(path, caps=false, closed=false) { } } - if (false && caps) { + if (caps) { move_copies([path[0],last(path)]) rotate_extrude() right_half(planar=true) children(); diff --git a/paths.scad b/paths.scad index bfe0772..15349dd 100644 --- a/paths.scad +++ b/paths.scad @@ -228,12 +228,12 @@ function path_length_fractions(path, closed) = let( lengths = [ 0, - for (i=[0:1:len(path)-(closed?1:2)]) - norm(select(path,i+1)-path[i]) + each path_segment_lengths(path,closed) ], partial_len = cumsum(lengths), total_len = last(partial_len) - ) partial_len / total_len; + ) + partial_len / total_len; @@ -556,7 +556,7 @@ function path_closest_point(path, pt, closed=true) = assert(is_vector(pt, len(path[0])), "Input pt must be a compatible vector") assert(is_bool(closed)) let( - pts = [for (seg=[0:1:len(path)-(closed?1:2)]) line_closest_point(select(path,seg,seg+1),pt,SEGMENT)], + pts = [for (seg=pair(path,closed)) line_closest_point(seg,pt,SEGMENT)], dists = [for (p=pts) norm(p-pt)], min_seg = min_index(dists) ) [min_seg, pts[min_seg]]; diff --git a/tests/test_lists.scad b/tests/test_lists.scad index bb8b140..3672802 100644 --- a/tests/test_lists.scad +++ b/tests/test_lists.scad @@ -358,10 +358,9 @@ test_pair(); module test_triplet() { assert(triplet([3,4,5,6,7]) == [[3,4,5], [4,5,6], [5,6,7]]); assert(triplet("ABCDE") == [["A","B","C"], ["B","C","D"], ["C","D","E"]]); - assert(triplet([3,4,5,6],true) == [[3,4,5], [4,5,6], [5,6,3], [6,3,4]]); - assert(triplet("ABCD",true) == [["A","B","C"], ["B","C","D"], ["C","D","A"], ["D","A","B"]]); - assert(triplet([3,4,5,6],wrap=true) == [[3,4,5], [4,5,6], [5,6,3], [6,3,4]]); - assert(triplet("ABCD",wrap=true) == [["A","B","C"], ["B","C","D"], ["C","D","A"], ["D","A","B"]]); + assert(triplet([3,4,5,6],true) == [[6,3,4],[3,4,5], [4,5,6], [5,6,3]]); + assert(triplet("ABCD",true) == [["D","A","B"],["A","B","C"], ["B","C","D"], ["C","D","A"]]); + assert(triplet("ABCD",wrap=true) == [["D","A","B"],["A","B","C"], ["B","C","D"], ["C","D","A"]]); } test_triplet();