mirror of
https://github.com/revarbat/BOSL2.git
synced 2025-08-31 11:42:02 +02:00
Adds sweep and new version of path_sweep to skin.scad, which probably
needs a name change. Adds apply(), apply_list() and affine_frame_map() to affine.scad. Adds derivative calcluation to math.scad. Adds path_tangent, path_normal, path_curvature and path_torsion functions. Adds path_length_fraction(). Fixed bug in reindex_polygon where it randomly reverses a 3d path (due to clockwise check that is bogus in 3d) and put a check in polygon_is_clockwise to trap this case.
This commit is contained in:
62
affine.scad
62
affine.scad
@@ -379,4 +379,66 @@ function affine3d_apply(pts, affines) =
|
||||
|
||||
|
||||
|
||||
// Function: apply()
|
||||
// Usage: apply(transform, points)
|
||||
// Description:
|
||||
// Applies the specified transformation matrix to a point list (or single point). Both inputs can be 2d or 3d, and it is also allowed
|
||||
// to supply 3d transformations with 2d data as long as the the only action on the z coordinate is a simple scaling.
|
||||
// Examples:
|
||||
// transformed = apply(xrot(45), path3d(circle(r=3))); // Rotates 3d circle data around x axis
|
||||
// transformed = apply(rot(45), circle(r=3)); // Rotates 2d circle data by 45 deg
|
||||
// transformed = apply(rot(45)*right(4)*scale(3), circle(r=3)); // Scales, translates and rotates 2d circle data
|
||||
function apply(transform,points) =
|
||||
is_vector(points) ? apply(transform, [points])[0] :
|
||||
let(
|
||||
tdim = len(transform[0])-1,
|
||||
datadim = len(points[0])
|
||||
)
|
||||
tdim == 3 && datadim == 3 ? [for(p=points) point3d(transform*concat(p,[1]))] :
|
||||
tdim == 2 && datadim == 2 ? [for(p=points) point2d(transform*concat(p,[1]))] :
|
||||
tdim == 3 && datadim == 2 ?
|
||||
assert(is_2d_transform(transform),str("Transforms is 3d but points are 2d"))
|
||||
[for(p=points) point2d(transform*concat(p,[0,1]))] :
|
||||
assert(false,str("Unsupported combination: transform with dimension ",tdim,", data of dimension ",datadim));
|
||||
|
||||
|
||||
// Function: apply_list()
|
||||
// Usage: apply_list(points, transform_list)
|
||||
// Description:
|
||||
// Transforms the specified point list (or single point) using a list of transformation matrices. Transformations on
|
||||
// the list are applied in the order they appear in the list (as in right multiplication of matrices). Both inputs can be
|
||||
// 2d or 3d, and it is also allowed to supply 3d transformations with 2d data as long as the the only action on the z coordinate
|
||||
// is a simple scaling. All transformations on `transform_list` must have the same dimension: you cannot mix 2d and 3d transformations
|
||||
// even when acting on 2d data.
|
||||
// Examples:
|
||||
// transformed = apply_list(path3d(circle(r=3)),[xrot(45)]); // Rotates 3d circle data around x axis
|
||||
// transformed = apply_list(circle(r=3), [scale(3), right(4), rot(45)]); // Scales, then translates, and then rotates 2d circle data
|
||||
function apply_list(points,transform_list) =
|
||||
is_vector(points) ? apply_list([points],transform_list)[0] :
|
||||
let(
|
||||
tdims = array_dim(transform_list),
|
||||
datadim = len(points[0])
|
||||
)
|
||||
assert(len(tdims)==3 || tdims[1]!=tdims[2], "Invalid transformation list")
|
||||
let( tdim = tdims[1]-1 )
|
||||
tdim==2 && datadim == 2 ? apply(affine2d_chain(transform_list), points) :
|
||||
tdim==3 && datadim == 3 ? apply(affine3d_chain(transform_list), points) :
|
||||
tdim==3 && datadim == 2 ?
|
||||
let(
|
||||
badlist = [for(i=idx(transform_list)) if (!is_2d_transform(transform_list[i])) i]
|
||||
)
|
||||
assert(badlist==[],str("Transforms with indices ",badlist," are 3d but points are 2d"))
|
||||
apply(affine3d_chain(transform_list), points) :
|
||||
assert(false,str("Unsupported combination: transform with dimension ",tdim,", data of dimension ",datadim));
|
||||
|
||||
|
||||
// Function: is_2d_transform()
|
||||
// Usage: is_2d_transform(t)
|
||||
// Description: Checks if the input is a 3d transform that does not act on the z coordinate, except
|
||||
// possibly for a simple scaling of z. Note that an input which is only a zscale returns false.
|
||||
function is_2d_transform(t) = // z-parameters are zero, except we allow t[2][2]!=1 so scale() works
|
||||
t[2][0]==0 && t[2][1]==0 && t[2][3]==0 && t[0][2] == 0 && t[1][2]==0 &&
|
||||
(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
|
||||
|
Reference in New Issue
Block a user