subarray -> columns

This commit is contained in:
Adrian Mariano 2021-10-15 22:39:10 -04:00
parent a65315b876
commit 2d205a2568
17 changed files with 79 additions and 79 deletions

View file

@ -70,7 +70,7 @@ function _same_type(a,b, depth) =
// list = The list to get the portion of. // list = The list to get the portion of.
// start = Either the index of the first item or an index range or a list of indices. // start = Either the index of the first item or an index range or a list of indices.
// end = The index of the last item when `start` is a number. When `start` is a list or a range, `end` should not be given. // end = The index of the last item when `start` is a number. When `start` is a list or a range, `end` should not be given.
// See Also: slice(), subindex(), last() // See Also: slice(), columns(), last()
// Example: // Example:
// l = [3,4,5,6,7,8,9]; // l = [3,4,5,6,7,8,9];
// a = select(l, 5, 6); // Returns [8,9] // a = select(l, 5, 6); // Returns [8,9]
@ -111,7 +111,7 @@ function select(list, start, end) =
// list = The list to get the slice of. // list = The list to get the slice of.
// s = The index of the first item to return. // s = The index of the first item to return.
// e = The index of the last item to return. // e = The index of the last item to return.
// See Also: select(), subindex(), last() // See Also: select(), columns(), last()
// Example: // Example:
// a = slice([3,4,5,6,7,8,9], 3, 5); // Returns [6,7,8] // a = slice([3,4,5,6,7,8,9], 3, 5); // Returns [6,7,8]
// b = slice([3,4,5,6,7,8,9], 2, -1); // Returns [5,6,7,8,9] // b = slice([3,4,5,6,7,8,9], 2, -1); // Returns [5,6,7,8,9]
@ -136,7 +136,7 @@ function slice(list,s=0,e=-1) =
// Usage: // Usage:
// item = last(list); // item = last(list);
// Topics: List Handling // Topics: List Handling
// See Also: select(), slice(), subindex() // See Also: select(), slice(), columns()
// Description: // Description:
// Returns the last element of a list, or undef if empty. // Returns the last element of a list, or undef if empty.
// Arguments: // Arguments:
@ -272,7 +272,7 @@ function add_scalar(v,s) =
// Arguments: // Arguments:
// val = The simple value to search for. // val = The simple value to search for.
// list = The list to search. // list = The list to search.
// idx = If given, searches the given subindex for matches for `val`. // idx = If given, searches the given columns for matches for `val`.
// Example: // Example:
// a = in_list("bar", ["foo", "bar", "baz"]); // Returns true. // a = in_list("bar", ["foo", "bar", "baz"]); // Returns true.
// b = in_list("bee", ["foo", "bar", "baz"]); // Returns false. // b = in_list("bee", ["foo", "bar", "baz"]); // Returns false.
@ -1293,7 +1293,7 @@ function idx(list, s=0, e=-1, step=1) =
// Something like: `[[0,l[0]], [1,l[1]], [2,l[2]], ...]` // Something like: `[[0,l[0]], [1,l[1]], [2,l[2]], ...]`
// Arguments: // Arguments:
// l = List to enumerate. // l = List to enumerate.
// idx = If given, enumerates just the given subindex items of `l`. // idx = If given, enumerates just the given columns items of `l`.
// Example: // Example:
// enumerate(["a","b","c"]); // Returns: [[0,"a"], [1,"b"], [2,"c"]] // enumerate(["a","b","c"]); // Returns: [[0,"a"], [1,"b"], [2,"c"]]
// enumerate([[88,"a"],[76,"b"],[21,"c"]], idx=1); // Returns: [[0,"a"], [1,"b"], [2,"c"]] // enumerate([[88,"a"],[76,"b"],[21,"c"]], idx=1); // Returns: [[0,"a"], [1,"b"], [2,"c"]]
@ -1562,9 +1562,9 @@ function set_intersection(a, b) =
// Section: Array Manipulation // Section: Array Manipulation
// Function: subindex() // Function: columns()
// Usage: // Usage:
// list = subindex(M, idx); // list = columns(M, idx);
// Topics: Array Handling, List Handling // Topics: Array Handling, List Handling
// See Also: select(), slice() // See Also: select(), slice()
// Description: // Description:
@ -1577,13 +1577,13 @@ function set_intersection(a, b) =
// idx = The index, list of indices, or range of indices to fetch. // idx = The index, list of indices, or range of indices to fetch.
// Example: // Example:
// M = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]]; // M = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]];
// a = subindex(M,2); // Returns [3, 7, 11, 15] // a = columns(M,2); // Returns [3, 7, 11, 15]
// b = subindex(M,[2]); // Returns [[3], [7], [11], [15]] // b = columns(M,[2]); // Returns [[3], [7], [11], [15]]
// c = subindex(M,[2,1]); // Returns [[3, 2], [7, 6], [11, 10], [15, 14]] // c = columns(M,[2,1]); // Returns [[3, 2], [7, 6], [11, 10], [15, 14]]
// d = subindex(M,[1:3]); // Returns [[2, 3, 4], [6, 7, 8], [10, 11, 12], [14, 15, 16]] // d = columns(M,[1:3]); // Returns [[2, 3, 4], [6, 7, 8], [10, 11, 12], [14, 15, 16]]
// N = [ [1,2], [3], [4,5], [6,7,8] ]; // N = [ [1,2], [3], [4,5], [6,7,8] ];
// e = subindex(N,[0,1]); // Returns [ [1,2], [3,undef], [4,5], [6,7] ] // e = columns(N,[0,1]); // Returns [ [1,2], [3,undef], [4,5], [6,7] ]
function subindex(M, idx) = function columns(M, idx) =
assert( is_list(M), "The input is not a list." ) assert( is_list(M), "The input is not a list." )
assert( !is_undef(idx) && _valid_idx(idx,0,1/0), "Invalid index input." ) assert( !is_undef(idx) && _valid_idx(idx,0,1/0), "Invalid index input." )
is_finite(idx) is_finite(idx)
@ -1595,7 +1595,7 @@ function subindex(M, idx) =
// Usage: // Usage:
// mat = submatrix(M, idx1, idx2); // mat = submatrix(M, idx1, idx2);
// Topics: Matrices, Array Handling // Topics: Matrices, Array Handling
// See Also: subindex(), block_matrix(), submatrix_set() // See Also: columns(), block_matrix(), submatrix_set()
// Description: // Description:
// The input must be a list of lists (a matrix or 2d array). Returns a submatrix by selecting the rows listed in idx1 and columns listed in idx2. // The input must be a list of lists (a matrix or 2d array). Returns a submatrix by selecting the rows listed in idx1 and columns listed in idx2.
// Arguments: // Arguments:
@ -1628,10 +1628,10 @@ function submatrix(M,idx1,idx2) =
// A = hstack(M1, M2, M3) // A = hstack(M1, M2, M3)
// A = hstack([M1, M2, M3, ...]) // A = hstack([M1, M2, M3, ...])
// Topics: Matrices, Array Handling // Topics: Matrices, Array Handling
// See Also: subindex(), submatrix(), block_matrix() // See Also: columns(), submatrix(), block_matrix()
// Description: // Description:
// Constructs a matrix by horizontally "stacking" together compatible matrices or vectors. Vectors are treated as columsn in the stack. // Constructs a matrix by horizontally "stacking" together compatible matrices or vectors. Vectors are treated as columsn in the stack.
// This command is the inverse of subindex. Note: strings given in vectors are broken apart into lists of characters. Strings given // This command is the inverse of columns. Note: strings given in vectors are broken apart into lists of characters. Strings given
// in matrices are preserved as strings. If you need to combine vectors of strings use array_group as shown below to convert the // in matrices are preserved as strings. If you need to combine vectors of strings use array_group as shown below to convert the
// vector into a column matrix. Also note that vertical stacking can be done directly with concat. // vector into a column matrix. Also note that vertical stacking can be done directly with concat.
// Arguments: // Arguments:
@ -1650,7 +1650,7 @@ function submatrix(M,idx1,idx2) =
// c = hstack([M,v1,M]); // Returns [[1, 0, 0, 2, 1, 0, 0], // c = hstack([M,v1,M]); // Returns [[1, 0, 0, 2, 1, 0, 0],
// // [0, 1, 0, 3, 0, 1, 0], // // [0, 1, 0, 3, 0, 1, 0],
// // [0, 0, 1, 4, 0, 0, 1]] // // [0, 0, 1, 4, 0, 0, 1]]
// d = hstack(subindex(M,0), subindex(M,[1 2])); // Returns M // d = hstack(columns(M,0), columns(M,[1 2])); // Returns M
// strvec = ["one","two"]; // strvec = ["one","two"];
// strmat = [["three","four"], ["five","six"]]; // strmat = [["three","four"], ["five","six"]];
// e = hstack(strvec,strvec); // Returns [["o", "n", "e", "o", "n", "e"], // e = hstack(strvec,strvec); // Returns [["o", "n", "e", "o", "n", "e"],
@ -1680,7 +1680,7 @@ function hstack(M1, M2, M3) =
// Usage: // Usage:
// bmat = block_matrix([[M11, M12,...],[M21, M22,...], ... ]); // bmat = block_matrix([[M11, M12,...],[M21, M22,...], ... ]);
// Topics: Matrices, Array Handling // Topics: Matrices, Array Handling
// See Also: subindex(), submatrix() // See Also: columns(), submatrix()
// Description: // Description:
// Create a block matrix by supplying a matrix of matrices, which will // Create a block matrix by supplying a matrix of matrices, which will
// be combined into one unified matrix. Every matrix in one row // be combined into one unified matrix. Every matrix in one row
@ -1724,7 +1724,7 @@ function block_matrix(M) =
// Usage: // Usage:
// mat = diagonal_matrix(diag, [offdiag]); // mat = diagonal_matrix(diag, [offdiag]);
// Topics: Matrices, Array Handling // Topics: Matrices, Array Handling
// See Also: subindex(), submatrix() // See Also: columns(), submatrix()
// Description: // Description:
// Creates a square matrix with the items in the list `diag` on // Creates a square matrix with the items in the list `diag` on
// its diagonal. The off diagonal entries are set to offdiag, // its diagonal. The off diagonal entries are set to offdiag,
@ -1741,7 +1741,7 @@ function diagonal_matrix(diag, offdiag=0) =
// Usage: // Usage:
// mat = submatrix_set(M, A, [m], [n]); // mat = submatrix_set(M, A, [m], [n]);
// Topics: Matrices, Array Handling // Topics: Matrices, Array Handling
// See Also: subindex(), submatrix() // See Also: columns(), submatrix()
// Description: // Description:
// Sets a submatrix of M equal to the matrix A. By default the top left corner of M is set to A, but // Sets a submatrix of M equal to the matrix A. By default the top left corner of M is set to A, but
// you can specify offset coordinates m and n. If A (as adjusted by m and n) extends beyond the bounds // you can specify offset coordinates m and n. If A (as adjusted by m and n) extends beyond the bounds
@ -1772,7 +1772,7 @@ function submatrix_set(M,A,m=0,n=0) =
// Takes a flat array of values, and groups items in sets of `cnt` length. // Takes a flat array of values, and groups items in sets of `cnt` length.
// The opposite of this is `flatten()`. // The opposite of this is `flatten()`.
// Topics: Matrices, Array Handling // Topics: Matrices, Array Handling
// See Also: subindex(), submatrix(), hstack(), flatten(), full_flatten() // See Also: columns(), submatrix(), hstack(), flatten(), full_flatten()
// Arguments: // Arguments:
// v = The list of items to group. // v = The list of items to group.
// cnt = The number of items to put in each grouping. Default:2 // cnt = The number of items to put in each grouping. Default:2
@ -1829,7 +1829,7 @@ function group_data(groups, values) =
// Usage: // Usage:
// list = flatten(l); // list = flatten(l);
// Topics: Matrices, Array Handling // Topics: Matrices, Array Handling
// See Also: subindex(), submatrix(), hstack(), full_flatten() // See Also: columns(), submatrix(), hstack(), full_flatten()
// Description: // Description:
// Takes a list of lists and flattens it by one level. // Takes a list of lists and flattens it by one level.
// Arguments: // Arguments:
@ -1845,7 +1845,7 @@ function flatten(l) =
// Usage: // Usage:
// list = full_flatten(l); // list = full_flatten(l);
// Topics: Matrices, Array Handling // Topics: Matrices, Array Handling
// See Also: subindex(), submatrix(), hstack(), flatten() // See Also: columns(), submatrix(), hstack(), flatten()
// Description: // Description:
// Collects in a list all elements recursively found in any level of the given list. // Collects in a list all elements recursively found in any level of the given list.
// The output list is ordered in depth first order. // The output list is ordered in depth first order.

