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