Merge pull request #793 from adrianVmariano/master

is_rotation
This commit is contained in:
Revar Desmera 2022-02-27 22:15:11 -08:00 committed by GitHub
commit df2deec07f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 3 deletions

View file

@ -62,6 +62,33 @@ function is_matrix_symmetric(A,eps=1e-12) =
approx(A,transpose(A), eps);
// Function: is_rotation()
// Usage:
// b = is_rotation(A, [dim], [centered])
// Description:
// Returns true if the input matrix is a square affine matrix that is a rotation around any point,
// or around the origin if `centered` is true.
// The matrix must be 3x3 (representing a 2d transformation) or 4x4 (representing a 3d transformation).
// You can set `dim` to 2 to require a 2d transform (3x3 matrix) or to 3 to require a 3d transform (4x4 matrix).
// Arguments:
// A = matrix to test
// dim = if set, specify dimension in which the transform operates (2 or 3)
// centered = if true then require rotation to be around the origin. Default: false
function is_rotation(A,dim,centered=false) =
let(n=len(A))
is_matrix(A,square=true)
&& ( n==3 || n==4 && (is_undef(dim) || dim==n-1))
&&
(
let(
rotpart = [for(i=[0:n-2]) [for(j=[0:n-2]) A[j][i]]]
)
approx(determinant(rotpart),1)
)
&&
(!centered || [for(row=[0:n-2]) if (!approx(A[row][n-1],0)) row]==[]);
// Function&Module: echo_matrix()
// Usage:
// echo_matrix(M, [description], [sig], [sep], [eps]);

View file

@ -907,9 +907,11 @@ module spiral_sweep(poly, h, r, turns=1, higbee, center, r1, r2, d, d1, d2, higb
// path_sweep(ushape, path3d(elliptic_arc), method="manual", normal=UP+RIGHT);
// Example(NoScales): It is easy to produce an invalid shape when your path has a smaller radius of curvature than the width of your shape. The exact threshold where the shape becomes invalid depends on the density of points on your path. The error may not be immediately obvious, as the swept shape appears fine when alone in your model, but adding a cube to the model reveals the problem. In this case the pentagon is turned so its longest direction points inward to create the singularity.
// qpath = [for(x=[-3:.01:3]) [x,x*x/1.8,0]];
// echo(radius_of_curvature = 1/max(path_curvature(qpath))); // Prints 0.9, but we use pentagon with radius of 1.0 > 0.9
// // Prints 0.9, but we use pentagon with radius of 1.0 > 0.9
// echo(radius_of_curvature = 1/max(path_curvature(qpath)));
// path_sweep(apply(rot(90),pentagon(r=1)), qpath, normal=BACK, method="manual");
// cube(0.5); // Adding a small cube forces a CGAL computation which reveals the error by displaying nothing or giving a cryptic message
// cube(0.5); // Adding a small cube forces a CGAL computation which reveals
// // the error by displaying nothing or giving a cryptic message
// Example(NoScales): Using the `relax` option we allow the profiles to deviate from orthogonality to the path. This eliminates the crease that broke the previous example because the sections are all parallel to each other.
// qpath = [for(x=[-3:.01:3]) [x,x*x/1.8,0]];
// path_sweep(apply(rot(90),pentagon(r=1)), qpath, normal=BACK, method="manual", relaxed=true);
@ -1111,7 +1113,7 @@ module spiral_sweep(poly, h, r, turns=1, higbee, center, r1, r2, d, d1, d2, higb
// path_sweep(region,
// circle(r=16,$fn=75),closed=true,
// twist=360/5*2,symmetry=5);
// Example: Cutting a cylinder with a curved path. Note that in this case, the incremental method produces just a slight twist but the natural method produces an extreme twist. But manual specification produces no twist, as desired:
// Example(Med,NoScales): Cutting a cylinder with a curved path. Note that in this case, the incremental method produces just a slight twist but the natural method produces an extreme twist. But manual specification produces no twist, as desired:
// $fn=90;
// r=8;
// thickness=1;