我有一堆等轴测图[R | t]变换矩阵,即它们是3D刚性变换。目前我将它们存储为Eigen仿射transformations,以紧凑形式表示,例如Eigen::AffineCompact3d
,它不存储[0 0 0 1]的冗余最后一行。
我也知道有一个Eigen::Isometry3d
,我猜是Transform<double, 3, AffineCompact, Isometry>
的typedef。
我在Isometry之后,逆转换比一般仿射逆更便宜(转置)。当我使用inverse()作为affine_mat.inverse(Eigen::Isometry);
但是我希望在没有每次手动传递提示的情况下获得等距逆行为。换句话说,我想知道,复制Eigen::IsometryCompact3d
行为的最佳方式是什么,这在Eigen API中是出乎意料的缺失?
答案 0 :(得分:1)
表示我目前正在使用twists的等轴测图。该参数化可以用6元素向量来描述。
要来回转换为标准均匀矩阵公式,您需要基于log()和exp()的几个函数(因此转换将是一个缓慢的操作)。
如果您在两个配方之间来回(或者您很少这样做)或者想要利用曲折的属性(例如在数值优化中)没有性能限制,那么这个解决方案是有利的
答案 1 :(得分:0)
我知道这个问题有点老了,您现在可能已经找到了解决方案。但这可能会让其他有此问题的人感兴趣。
首先,你写道:
<块引用>我追求 Isometry 因为,逆变换比一般的仿射逆更便宜(转置)>。
只是为了澄清:您不能只是转置以获得相反的结果:
/*
| R t|
T = |0 0 0 1|
| 0|
T' =| R' 0| not an affine transformation!
| 0|
| t 1|
// inverse of Isometric matrix without actual matrix inversion
T^(-1) = | R' -R'*t|
|0 0 0 1 |
*/
真遗憾,你可以定义自己的函数:
void invertAffineCompact3d(Eigen::AffineCompact3d &m){
m.linear() = m.linear().transpose();
m.translation() = -m.linear()*m.translation();
}
并称之为:
Eigen::AffineCompact3d T1 = ...
invertAffineCompact3d(T1);
或者,如果您想要一种适用于所有类型的解决方案:
template<size_t m, size_t n, size_t x, size_t y, typename Derived>
Eigen::Block<Derived, m, n>
getSubmatrix(MatrixBase<Derived>& data)
{
return Eigen::Block<Derived, m, n>(data.derived(), x, y);
}
template<typename Derived>
void invertAffine3d(Eigen::MatrixBase<Derived> &m){
getSubmatrix<3,3,0,0>(m).transposeInPlace();
getSubmatrix<3,1,0,3>(m) = -getSubmatrix<3,3,0,0>(m)*getSubmatrix<3,1,0,3>(m);
}
并称之为:
Eigen::AffineCompact3d T2 = ...
invertAffine3d(T2.matrix());
Eigen::Affine3f T3 = ...
invertAffine3d(T3.matrix());
Eigen::Isometry3d T4 = ...
invertAffine3d(T4.matrix());
如果您真的很喜欢,可以使用 EIGEN_MATRIXBASE_PLUGIN
扩展 MatrixBase