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])