将快速逆应用于级联4x4仿射变换?

时间:2016-02-12 16:11:26

标签: 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 ]

inv(M1) = [inv(R1)  inv(R1)*-t1 ] given by [ 1  -t1 ] * [ inv(R1) 0 ] 
          [ 0             1     ]          [ 1    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,但仍然只是单独轮换和翻译,该怎么办?

2 个答案:

答案 0 :(得分:1)

是的,如果您的4x4矩阵是纯旋转矩阵和平移矩阵的串联,您应该能够计算快速逆矩阵:

fast_inverse( [R1  t1] ) = [transpose(R1)  transpose(R1)*(-t1)]
              [0    1]     [     0                1           ]

这是因为3x3旋转矩阵(代码中的R1)只是输入旋转矩阵的乘积,所以它本身应该是一个旋转矩阵,它的转置应该是它的反转。 / p>

如果你的任何连接矩阵都是缩放矩阵,或者底行不是[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_orthonormalize代码的工作原理,请先将orth输出的点积与其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

因此,如果ab已基本正交,ortho(a,b)会添加少量b以确保点积确实为0

这意味着在re_orthonormalize中,yx完全正交。棘手的一点是确保z xy正交。这只有效,因为我们已经确保xy完全正交,因此添加一点y并不会阻止orth(Rin.z, x)x正交$add_number = $twilio->account->incoming_phone_numbers->create(array( "PhoneNumber" => $number, "MessagingServiceSid" => "MG68f3...4b72", // Messaging Service ID on Twilio ));

答案 1 :(得分:0)

两个平方矩阵的乘积(P = AB)的倒数通常是Inv(B)* Inv(A)。轮换和翻译将通勤。通常,您必须按照应用顺序的相反方式展开操作。

在这种情况下,R1 * T1 * R2 * T2 = R1 * R2 * T1 * T2然后您可以计算连接的倒数,作为单个旋转和平移的组成的倒数。

所以是的,这对于纯粹的旋转和翻译来说是合理的。