apply tweaks

This commit is contained in:
Adrian Mariano 2021-12-29 17:55:29 -05:00
parent 88e0c6aa15
commit 1d72c91454
3 changed files with 14 additions and 13 deletions

View file

@ -404,6 +404,8 @@ function affine3d_rot_from_to(from, to) =
from = unit(point3d(from)), from = unit(point3d(from)),
to = unit(point3d(to)) to = unit(point3d(to))
) approx(from,to)? affine3d_identity() : ) approx(from,to)? affine3d_identity() :
from.z==0 && to.z==0 ? affine3d_zrot(v_theta(point2d(to)) - v_theta(point2d(from)))
:
let( let(
u = vector_axis(from,to), u = vector_axis(from,to),
ang = vector_angle(from,to), ang = vector_angle(from,to),

View file

@ -462,7 +462,7 @@ function matrix_inverse(A) =
// B = rot_inverse(A) // B = rot_inverse(A)
// Description: // Description:
// Inverts a 2d (3x3) or 3d (4x4) rotation matrix. The matrix can be a rotation around any center, // Inverts a 2d (3x3) or 3d (4x4) rotation matrix. The matrix can be a rotation around any center,
// so it may include a translation. // so it may include a translation. This is faster and likely to be more accurate than using `matrix_inverse()`.
function rot_inverse(T) = function rot_inverse(T) =
assert(is_matrix(T,square=true),"Matrix must be square") assert(is_matrix(T,square=true),"Matrix must be square")
let( n = len(T)) let( n = len(T))

View file

@ -493,23 +493,21 @@ function rot(a=0, v, cp, from, to, reverse=false, planar=false, p=_NO_ARG, _m) =
v_theta(from) v_theta(from)
), ),
m2 = is_undef(cp)? m1 : (move(cp) * m1 * move(-cp)), m2 = is_undef(cp)? m1 : (move(cp) * m1 * move(-cp)),
m3 = reverse? matrix_inverse(m2) : m2 m3 = reverse? rot_inverse(m2) : m2
) m3 : let( ) m3 : let(
from = is_undef(from)? undef : point3d(from), from = is_undef(from)? undef : point3d(from),
to = is_undef(to)? undef : point3d(to), to = is_undef(to)? undef : point3d(to),
cp = is_undef(cp)? undef : point3d(cp), cp = is_undef(cp)? undef : point3d(cp),
m1 = !is_undef(from)? ( m1 = !is_undef(from) ?
assert(is_num(a)) assert(is_num(a))
(from.z == 0 && to.z == 0 affine3d_rot_from_to(from,to) * affine3d_rot_by_axis(from,a)
? affine3d_zrot(v_theta(point2d(to)) - v_theta(point2d(from))) : !is_undef(v)?
: affine3d_rot_from_to(from,to) assert(is_num(a))
) * affine3d_rot_by_axis(from,a) affine3d_rot_by_axis(v,a)
) : : is_num(a) ? affine3d_zrot(a)
!is_undef(v)? assert(is_num(a)) affine3d_rot_by_axis(v,a) : : affine3d_zrot(a.z) * affine3d_yrot(a.y) * affine3d_xrot(a.x),
is_num(a)? affine3d_zrot(a) :
affine3d_zrot(a.z) * affine3d_yrot(a.y) * affine3d_xrot(a.x),
m2 = is_undef(cp)? m1 : (move(cp) * m1 * move(-cp)), m2 = is_undef(cp)? m1 : (move(cp) * m1 * move(-cp)),
m3 = reverse? matrix_inverse(m2) : m2 m3 = reverse? rot_inverse(m2) : m2
) m3 ) m3
) )
p==_NO_ARG ? m : apply(m, p); p==_NO_ARG ? m : apply(m, p);
@ -1381,7 +1379,8 @@ function _apply(transform,points) =
assert(len(transform)==tdim || len(transform)-1==tdim, "transform matrix height not compatible with width") assert(len(transform)==tdim || len(transform)-1==tdim, "transform matrix height not compatible with width")
assert(datadim==2 || datadim==3,"Data must be 2D or 3D") assert(datadim==2 || datadim==3,"Data must be 2D or 3D")
let( let(
matrix = [for(i=[0:1:tdim]) [for(j=[0:1:datadim-1]) transform[j][i]]] scale = len(transform)==tdim ? 1 : transform[tdim][tdim],
matrix = [for(i=[0:1:tdim]) [for(j=[0:1:datadim-1]) transform[j][i]/scale]]
) )
tdim==datadim tdim==datadim
? [for(p=points) concat(p,1)] * matrix ? [for(p=points) concat(p,1)] * matrix