【发布时间】:2015-05-29 18:46:44
【问题描述】:
我有一个 4x4 矩阵,其中包含平移、旋转和缩放组件,但没有剪切或其他转换。我如何找到它的倒数?我在 C++ 中使用 Eigen 库。
【问题讨论】:
标签: c++ linear-algebra eigen
我有一个 4x4 矩阵,其中包含平移、旋转和缩放组件,但没有剪切或其他转换。我如何找到它的倒数?我在 C++ 中使用 Eigen 库。
【问题讨论】:
标签: c++ linear-algebra eigen
这很难做到,因为操作需要以正确的顺序执行:
template<class Derived>
Matrix4f AffineInverse(const Eigen::MatrixBase<Derived>& mat)
{
Matrix3f RotSclInv = (
mat.block<3, 3>(0, 0).array().rowwise()
/ mat.block<3, 3>(0, 0).colwise().squaredNorm().array() //scaling
).transpose(); //rotation
return (Matrix4f(4,4) << RotSclInv
, -RotSclInv * mat.block<3, 1>(0, 3) //translation
, 0, 0, 0, 1).finished();
}
正如this answer所说,左上角3x3块的逆可以单独计算:
inv ([ A b ]) = [inv(A) -inv(A)*b]
([ 0 1 ]) [ 0 1 ]
左上块的关键见解是缩放和旋转等于正交(旋转)矩阵Q 乘以对角线(缩放)矩阵D:Q*D。要反转它,请做一些线性代数:
inv(Q*D)
= transp(transp(inv(Q*D)))
= transp(inv(transp(Q*D)))
= transp(inv(transp(D)*transp(Q)))
(参见this proof),因为D 是对角线,而Q 是正交线,
= transp(inv(D*inv(Q)))
= transp(Q*inv(D))).
Q*inv(D) 很容易找到:因为在Q*D 中,每一列都是Q(这是一个单位向量)的一列乘以D(这是一个标量)的一个条目,这就足够了将每一列除以其范数的平方。这就是函数的前三行所做的。
完全写成线性代数形式:
inv ([ Q*D b ]) = [transp(Q*inv(D)) -transp(Q*inv(D))*b]
([ 0 1 ]) [ 0 1 ]
【讨论】:
inverse() 方法的特征变换?