Math 将快速逆应用于串联4x4仿射变换?
是否可以将矩阵的快速逆应用于纯旋转矩阵和平移矩阵的串联,例如Math 将快速逆应用于串联4x4仿射变换?,math,matrix,linear-algebra,Math,Matrix,Linear Algebra,是否可以将矩阵的快速逆应用于纯旋转矩阵和平移矩阵的串联,例如M=T2*R1*T1*R1 如果旋转和平移存储在4x4齐次列顺序矩阵中,我可以说: M1 = [ R1 t1 ] given by [ 1 t1 ] * [ R1 0 ] [ 0 1 ] [ 0 1 ] [ 0 1 ] 及 因为R1是旋转,所以我们知道inv(R1)=转置(R1),所以我们可以简单地说: inv(M1) = [transp(R1) transp(R1)*-t1 ]
M=T2*R1*T1*R1
如果旋转和平移存储在4x4齐次列顺序矩阵中,我可以说:
M1 = [ R1 t1 ] given by [ 1 t1 ] * [ R1 0 ]
[ 0 1 ] [ 0 1 ] [ 0 1 ]
及
因为R1是旋转,所以我们知道inv(R1)=转置(R1),所以我们可以简单地说:
inv(M1) = [transp(R1) transp(R1)*-t1 ]
[ 0 1 ]
现在给出一些其他类似的旋转和平移矩阵M2,若我们说这两个矩阵的串联形式是MFinal=M2*M1=T2*R1*T1*R1
我们可以这么说吗
inv(MFinal) = [transp(MFinalRot) transp(MFinalRot)*-tfinal ]
[ 0 1 ]
其中,MFinalRot是4x4矩阵的旋转部分
此外,如果顺序更为任意,例如
MFinal2=R3*T3*T2*R2*T1*R1
,但仍仅单独旋转和平移,该怎么办?是的,如果4x4矩阵是纯旋转和平移矩阵的串联,则应能够计算快速逆矩阵,如下所示:
fast_inverse( [R1 t1] ) = [transpose(R1) transpose(R1)*(-t1)]
[0 1] [ 0 1 ]
这是因为3x3旋转矩阵(R1
)将仅是输入旋转矩阵的乘积,因此它本身应该是旋转矩阵,其转置应该是其逆矩阵
如果任何串联矩阵是缩放矩阵,或者如果最下面一行不是[0 0 0 1]
,则这不再是真的
还要注意:在实践中,如果将足够多的矩阵相乘在一起,浮点错误可能会导致它们“漂移”一些,因此它们可能不像新生成的矩阵那样接近正确的旋转矩阵。根据您使用它的方式,这可能不是问题——但如果是,您可以“重新正交规格化”它,如下所示:
orth(Vec3 a, Vec3 b): // return value orthogonal to b
return (a - (dot(a,b)/dot(b,b)) * b)
re_orthonormalize(Mat3x3 Rin):
Vec3 x = Rin.x;
Vec3 y = orth(Rin.y, x);
Vec3 z = orth(orth(Rin.z, x), y);
return Mat3x3(normalize(x),normalize(y),normalize(z))
只要你的输入不是太远,这应该给你一个合适的旋转矩阵
要查看
re_正交规范化
代码的工作原理,首先获取orh
输出及其b
输入的点积。由于点积是线性的,我们有:
dot(a - (dot(a,b)/dot(b,b)*b, b)
== dot(a,b) - (dot(a,b)/dot(b,b)) * dot(b,b)
== dot(a,b) - dot(a,b)
== 0
因此,如果a
和b
已经基本上是正交的,ortho(a,b)
添加少量b
,以确保点积真的是0
这意味着在
re_正交规范化
中,y
与x
完全正交。棘手的一点是确保z
与x
和y
正交。这仅仅是因为我们已经确定了x
与y
完全正交,所以添加一点y
不会阻止orh(Rin.z,x)
与x正交,两个方阵的乘积(p=AB)的逆通常是Inv(B)*Inv(a)。旋转和平移将通勤。通常,您必须按照应用操作的相反顺序展开操作
但是在这种情况下,R1*T1*R2*T2=R1*R2*T1*T2,然后可以计算串联的逆,作为单个旋转和平移的合成的逆
是的,这是纯旋转和平移的声音。我不太理解重新正交规范化的代码,但我理解这个概念。例如,我可以说我将用x和z的叉积重新计算y轴,然后对所有3个轴进行规格化吗?您的重新规范化是否比这更正确/有效?是的。您需要确保所有三个输出向量彼此正交,并且点积可能更有效。好的,我明白了,另外,您如何决定何时执行此操作?我能想到的唯一一件事就是在每次X变换后都这样做,其中X=?好吧,试着将快速逆的结果与原始值相乘。如果结果离单位矩阵太远,你就有问题了。但是,你可能只需要累加任意数量的矩阵就可以了。如果你有一个旋转的立方体,每帧乘以一个小的旋转。。。
dot(a - (dot(a,b)/dot(b,b)*b, b)
== dot(a,b) - (dot(a,b)/dot(b,b)) * dot(b,b)
== dot(a,b) - dot(a,b)
== 0