From 67144218f430e48c638ed9b8f5702b41c76f4050 Mon Sep 17 00:00:00 2001 From: Revar Desmera Date: Mon, 25 Mar 2019 01:42:08 -0700 Subject: [PATCH] Renamed wrap_range() to select(), and fixed array_zip() --- math.scad | 125 +++++++++++++++++++++++++++++++++++++-------- triangulation.scad | 14 ++--- 2 files changed, 111 insertions(+), 28 deletions(-) diff --git a/math.scad b/math.scad index 63c66e2..3e39061 100644 --- a/math.scad +++ b/math.scad @@ -309,6 +309,7 @@ function slice(arr,st,end) = let( // Function: wrap_range() +// Status: DEPRECATED, use `select()` instead. // Description: // Returns a portion of a list, wrapping around past the beginning, if endlength)? array_trim(v,length) : array_pad(v,length,fill); + + // Function: array_zip() +// Usage: +// array_zip(v1, v2, v3, [fit], [fill]); +// array_zip(vecs, [fit], [fill]); // Description: // Zips together corresponding items from two or more lists. -// Returns a list of grouped values. +// Returns a list of lists, where each sublist contains corresponding +// items from each of the imput lists. `[[A1, B1, C1], [A2, B2, C2], ...]` // Arguments: // vecs = A list of two or more lists to zipper together. -// dflt = The default value to fill in with if one or more lists if short. +// fit = If `fit=="short"`, the zips together up to the length of the shortest list in vecs. If `fit=="long"`, then pads all lists to the length of the longest, using the value in `fill`. If `fit==false`, then requires all lists to be the same length. Default: false. +// fill = The default value to fill in with if one or more lists if short. Default: undef // Example: // v1 = [1,2,3,4]; // v2 = [5,6,7]; // v3 = [8,9,10,11]; -// array_zip([v1,v2]); // returns [[1,5], [2,6], [3,7], [4,undef]] -// array_zip([v1,v2], 20); // returns [[1,5], [2,6], [3,7], [4,20]] -// array_zip([v1,v2,v3]); // returns [[1,5,8], [2,6,9], [3,7,10], [4,undef,11]] -function array_zip(vecs, dflt=undef) = [ - for (i = [0:max([for (v=vecs) len(v)])-1]) - [for (v = vecs) default(v[i], dflt)] -]; +// array_zip(v1,v3); // returns [[1,8], [2,9], [3,10], [4,11]] +// array_zip([v1,v3]); // returns [[1,8], [2,9], [3,10], [4,11]] +// array_zip([v1,v2], fit="short"); // returns [[1,5], [2,6], [3,7]] +// array_zip([v1,v2], fit="long"); // returns [[1,5], [2,6], [3,7], [4,undef]] +// array_zip([v1,v2], fit="long, fill=0); // returns [[1,5], [2,6], [3,7], [4,0]] +// array_zip([v1,v2,v3], fit="long"); // returns [[1,5,8], [2,6,9], [3,7,10], [4,undef,11]] +// Example: +// v1 = [[1,2,3], [4,5,6], [7,8,9]]; +// v2 = [[20,19,18], [17,16,15], [14,13,12]]; +// array_zip(v1,v2); // Returns [[1,2,3,20,19,18], [4,5,6,17,16,15], [7,8,9,14,13,12]] +function array_zip(vecs, v2, v3, fit=false, fill=undef) = + (v3!=undef)? array_zip([vecs,v2,v3], fit=fit, fill=fill) : + (v2!=undef)? array_zip([vecs,v2], fit=fit, fill=fill) : + let( + dummy1 = assert_in_list("fit", fit, [false, "short", "long"]), + minlen = array_shortest(vecs), + maxlen = array_longest(vecs), + dummy2 = (fit==false)? assertion(minlen==maxlen, "Input vectors must have the same length") : 0 + ) (fit == "long")? + [for(i=[0:maxlen-1]) [for(v=vecs) for (x=(i0 ? 0 : + sum([for(i=[0:len(path)-1]) point_on_segment(point, select(path, i, i+1))?1:0])>0 ? 0 : // Otherwise compute winding number and return 1 for interior, -1 for exterior - sum([for(i=[0:len(path)-1]) _point_above_below_segment(point, wrap_range(path, i, i+1))]) != 0 ? 1 : -1; + sum([for(i=[0:len(path)-1]) _point_above_below_segment(point, select(path, i, i+1))]) != 0 ? 1 : -1; // Function: pointlist_bounds() diff --git a/triangulation.scad b/triangulation.scad index d92afa5..7b39e9b 100644 --- a/triangulation.scad +++ b/triangulation.scad @@ -135,7 +135,7 @@ function normalize_vertex_perimeter(v) = // vertex = The index into `facelist`, of the vertex to test. function is_only_noncolinear_vertex(points, facelist, vertex) = let( - face=wrap_range(facelist, vertex+1, vertex-1), + face=select(facelist, vertex+1, vertex-1), count=len(face) ) 0==sum( @@ -184,19 +184,19 @@ function triangulate_face(points, face) = is_only_noncolinear_vertex(points, face, cv)? // In the point&line degeneracy clip to somewhere in the middle of the line. flatten([ - triangulate_face(points, wrap_range(face, cv, (cv+2)%count)), - triangulate_face(points, wrap_range(face, (cv+2)%count, cv)) + triangulate_face(points, select(face, cv, (cv+2)%count)), + triangulate_face(points, select(face, (cv+2)%count, cv)) ]) : // Otherwise the ear is safe to clip. flatten([ - [wrap_range(face, pv, nv)], - triangulate_face(points, wrap_range(face, nv, pv)) + [select(face, pv, nv)], + triangulate_face(points, select(face, nv, pv)) ]) : // If there is a point inside the ear, make a diagonal and clip along that. flatten([ - triangulate_face(points, wrap_range(face, cv, diagonal_point)), - triangulate_face(points, wrap_range(face, diagonal_point, cv)) + triangulate_face(points, select(face, cv, diagonal_point)), + triangulate_face(points, select(face, diagonal_point, cv)) ]) ;