View file

@ -1594,9 +1594,9 @@ function _find_anchor(anchor, geom) =
hits = [ hits = [
for (face = faces) let( for (face = faces) let(
verts = select(rpts, face), verts = select(rpts, face),
xs = subindex(verts,0), xs = columns(verts,0),
ys = subindex(verts,1), ys = columns(verts,1),
zs = subindex(verts,2) zs = columns(verts,2)
) if ( ) if (
max(xs) >= -eps && max(xs) >= -eps &&
max(ys) >= -eps && max(ys) >= -eps &&
@ -1615,7 +1615,7 @@ function _find_anchor(anchor, geom) =
) )
assert(len(hits)>0, "Anchor vector does not intersect with the shape. Attachment failed.") assert(len(hits)>0, "Anchor vector does not intersect with the shape. Attachment failed.")
let( let(
furthest = max_index(subindex(hits,0)), furthest = max_index(columns(hits,0)),
dist = hits[furthest][0], dist = hits[furthest][0],
pos = hits[furthest][2], pos = hits[furthest][2],
hitnorms = [for (hit = hits) if (approx(hit[0],dist,eps=eps)) hit[1]], hitnorms = [for (hit = hits) if (approx(hit[0],dist,eps=eps)) hit[1]],
@ -1640,7 +1640,7 @@ function _find_anchor(anchor, geom) =
) vnf==EMPTY_VNF? [anchor, [0,0,0], unit(anchor), 0] : ) vnf==EMPTY_VNF? [anchor, [0,0,0], unit(anchor), 0] :
let( let(
rpts = apply(rot(from=anchor, to=RIGHT) * move(point3d(-cp)), vnf[0]), rpts = apply(rot(from=anchor, to=RIGHT) * move(point3d(-cp)), vnf[0]),
maxx = max(subindex(rpts,0)), maxx = max(columns(rpts,0)),
idxs = [for (i = idx(rpts)) if (approx(rpts[i].x, maxx)) i], idxs = [for (i = idx(rpts)) if (approx(rpts[i].x, maxx)) i],
mm = pointlist_bounds(select(rpts,idxs)), mm = pointlist_bounds(select(rpts,idxs)),
avgy = (mm[0].y+mm[1].y)/2, avgy = (mm[0].y+mm[1].y)/2,
@ -1681,7 +1681,7 @@ function _find_anchor(anchor, geom) =
) )
if(!is_undef(isect) && !approx(isect,t[0])) [norm(isect), isect, n2] if(!is_undef(isect) && !approx(isect,t[0])) [norm(isect), isect, n2]
], ],
maxidx = max_index(subindex(isects,0)), maxidx = max_index(columns(isects,0)),
isect = isects[maxidx], isect = isects[maxidx],
pos = point2d(cp) + isect[1], pos = point2d(cp) + isect[1],
vec = unit(isect[2],[0,1]) vec = unit(isect[2],[0,1])
@ -1691,7 +1691,7 @@ function _find_anchor(anchor, geom) =
path = geom[1], path = geom[1],
anchor = point2d(anchor), anchor = point2d(anchor),
rpath = rot(from=anchor, to=RIGHT, p=move(point2d(-cp), p=path)), rpath = rot(from=anchor, to=RIGHT, p=move(point2d(-cp), p=path)),
maxx = max(subindex(rpath,0)), maxx = max(columns(rpath,0)),
idxs = [for (i = idx(rpath)) if (approx(rpath[i].x, maxx)) i], idxs = [for (i = idx(rpath)) if (approx(rpath[i].x, maxx)) i],
miny = min([for (i=idxs) rpath[i].y]), miny = min([for (i=idxs) rpath[i].y]),
maxy = max([for (i=idxs) rpath[i].y]), maxy = max([for (i=idxs) rpath[i].y]),
@ -1717,7 +1717,7 @@ function _find_anchor(anchor, geom) =
if(!is_undef(isect) && !approx(isect,t[0])) if(!is_undef(isect) && !approx(isect,t[0]))
[norm(isect), isect, n2] [norm(isect), isect, n2]
], ],
maxidx = max_index(subindex(isects,0)), maxidx = max_index(columns(isects,0)),
isect = isects[maxidx], isect = isects[maxidx],
pos = point3d(cp) + point3d(isect[1]) + unit([0,0,anchor.z],CENTER)*l/2, pos = point3d(cp) + point3d(isect[1]) + unit([0,0,anchor.z],CENTER)*l/2,
xyvec = unit(isect[2],[0,1]), xyvec = unit(isect[2],[0,1]),
@ -1730,7 +1730,7 @@ function _find_anchor(anchor, geom) =
anchor = point3d(anchor), anchor = point3d(anchor),
xyanch = point2d(anchor), xyanch = point2d(anchor),
rpath = rot(from=xyanch, to=RIGHT, p=move(point2d(-cp), p=path)), rpath = rot(from=xyanch, to=RIGHT, p=move(point2d(-cp), p=path)),
maxx = max(subindex(rpath,0)), maxx = max(columns(rpath,0)),
idxs = [for (i = idx(rpath)) if (approx(rpath[i].x, maxx)) i], idxs = [for (i = idx(rpath)) if (approx(rpath[i].x, maxx)) i],
ys = [for (i=idxs) rpath[i].y], ys = [for (i=idxs) rpath[i].y],
avgy = (min(ys)+max(ys))/2, avgy = (min(ys)+max(ys))/2,

