From b0292842286b24fe997cb418930b255391e0a204 Mon Sep 17 00:00:00 2001 From: Adrian Mariano Date: Sat, 29 Feb 2020 19:45:49 -0500 Subject: [PATCH 1/6] 2 bug fixes --- joiners.scad | 2 +- rounding.scad | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/joiners.scad b/joiners.scad index c98e476..a6303ee 100644 --- a/joiners.scad +++ b/joiners.scad @@ -556,7 +556,7 @@ module dovetail(gender, length, l, width, w, height, h, angle, slope, taper, bac reverse(concat(smallend_points, xflip(p=reverse(smallend_points)))), reverse(concat(bigend_points, xflip(p=reverse(bigend_points)))) ], - convexity=4 + slices=0, convexity=4 ); } children(); diff --git a/rounding.scad b/rounding.scad index 3457ee0..a726688 100644 --- a/rounding.scad +++ b/rounding.scad @@ -911,8 +911,8 @@ module convex_offset_extrude( top = struct_set(argspec, top, grow=false); bottom = struct_set(argspec, bottom, grow=false); - offsets_bot = rounding_offsets(bottom, -1); - offsets_top = rounding_offsets(top, 1); + offsets_bot = _rounding_offsets(bottom, -1); + offsets_top = _rounding_offsets(top, 1); // "Extra" height enlarges the result beyond the requested height, so subtract it bottom_height = len(offsets_bot)==0 ? 0 : abs(select(offsets_bot,-1)[1]) - struct_val(bottom,"extra"); From ca167f6bb1db7da5236811aa6166288e1c6f335c Mon Sep 17 00:00:00 2001 From: Adrian Mariano Date: Sat, 29 Feb 2020 22:54:33 -0500 Subject: [PATCH 2/6] moved affine_frame_map to affine.scad --- affine.scad | 46 ++++++++++++++++++++++++++++++++++++++++++++++ skin.scad | 40 ---------------------------------------- 2 files changed, 46 insertions(+), 40 deletions(-) diff --git a/affine.scad b/affine.scad index f5ecdd9..422ee1f 100644 --- a/affine.scad +++ b/affine.scad @@ -259,6 +259,49 @@ function affine3d_rot_from_to(from, to) = let( ]; +// Function: affine_frame_map() +// Usage: map = affine_frame_map(x=v1,y=v2); +// map = affine_frame_map(x=v1,z=v2); +// map = affine_frame_map(y=v1,y=v2); +// map = affine_frame_map(v1,v2,v3); +// Description: +// Returns a transformation that maps one coordinate frame to another. You must specify two or three of `x`, `y`, and `z`. The specified +// axes are mapped to the vectors you supplied. If you give two inputs, the third vector is mapped to the appropriate normal to maintain a right hand coordinate system. +// If the vectors you give are orthogonal the result will be a rotation. The `reverse` parameter will supply the inverse map, which enables you +// to map two arbitrary coordinate systems two each other by using the canonical coordinate system as an intermediary. +// Arguments: +// x = Destination vector for x axis +// y = Destination vector for y axis +// z = Destination vector for z axis +// reverse = reverse direction of the map. Default: false +// Examples: +// T = affine_frame_map(x=[1,1,0], y=[-1,1]); // This map is just a rotation around the z axis +// T = affine_frame_map(x=[1,0,0], y=[1,1]); // This map is not a rotation because x and y aren't orthogonal +// // The next map sends [1,1,0] to [0,1,1] and [-1,1,0] to [0,-1,1] +// T = affine_frame_map(x=[0,1,1], y=[0,-1,1]) * affine_frame_map(x=[1,1,0], y=[-1,1,0],reverse=true); +function affine_frame_map(x,y,z, reverse=false) = + assert(num_defined([x,y,z])>=2, "Must define at least two inputs") + let( + xvalid = is_undef(x) || (is_vector(x) && len(x)==3), + yvalid = is_undef(y) || (is_vector(y) && len(y)==3), + zvalid = is_undef(z) || (is_vector(z) && len(z)==3) + ) + assert(xvalid,"Input x must be a length 3 vector") + assert(yvalid,"Input y must be a length 3 vector") + assert(zvalid,"Input z must be a length 3 vector") + let( + x = is_def(x) ? normalize(x) : undef, + y = is_def(y) ? normalize(y) : undef, + z = is_def(z) ? normalize(z) : undef, + map = is_undef(x) ? [cross(y,z), y, z] : + is_undef(y) ? [x, cross(z,x), z] : + is_undef(z) ? [x, y, cross(x,y)] : + [x, y, z] + ) + reverse ? affine2d_to_3d(map) : affine2d_to_3d(transpose(map)); + + + // Function: affine3d_mirror() // Usage: // mat = affine3d_mirror(v); @@ -441,4 +484,7 @@ function is_2d_transform(t) = // z-parameters are zero, except we allow t[2][ (t[2][2]==1 || !(t[0][0]==1 && t[0][1]==0 && t[1][0]==0 && t[1][1]==1)); // But rule out zscale() + + + // vim: noexpandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap diff --git a/skin.scad b/skin.scad index f9c4abc..3ca4fb2 100644 --- a/skin.scad +++ b/skin.scad @@ -779,46 +779,6 @@ module sweep(shape, transformations, closed=false, caps, convexity=10) { vnf_polyhedron(sweep(shape, transformations, closed, caps), convexity=convexity); } -// Function: affine_frame_map() -// Usage: map = affine_frame_map(x=v1,y=v2); -// map = affine_frame_map(x=v1,z=v2); -// map = affine_frame_map(y=v1,y=v2); -// map = affine_frame_map(v1,v2,v3); -// Description: -// Returns a transformation that maps one coordinate frame to another. You must specify two or three of `x`, `y`, and `z`. The specified -// axes are mapped to the vectors you supplied. If you give two inputs, the third vector is mapped to the appropriate normal to maintain a right hand coordinate system. -// If the vectors you give are orthogonal the result will be a rotation. The `reverse` parameter will supply the inverse map, which enables you -// to map two arbitrary coordinate systems two each other by using the canonical coordinate system as an intermediary. -// Arguments: -// x = Destination vector for x axis -// y = Destination vector for y axis -// z = Destination vector for z axis -// reverse = reverse direction of the map. Default: false -// Examples: -// T = affine_frame_map(x=[1,1,0], y=[-1,1]); // This map is just a rotation around the z axis -// T = affine_frame_map(x=[1,0,0], y=[1,1]); // This map is not a rotation because x and y aren't orthogonal -// // The next map sends [1,1,0] to [0,1,1] and [-1,1,0] to [0,-1,1] -// T = affine_frame_map(x=[0,1,1], y=[0,-1,1]) * affine_frame_map(x=[1,1,0], y=[-1,1,0],reverse=true); -function affine_frame_map(x,y,z, reverse=false) = - assert(num_defined([x,y,z])>=2, "Must define at least two inputs") - let( - xvalid = is_undef(x) || (is_vector(x) && len(x)==3), - yvalid = is_undef(y) || (is_vector(y) && len(y)==3), - zvalid = is_undef(z) || (is_vector(z) && len(z)==3) - ) - assert(xvalid,"Input x must be a length 3 vector") - assert(yvalid,"Input y must be a length 3 vector") - assert(zvalid,"Input z must be a length 3 vector") - let( - x = is_def(x) ? normalize(x) : undef, - y = is_def(y) ? normalize(y) : undef, - z = is_def(z) ? normalize(z) : undef, - map = is_undef(x) ? [cross(y,z), y, z] : - is_undef(y) ? [x, cross(z,x), z] : - is_undef(z) ? [x, y, cross(x,y)] : - [x, y, z] - ) - reverse ? affine2d_to_3d(map) : affine2d_to_3d(transpose(map)); // Function&Module: path_sweep() // Usage: path_sweep(shape, path, [method], [normal], [closed], [twist], [twist_by_length], [symmetry], [last_normal], [tangent], [relaxed], [caps], [convexity], [transforms]) From 5bd2cba0ff1d712f52d83810539492613bded939 Mon Sep 17 00:00:00 2001 From: Adrian Mariano Date: Sat, 29 Feb 2020 22:56:24 -0500 Subject: [PATCH 3/6] Added colons to "Function" doc strings --- math.scad | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/math.scad b/math.scad index ac99804..d270831 100644 --- a/math.scad +++ b/math.scad @@ -814,7 +814,7 @@ function count_true(l, nmax=undef, i=0, cnt=0) = // Section: Calculus -// Function deriv() +// Function: deriv() // Usage: deriv(data, [h], [closed]) // Description: // Computes a numerical derivative estimate of the data, which may be scalar or vector valued. @@ -839,7 +839,7 @@ function deriv(data, h=1, closed=false) = last/2/h]; -// Function deriv2() +// Function: deriv2() // Usage: deriv2(data, [h], [closed]) // Description: // Computes a numerical esimate of the second derivative of the data, which may be scalar or vector valued. @@ -869,7 +869,7 @@ function deriv2(data, h=1, closed=false) = -// Function deriv3() +// Function: deriv3() // Usage: deriv3(data, [h], [closed]) // Description: // Computes a numerical third derivative estimate of the data, which may be scalar or vector valued. From 1e6cf426a9067f03c60436af86ff2caddb6663ca Mon Sep 17 00:00:00 2001 From: Adrian Mariano Date: Sat, 29 Feb 2020 22:59:39 -0500 Subject: [PATCH 4/6] changed order so linear_solve and submatrix are first. --- math.scad | 72 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/math.scad b/math.scad index d270831..010c307 100644 --- a/math.scad +++ b/math.scad @@ -532,6 +532,43 @@ function mean(v) = sum(v)/len(v); // Section: Matrix math +// Function: linear_solve() +// Usage: linear_solve(A,b) +// Description: +// Solves the linear system Ax=b. If A is square and non-singular the unique solution is returned. If A is overdetermined +// the least squares solution is returned. If A is underdetermined, the minimal norm solution is returned. +// If A is rank deficient or singular then linear_solve returns `undef`. +function linear_solve(A,b) = + let( + dim = array_dim(A), + m=dim[0], n=dim[1] + ) + assert(len(b)==m,str("Incompatible matrix and vector",dim,len(b))) + let ( + qr = m Date: Sat, 29 Feb 2020 23:09:16 -0500 Subject: [PATCH 5/6] Tweaked docs for reindex_polygon --- geometry.scad | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/geometry.scad b/geometry.scad index 5670134..3d52ffe 100644 --- a/geometry.scad +++ b/geometry.scad @@ -1030,13 +1030,13 @@ function polygon_shift_to_closest_point(path, pt) = // Usage: // newpoly = reindex_polygon(reference, poly); // Description: -// Rotates and possibly reverses the point order of a polygon path to optimize its pairwise point -// association with a reference polygon. The two polygons must have the same number of vertices. +// Rotates and possibly reverses the point order of a 2d or 3d polygon path to optimize its pairwise point +// association with a reference polygon. The two polygons must have the same number of vertices and be the same dimension. // The optimization is done by computing the distance, norm(reference[i]-poly[i]), between // corresponding pairs of vertices of the two polygons and choosing the polygon point order that // makes the total sum over all pairs as small as possible. Returns the reindexed polygon. Note // that the geometry of the polygon is not changed by this operation, just the labeling of its -// vertices. If the input polygon is oriented opposite the reference then its point order is +// vertices. If the input polygon is 2d and is oriented opposite the reference then its point order is // flipped. // Arguments: // reference = reference polygon path From d0e625809e7d4dc73b4140587dbfa40a592a28b8 Mon Sep 17 00:00:00 2001 From: Adrian Mariano Date: Sat, 29 Feb 2020 23:29:00 -0500 Subject: [PATCH 6/6] fixed last example for better view --- skin.scad | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skin.scad b/skin.scad index 3ca4fb2..0155eee 100644 --- a/skin.scad +++ b/skin.scad @@ -1051,7 +1051,7 @@ module sweep(shape, transformations, closed=false, caps, convexity=10) { // path_sweep(ushape,knot_path,normal=normals, method="manual", closed=true); // Example: You can request the transformations and manipulate them before passing them on to sweep. Here we construct a tube that changes scale by first generating the transforms and then applying the scale factor and connecting the inside and outside. Note that the wall thickness varies because it is produced by scaling. // shape = star(n=5, r=10, ir=5); -// rpath = arc(25, points=[[-30,0,0], [-3,1,7], [0,3,6]]); +// rpath = arc(25, points=[[29,6,-4], [3,4,6], [1,1,7]]); // trans = path_sweep(shape, rpath, transforms=true); // outside = [for(i=[0:len(trans)-1]) trans[i]*scale(lerp(1,1.5,i/(len(trans)-1)))]; // inside = [for(i=[len(trans)-1:-1:0]) trans[i]*scale(lerp(1.1,1.4,i/(len(trans)-1)))];