将变换应用于包含特征向量的矩阵的更短方法?

问题描述 投票:0回答:3

有没有更短的方法来应用变换?

auto vecs = Matrix<float, Dynamic, 3>(); //vector in each row.
Affine3f transform = ...; // some Affine3 transform

for (int r = 0; r < vecs.rows(); r++) {
    Vector3f v = vecs.row(r);
    v = transform * v;
    vecs.row(r) = v;
}
c++ eigen
3个回答
2
投票

您可以直接将

Affine
变换应用于存储在矩阵中的一组列向量。由于向量是按行排列的,因此需要转置矩阵。您的 for 循环因此减少为:

vecs.transpose() = transform * vecs.transpose();

1
投票

@JE42 是对的,对于 Eigen 几乎不需要 for 循环。 当然可以简化。但是,请注意,在您的情况下,

transform * v
不是简单的乘法,而是相当于
transform.linear() * v + transform.translation()
的仿射变换。 https://eigen.tuxfamily.org/dox-devel/group__TutorialGeometry.html

此外,您的“点”是行,因此需要额外的转置。

总之,(无需实际编译或测试)您的计算应该相当于

vecs.transpose() = (transform.linear() * vecs.transpose()).array() + transform.translation();

0
投票

以下代码对我有用。它取自这个教程。 上面提供的解决方案对我不起作用。不过我没有像OP那样的转置矩阵。

这是代码:

#include <Eigen/Core>
#include <Eigen/Geometry>
#include <iostream>


using namespace std;
using namespace Eigen;

int main() {
    float arrVertices[] = { -1.0 , -1.0 , -1.0 ,
    1.0 , -1.0 , -1.0 ,
    1.0 , 1.0 , -1.0 ,
    -1.0 , 1.0 , -1.0 ,
    -1.0 , -1.0 , 1.0 ,
    1.0 , -1.0 , 1.0 ,
    1.0 , 1.0 , 1.0 ,
    -1.0 , 1.0 , 1.0 };

    MatrixXf mVertices = Map < Matrix <float, 3, 8 > >(arrVertices);
    Transform <float, 3, Affine > t = Transform <float, 3, Affine >::Identity();
    t.scale(0.8f);

    t.rotate(AngleAxisf(0.25f * EIGEN_PI, Vector3f::UnitX()));

    t.translate(Vector3f(1.5, 10.2, -5.1));
    cout << t * mVertices.colwise().homogeneous() << endl;
}

注意我使用的是 EIGEN_PI 而不是原始文档中使用的 M_PI。

引用文档中的描述也应该有助于理解代码的最后一行:“了解如何将顶点存储为矩阵的列,使我们能够通过单个矩阵乘法来转换所有顶点。但是,要做到这一点,内部维度的变换矩阵,并且顶点矩阵 t 使用齐次坐标,因此 3 维变换表示为 4x4 矩阵,为了匹配这些维度,我们对顶点矩阵的每一列进行均质化。 通过使用 colwise() 方法。”

© www.soinside.com 2019 - 2024. All rights reserved.