View file

@ -1043,9 +1043,9 @@ function bezier_patch_points(patch, u, v) =
assert(is_num(u) || !is_undef(u[0])) assert(is_num(u) || !is_undef(u[0]))
assert(is_num(v) || !is_undef(v[0])) assert(is_num(v) || !is_undef(v[0]))
let( let(
vbezes = [for (i = idx(patch[0])) bezier_points(subindex(patch,i), is_num(u)? [u] : u)] vbezes = [for (i = idx(patch[0])) bezier_points(columns(patch,i), is_num(u)? [u] : u)]
) )
[for (i = idx(vbezes[0])) bezier_points(subindex(vbezes,i), is_num(v)? [v] : v)]; [for (i = idx(vbezes[0])) bezier_points(columns(vbezes,i), is_num(v)? [v] : v)];
// Function: bezier_triangle_point() // Function: bezier_triangle_point()
@ -1357,7 +1357,7 @@ function bezier_patch_degenerate(patch, splinesteps=16, reverse=false, return_ed
all(row_degen) && all(col_degen) ? // fully degenerate case all(row_degen) && all(col_degen) ? // fully degenerate case
[EMPTY_VNF, repeat([patch[0][0]],4)] : [EMPTY_VNF, repeat([patch[0][0]],4)] :
all(row_degen) ? // degenerate to a line (top to bottom) all(row_degen) ? // degenerate to a line (top to bottom)
let(pts = bezier_points(subindex(patch,0), samplepts)) let(pts = bezier_points(columns(patch,0), samplepts))
[EMPTY_VNF, [pts,pts,[pts[0]],[last(pts)]]] : [EMPTY_VNF, [pts,pts,[pts[0]],[last(pts)]]] :
all(col_degen) ? // degenerate to a line (left to right) all(col_degen) ? // degenerate to a line (left to right)
let(pts = bezier_points(patch[0], samplepts)) let(pts = bezier_points(patch[0], samplepts))
@ -1366,7 +1366,7 @@ function bezier_patch_degenerate(patch, splinesteps=16, reverse=false, return_ed
let(pts = bezier_patch_points(patch, samplepts, samplepts)) let(pts = bezier_patch_points(patch, samplepts, samplepts))
[ [
vnf_vertex_array(pts, reverse=!reverse), vnf_vertex_array(pts, reverse=!reverse),
[subindex(pts,0), subindex(pts,len(pts)-1), pts[0], last(pts)] [columns(pts,0), columns(pts,len(pts)-1), pts[0], last(pts)]
] : ] :
top_degen && bot_degen ? top_degen && bot_degen ?
let( let(
@ -1375,17 +1375,17 @@ function bezier_patch_degenerate(patch, splinesteps=16, reverse=false, return_ed
if (splinesteps%2==0) splinesteps+1, if (splinesteps%2==0) splinesteps+1,
each reverse(list([3:2:splinesteps])) each reverse(list([3:2:splinesteps]))
], ],
bpatch = [for(i=[0:1:len(patch[0])-1]) bezier_points(subindex(patch,i), samplepts)], bpatch = [for(i=[0:1:len(patch[0])-1]) bezier_points(columns(patch,i), samplepts)],
pts = [ pts = [
[bpatch[0][0]], [bpatch[0][0]],
for(j=[0:splinesteps-2]) bezier_points(subindex(bpatch,j+1), lerpn(0,1,rowcount[j])), for(j=[0:splinesteps-2]) bezier_points(columns(bpatch,j+1), lerpn(0,1,rowcount[j])),
[last(bpatch[0])] [last(bpatch[0])]
], ],
vnf = vnf_tri_array(pts, reverse=!reverse) vnf = vnf_tri_array(pts, reverse=!reverse)
) [ ) [
vnf, vnf,
[ [
subindex(pts,0), columns(pts,0),
[for(row=pts) last(row)], [for(row=pts) last(row)],
pts[0], pts[0],
last(pts), last(pts),
@ -1404,16 +1404,16 @@ function bezier_patch_degenerate(patch, splinesteps=16, reverse=false, return_ed
full_degen = len(patch)>=4 && all(select(row_degen,1,ceil(len(patch)/2-1))), full_degen = len(patch)>=4 && all(select(row_degen,1,ceil(len(patch)/2-1))),
rowmax = full_degen ? count(splinesteps+1) : rowmax = full_degen ? count(splinesteps+1) :
[for(j=[0:splinesteps]) j<=splinesteps/2 ? 2*j : splinesteps], [for(j=[0:splinesteps]) j<=splinesteps/2 ? 2*j : splinesteps],
bpatch = [for(i=[0:1:len(patch[0])-1]) bezier_points(subindex(patch,i), samplepts)], bpatch = [for(i=[0:1:len(patch[0])-1]) bezier_points(columns(patch,i), samplepts)],
pts = [ pts = [
[bpatch[0][0]], [bpatch[0][0]],
for(j=[1:splinesteps]) bezier_points(subindex(bpatch,j), lerpn(0,1,rowmax[j]+1)) for(j=[1:splinesteps]) bezier_points(columns(bpatch,j), lerpn(0,1,rowmax[j]+1))
], ],
vnf = vnf_tri_array(pts, reverse=!reverse) vnf = vnf_tri_array(pts, reverse=!reverse)
) [ ) [
vnf, vnf,
[ [
subindex(pts,0), columns(pts,0),
[for(row=pts) last(row)], [for(row=pts) last(row)],
pts[0], pts[0],
last(pts), last(pts),

View file

@ -1121,7 +1121,7 @@ module sp_neck(diam,type,wall,id,style="L",bead=false, anchor, spin, orient)
isect400 = [for(seg=pair(beadpts)) let(segisect = line_intersection([[T/2,0],[T/2,1]] , seg, LINE, SEGMENT)) if (is_def(segisect)) segisect.y]; isect400 = [for(seg=pair(beadpts)) let(segisect = line_intersection([[T/2,0],[T/2,1]] , seg, LINE, SEGMENT)) if (is_def(segisect)) segisect.y];
extra_bot = type==400 && bead ? -min(subindex(beadpts,1))+max(isect400) : 0; extra_bot = type==400 && bead ? -min(columns(beadpts,1))+max(isect400) : 0;
bead_shift = type==400 ? H+max(isect400) : entry[5]+W/2; // entry[5] is L bead_shift = type==400 ? H+max(isect400) : entry[5]+W/2; // entry[5] is L
attachable(anchor,spin,orient,r=bead ? beadmax : T/2, l=H+extra_bot){ attachable(anchor,spin,orient,r=bead ? beadmax : T/2, l=H+extra_bot){

View file

@ -1965,7 +1965,7 @@ function align_polygon(reference, poly, angles, cp, trans, return_ind=false) =
return_error=true return_error=true
) )
], ],
scores = subindex(alignments,1), scores = columns(alignments,1),
minscore = min(scores), minscore = min(scores),
minind = [for(i=idx(scores)) if (scores[i]<minscore+EPSILON) i], minind = [for(i=idx(scores)) if (scores[i]<minscore+EPSILON) i],
dummy = is_def(angles) ? echo(best_angles = select(list(angles), minind)):0, dummy = is_def(angles) ? echo(best_angles = select(list(angles), minind)):0,

View file

@ -999,7 +999,7 @@ function null_space(A,eps=1e-12) =
zrow = [for(i=idx(R)) if (all_zero(R[i],eps)) i] zrow = [for(i=idx(R)) if (all_zero(R[i],eps)) i]
) )
len(zrow)==0 ? [] : len(zrow)==0 ? [] :
transpose(subindex(Q_R[0],zrow)); transpose(columns(Q_R[0],zrow));
// Function: qr_factor() // Function: qr_factor()

View file

@ -427,7 +427,7 @@ function resample_path(path, N, spacing, closed=false) =
distlist = lerpn(0,length,N,false), distlist = lerpn(0,length,N,false),
cuts = _path_cut_points(path, distlist, closed=closed) cuts = _path_cut_points(path, distlist, closed=closed)
) )
[ each subindex(cuts,0), [ each columns(cuts,0),
if (!closed) last(path) // Then add last point here if (!closed) last(path) // Then add last point here
]; ];
@ -1174,7 +1174,7 @@ function _assemble_path_fragments(fragments, eps=EPSILON, _finished=[]) =
len(fragments)==0? _finished : len(fragments)==0? _finished :
let( let(
minxidx = min_index([ minxidx = min_index([
for (frag=fragments) min(subindex(frag,0)) for (frag=fragments) min(columns(frag,0))
]), ]),
result_l = _assemble_a_path_from_fragments( result_l = _assemble_a_path_from_fragments(
fragments=fragments, fragments=fragments,

View file

@ -267,7 +267,7 @@ function _region_region_intersections(region1, region2, closed1=true,closed2=tru
cornerpts = [for(i=[0:1]) cornerpts = [for(i=[0:1])
[for(k=vector_search(points[i],eps,points[i])) [for(k=vector_search(points[i],eps,points[i]))
each if (len(k)>1) select(ptind[i],k)]], each if (len(k)>1) select(ptind[i],k)]],
risect = [for(i=[0:1]) concat(subindex(intersections,i), cornerpts[i])], risect = [for(i=[0:1]) concat(columns(intersections,i), cornerpts[i])],
counts = [count(len(region1)), count(len(region2))], counts = [count(len(region1)), count(len(region2))],
pathind = [for(i=[0:1]) search(counts[i], risect[i], 0)] pathind = [for(i=[0:1]) search(counts[i], risect[i], 0)]
) )

View file

@ -1270,7 +1270,7 @@ module convex_offset_extrude(
// The entry r[i] is [radius,z] for a given layer // The entry r[i] is [radius,z] for a given layer
r = move([0,bottom_height],p=concat( r = move([0,bottom_height],p=concat(
reverse(offsets_bot), [[0,0], [0,middle]], move([0,middle], p=offsets_top))); reverse(offsets_bot), [[0,0], [0,middle]], move([0,middle], p=offsets_top)));
delta = [for(val=deltas(subindex(r,0))) sign(val)]; delta = [for(val=deltas(columns(r,0))) sign(val)];
below=[-thickness,0]; below=[-thickness,0];
above=[0,thickness]; above=[0,thickness];
// layers is a list of pairs of the relative positions for each layer, e.g. [0,thickness] // layers is a list of pairs of the relative positions for each layer, e.g. [0,thickness]
@ -1937,8 +1937,8 @@ function rounded_prism(bottom, top, joint_bot=0, joint_top=0, joint_sides=0, k_b
verify_vert = verify_vert =
[for(i=[0:N-1],j=[0:4]) [for(i=[0:N-1],j=[0:4])
let( let(
vline = concat(select(subindex(top_patch[i],j),2,4), vline = concat(select(columns(top_patch[i],j),2,4),
select(subindex(bot_patch[i],j),2,4)) select(columns(bot_patch[i],j),2,4))
) )
if (!is_collinear(vline)) [i,j]], if (!is_collinear(vline)) [i,j]],
//verify horiz edges //verify horiz edges
@ -1955,8 +1955,8 @@ function rounded_prism(bottom, top, joint_bot=0, joint_top=0, joint_sides=0, k_b
"Roundovers interfere with each other on bottom face: either input is self intersecting or top joint length is too large") "Roundovers interfere with each other on bottom face: either input is self intersecting or top joint length is too large")
assert(debug || (verify_vert==[] && verify_horiz==[]), "Curvature continuity failed") assert(debug || (verify_vert==[] && verify_horiz==[]), "Curvature continuity failed")
let( let(
vnf = vnf_merge([ each subindex(top_samples,0), vnf = vnf_merge([ each columns(top_samples,0),
each subindex(bot_samples,0), each columns(bot_samples,0),
for(pts=edge_points) vnf_vertex_array(pts), for(pts=edge_points) vnf_vertex_array(pts),
debug ? vnf_from_polygons(faces) debug ? vnf_from_polygons(faces)
: vnf_triangulate(vnf_from_polygons(faces)) : vnf_triangulate(vnf_from_polygons(faces))
@ -2114,7 +2114,7 @@ function _circle_mask(r) =
// ]), // ]),
// radius = [0,0,each repeat(slotradius,4),0,0], closed=false // radius = [0,0,each repeat(slotradius,4),0,0], closed=false
// ) // )
// ) apply(left(max(subindex(slot,0))/2)*fwd(min(subindex(slot,1))), slot); // ) apply(left(max(columns(slot,0))/2)*fwd(min(columns(slot,1))), slot);
// stroke(slot(15,29,7)); // stroke(slot(15,29,7));
// Example: A cylindrical container with rounded edges and a rounded finger slot. // Example: A cylindrical container with rounded edges and a rounded finger slot.
// function slot(slotwidth, slotheight, slotradius) = let( // function slot(slotwidth, slotheight, slotradius) = let(
@ -2138,7 +2138,7 @@ function _circle_mask(r) =
// ]), // ]),
// radius = [0,0,each repeat(slotradius,4),0,0], closed=false // radius = [0,0,each repeat(slotradius,4),0,0], closed=false
// ) // )
// ) apply(left(max(subindex(slot,0))/2)*fwd(min(subindex(slot,1))), slot); // ) apply(left(max(columns(slot,0))/2)*fwd(min(columns(slot,1))), slot);
// diam = 80; // diam = 80;
// wall = 4; // wall = 4;
// height = 40; // height = 40;
@ -2162,12 +2162,12 @@ module bent_cutout_mask(r, thickness, path, radius, convexity=10)
path = clockwise_polygon(path); path = clockwise_polygon(path);
curvepoints = arc(d=thickness, angle = [-180,0]); curvepoints = arc(d=thickness, angle = [-180,0]);
profiles = [for(pt=curvepoints) _cyl_hole(r+pt.x,apply(xscale((r+pt.x)/r), offset(path,delta=thickness/2+pt.y,check_valid=false,closed=true)))]; profiles = [for(pt=curvepoints) _cyl_hole(r+pt.x,apply(xscale((r+pt.x)/r), offset(path,delta=thickness/2+pt.y,check_valid=false,closed=true)))];
pathx = subindex(path,0); pathx = columns(path,0);
minangle = (min(pathx)-thickness/2)*360/(2*PI*r); minangle = (min(pathx)-thickness/2)*360/(2*PI*r);
maxangle = (max(pathx)+thickness/2)*360/(2*PI*r); maxangle = (max(pathx)+thickness/2)*360/(2*PI*r);
mindist = (r+thickness/2)/cos((maxangle-minangle)/2); mindist = (r+thickness/2)/cos((maxangle-minangle)/2);
assert(maxangle-minangle<180,"Cutout angle span is too large. Must be smaller than 180."); assert(maxangle-minangle<180,"Cutout angle span is too large. Must be smaller than 180.");
zmean = mean(subindex(path,1)); zmean = mean(columns(path,1));
innerzero = repeat([0,0,zmean], len(path)); innerzero = repeat([0,0,zmean], len(path));
outerpt = repeat( [1.5*mindist*cos((maxangle+minangle)/2),1.5*mindist*sin((maxangle+minangle)/2),zmean], len(path)); outerpt = repeat( [1.5*mindist*cos((maxangle+minangle)/2),1.5*mindist*sin((maxangle+minangle)/2),zmean], len(path));
vnf_polyhedron(vnf_vertex_array([innerzero, each profiles, outerpt],col_wrap=true),convexity=convexity); vnf_polyhedron(vnf_vertex_array([innerzero, each profiles, outerpt],col_wrap=true),convexity=convexity);

View file

@ -363,7 +363,7 @@ function regular_ngon(n=6, r, d, or, od, ir, id, side, rounding=0, realign=false
) )
each arc(N=steps, cp=p, r=rounding, start=a+180/n, angle=-360/n) each arc(N=steps, cp=p, r=rounding, start=a+180/n, angle=-360/n)
], ],
maxx_idx = max_index(subindex(path2,0)), maxx_idx = max_index(columns(path2,0)),
path3 = polygon_shift(path2,maxx_idx) path3 = polygon_shift(path2,maxx_idx)
) path3 ) path3
), ),
@ -961,7 +961,7 @@ function teardrop2d(r, ang=45, cap_h, d, anchor=CENTER, spin=0) =
[-cap_w,cap_h] [-cap_w,cap_h]
], closed=true ], closed=true
), ),
maxx_idx = max_index(subindex(path,0)), maxx_idx = max_index(columns(path,0)),
path2 = polygon_shift(path,maxx_idx) path2 = polygon_shift(path,maxx_idx)
) reorient(anchor,spin, two_d=true, path=path2, p=path2); ) reorient(anchor,spin, two_d=true, path=path2, p=path2);
@ -1016,7 +1016,7 @@ function glued_circles(r, spread=10, tangent=30, d, anchor=CENTER, spin=0) =
[for (i=[0:1:lobesegs]) let(a=sa1+i*lobestep+180) r * [cos(a),sin(a)] + cp1], [for (i=[0:1:lobesegs]) let(a=sa1+i*lobestep+180) r * [cos(a),sin(a)] + cp1],
tangent==0? [] : [for (i=[0:1:arcsegs]) let(a=ea2-i*arcstep) r2 * [cos(a),sin(a)] + cp2] tangent==0? [] : [for (i=[0:1:arcsegs]) let(a=ea2-i*arcstep) r2 * [cos(a),sin(a)] + cp2]
), ),
maxx_idx = max_index(subindex(path,0)), maxx_idx = max_index(columns(path,0)),
path2 = reverse_polygon(polygon_shift(path,maxx_idx)) path2 = reverse_polygon(polygon_shift(path,maxx_idx))
) reorient(anchor,spin, two_d=true, path=path2, extent=true, p=path2); ) reorient(anchor,spin, two_d=true, path=path2, extent=true, p=path2);

View file

@ -2211,7 +2211,7 @@ module path_text(path, text, font, size, thickness, lettersize, offset=0, revers
usernorm = is_def(normal); usernorm = is_def(normal);
usetop = is_def(top); usetop = is_def(top);
normpts = is_undef(normal) ? (reverse?1:-1)*subindex(pts,3) : _cut_interp(pts,path, normal); normpts = is_undef(normal) ? (reverse?1:-1)*columns(pts,3) : _cut_interp(pts,path, normal);
toppts = is_undef(top) ? undef : _cut_interp(pts,path,top); toppts = is_undef(top) ? undef : _cut_interp(pts,path,top);
for(i=idx(text)) for(i=idx(text))
let( tangent = pts[i][2] ) let( tangent = pts[i][2] )

View file

@ -985,7 +985,7 @@ function path_sweep2d(shape, path, closed=false, caps, quality=1, style="min_edg
[for(pt = profile) [for(pt = profile)
let( let(
ofs = offset(path, delta=-flip*pt.x, return_faces=true,closed=closed, quality=quality), ofs = offset(path, delta=-flip*pt.x, return_faces=true,closed=closed, quality=quality),
map = subindex(_ofs_vmap(ofs,closed=closed),1) map = columns(_ofs_vmap(ofs,closed=closed),1)
) )
select(path3d(ofs[0],pt.y),map) select(path3d(ofs[0],pt.y),map)
] ]

View file

@ -433,14 +433,14 @@ module test_add_scalar() {
test_add_scalar(); test_add_scalar();
module test_subindex() { module test_columns() {
v = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]]; v = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]];
assert(subindex(v,2) == [3, 7, 11, 15]); assert(columns(v,2) == [3, 7, 11, 15]);
assert(subindex(v,[2]) == [[3], [7], [11], [15]]); assert(columns(v,[2]) == [[3], [7], [11], [15]]);
assert(subindex(v,[2,1]) == [[3, 2], [7, 6], [11, 10], [15, 14]]); assert(columns(v,[2,1]) == [[3, 2], [7, 6], [11, 10], [15, 14]]);
assert(subindex(v,[1:3]) == [[2, 3, 4], [6, 7, 8], [10, 11, 12], [14, 15, 16]]); assert(columns(v,[1:3]) == [[2, 3, 4], [6, 7, 8], [10, 11, 12], [14, 15, 16]]);
} }
test_subindex(); test_columns();
// Need decision about behavior for out of bounds ranges, empty ranges // Need decision about behavior for out of bounds ranges, empty ranges
@ -532,7 +532,7 @@ module test_hstack() {
a = hstack(v1,v2); a = hstack(v1,v2);
b = hstack(v1,v2,v3); b = hstack(v1,v2,v3);
c = hstack([M,v1,M]); c = hstack([M,v1,M]);
d = hstack(subindex(M,0), subindex(M,[1, 2])); d = hstack(columns(M,0), columns(M,[1, 2]));
assert_equal(a,[[2, 5], [3, 6], [4, 7]]); assert_equal(a,[[2, 5], [3, 6], [4, 7]]);
assert_equal(b,[[2, 5, 8], [3, 6, 9], [4, 7, 10]]); assert_equal(b,[[2, 5, 8], [3, 6, 9], [4, 7, 10]]);
assert_equal(c,[[1, 0, 0, 2, 1, 0, 0], [0, 1, 0, 3, 0, 1, 0], [0, 0, 1, 4, 0, 0, 1]]); assert_equal(c,[[1, 0, 0, 2, 1, 0, 0], [0, 1, 0, 3, 0, 1, 0], [0, 0, 1, 4, 0, 0, 1]]);

View file

@ -994,7 +994,7 @@ module test_linear_solve(){
-8.378819388897780e-01, -8.378819388897780e-01,
2.330507118860985e-01, 2.330507118860985e-01,
8.511278195488737e-01]); 8.511278195488737e-01]);
assert_approx(linear_solve(subindex(M,[0:2]), [2,4,4,4]), assert_approx(linear_solve(columns(M,[0:2]), [2,4,4,4]),
[-2.457142857142859e-01, [-2.457142857142859e-01,
5.200000000000000e-01, 5.200000000000000e-01,
7.428571428571396e-02]); 7.428571428571396e-02]);

View file

@ -926,8 +926,8 @@ module generic_threaded_rod(
assert(higang1 < twist/2); assert(higang1 < twist/2);
assert(higang2 < twist/2); assert(higang2 < twist/2);
prof3d = path3d(profile); prof3d = path3d(profile);
pdepth = -min(subindex(profile,1)); pdepth = -min(columns(profile,1));
pmax = pitch * max(subindex(profile,1)); pmax = pitch * max(columns(profile,1));
rmax = max(_r1,_r2)+pmax; rmax = max(_r1,_r2)+pmax;
depth = pdepth * pitch; depth = pdepth * pitch;
dummy1 = assert(_r1>depth && _r2>depth, "Screw profile deeper than rod radius"); dummy1 = assert(_r1>depth && _r2>depth, "Screw profile deeper than rod radius");
@ -1087,7 +1087,7 @@ module generic_threaded_nut(
bevel1 = first_defined([bevel1,bevel,false]); bevel1 = first_defined([bevel1,bevel,false]);
bevel2 = first_defined([bevel2,bevel,false]); bevel2 = first_defined([bevel2,bevel,false]);
dummy1 = assert(is_num(pitch) && pitch>0); dummy1 = assert(is_num(pitch) && pitch>0);
depth = -pitch*min(subindex(profile,1)); depth = -pitch*min(columns(profile,1));
attachable(anchor,spin,orient, size=[od/cos(30),od,h]) { attachable(anchor,spin,orient, size=[od/cos(30),od,h]) {
difference() { difference() {
cyl(d=od/cos(30), h=h, center=true, $fn=6,chamfer1=bevel1?depth:undef,chamfer2=bevel2?depth:undef); cyl(d=od/cos(30), h=h, center=true, $fn=6,chamfer1=bevel1?depth:undef,chamfer2=bevel2?depth:undef);

View file

@ -504,8 +504,8 @@ function vector_nearest(query, k, target) =
"More results are requested than the number of points.") "More results are requested than the number of points.")
tgpts tgpts
? let( tree = _bt_tree(target, count(len(target))) ) ? let( tree = _bt_tree(target, count(len(target))) )
subindex(_bt_nearest( query, k, target, tree),0) columns(_bt_nearest( query, k, target, tree),0)
: subindex(_bt_nearest( query, k, target[0], target[1]),0); : columns(_bt_nearest( query, k, target[0], target[1]),0);
//Ball tree nearest //Ball tree nearest

View file

@ -354,7 +354,7 @@ function vnf_from_polygons(polygons) =
function _path_path_closest_vertices(path1,path2) = function _path_path_closest_vertices(path1,path2) =
let( let(
dists = [for (i=idx(path1)) let(j=closest_point(path1[i],path2)) [j,norm(path2[j]-path1[i])]], dists = [for (i=idx(path1)) let(j=closest_point(path1[i],path2)) [j,norm(path2[j]-path1[i])]],
i1 = min_index(subindex(dists,1)), i1 = min_index(columns(dists,1)),
i2 = dists[i1][0] i2 = dists[i1][0]
) [dists[i1][1], i1, i2]; ) [dists[i1][1], i1, i2];
@ -384,7 +384,7 @@ function _cleave_connected_region(region) =
for (i=[1:1:len(region)-1]) for (i=[1:1:len(region)-1])
_path_path_closest_vertices(region[0],region[i]) _path_path_closest_vertices(region[0],region[i])
], ],
idxi = min_index(subindex(dists,0)), idxi = min_index(columns(dists,0)),
newoline = _join_paths_at_vertices( newoline = _join_paths_at_vertices(
region[0], region[idxi+1], region[0], region[idxi+1],
dists[idxi][1], dists[idxi][2] dists[idxi][1], dists[idxi][2]
@ -479,7 +479,7 @@ function vnf_faces(vnf) = vnf[1];
// Usage: // Usage:
// rvnf = vnf_reverse_faces(vnf); // rvnf = vnf_reverse_faces(vnf);
// Description: // Description:
// Reverses the facing of all the faces in the given VNF. // Reverses the orientation of all the faces in the given VNF.
function vnf_reverse_faces(vnf) = function vnf_reverse_faces(vnf) =
[vnf[0], [for (face=vnf[1]) reverse(face)]]; [vnf[0], [for (face=vnf[1]) reverse(face)]];
@ -568,7 +568,7 @@ function vnf_slice(vnf,dir,cuts) =
function _split_polygon_at_x(poly, x) = function _split_polygon_at_x(poly, x) =
let( let(
xs = subindex(poly,0) xs = columns(poly,0)
) (min(xs) >= x || max(xs) <= x)? [poly] : ) (min(xs) >= x || max(xs) <= x)? [poly] :
let( let(
poly2 = [ poly2 = [