C++ Eigen 将旋转和平移合并为一个矩阵

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25504397/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 11:19:59  来源:igfitidea点击:

Eigen combine rotation and translation into one matrix

c++matrixeigen

提问by DaedalusAlpha

I have a rotation matrix rot(Eigen::Matrix3d) and a translation vector transl(Eigen::Vector3d) and I want them both together in a 4x4 transformation matrix. I just for the life of me can't figure out how to do this in Eigen. I think Affine can be used somehow but I don't understand how it works.

我有一个旋转矩阵rot(Eigen::Matrix3d) 和一个平移向量transl(Eigen::Vector3d),我希望它们都在一个 4x4 变换矩阵中。我只是为了我的生活无法弄清楚如何在 Eigen 中做到这一点。我认为 Affine 可以以某种方式使用,但我不明白它是如何工作的。

Essentially I want a combination of How translation a matrix(4x4) in Eigen?and Multiplying Transform and Matrix types in Eigen

本质上,我想要组合如何在 Eigen 中转换矩阵(4x4)?乘以 Eigen 中的变换和矩阵类型

My code (that doesn't compile as I don't understand how Affine works) looks like this:

我的代码(无法编译,因为我不明白 Affine 是如何工作的)如下所示:

Eigen::Affine3d r(rot);
Eigen::Affine3d t(transl);
Eigen::Matrix4d m = t.matrix();
m *= r.matrix();

采纳答案by Timothy Murphy

Another method is to do the following:

另一种方法是执行以下操作:

Eigen::Matrix3d R;
// Find your Rotation Matrix
Eigen::Vector3d T;
// Find your translation Vector
Eigen::Matrix4d Trans; // Your Transformation Matrix
Trans.setIdentity();   // Set to Identity to make bottom row of Matrix 0,0,0,1
Trans.block<3,3>(0,0) = R;
Trans.block<3,1>(0,3) = T;

This method literally copies the Rotation matrix into the first 3 rows and columns and the translation vector to the 4th column. Then sets the bottom right matrix entry to 1. You final matrix will look like:

此方法逐字地将旋转矩阵复制到前 3 行和列,并将平移向量复制到第 4 列。然后将右下角矩阵条目设置为 1。最终矩阵将如下所示:

R R R T
R R R T
R R R T
0 0 0 1

where R are the corresponding values from the rotation matrix and T the values from the Translation vector.

其中 R 是来自旋转矩阵的相应值,T 是来自平移向量的值。

回答by Blaz Bratanic

You didn't post the compilation errors, nor what are rotand transl. Below is a working sample showing, how you can create a 4x4 transformation matrix.

您没有发布编译错误,也没有发布rottransl. 下面是一个工作示例,展示了如何创建 4x4 转换矩阵。

#include <Eigen/Geometry>

Eigen::Affine3d create_rotation_matrix(double ax, double ay, double az) {
  Eigen::Affine3d rx =
      Eigen::Affine3d(Eigen::AngleAxisd(ax, Eigen::Vector3d(1, 0, 0)));
  Eigen::Affine3d ry =
      Eigen::Affine3d(Eigen::AngleAxisd(ay, Eigen::Vector3d(0, 1, 0)));
  Eigen::Affine3d rz =
      Eigen::Affine3d(Eigen::AngleAxisd(az, Eigen::Vector3d(0, 0, 1)));
  return rz * ry * rx;
}

int main() {
  Eigen::Affine3d r = create_rotation_matrix(1.0, 1.0, 1.0);
  Eigen::Affine3d t(Eigen::Translation3d(Eigen::Vector3d(1,1,2)));

  Eigen::Matrix4d m = (t * r).matrix(); // Option 1

  Eigen::Matrix4d m = t.matrix(); // Option 2
  m *= r.matrix();
  return 0;
}

回答by Yantao Xie

Another way is to use the Eigen::Transform.

另一种方法是使用Eigen::Transform

Let's take a example such as to implemente this affine transform ,

让我们举一个例子来实现这个仿射变换

#include <Eigen/Dense>
#include <Eigen/Geometry>
using namespace Eigen;

Matrix4f create_affine_matrix(float a, float b, float c, Vector3f trans)
{
    Transform<float, 3, Eigen::Affine> t;
    t = Translation<float, 3>(trans);
    t.rotate(AngleAxis<float>(a, Vector3f::UnitX()));
    t.rotate(AngleAxis<float>(b, Vector3f::UnitY()));
    t.rotate(AngleAxis<float>(c, Vector3f::UnitZ()));
    return t.matrix();
}

You can also implemented as the following

你也可以实现如下

Matrix4f create_affine_matrix(float a, float b, float c, Vector3f trans)
{
    Transform<float, 3, Eigen::Affine> t;
    t = AngleAxis<float>(c, Vector3f::UnitZ());
    t.prerotate(AngleAxis<float>(b, Vector3f::UnitY()));
    t.prerotate(AngleAxis<float>(a, Vector3f::UnitX()));
    t.pretranslate(trans);
    return t.matrix();
}

The difference between the first implementation and the second is like the difference between Fix Angleand Euler Angle, you can refer to this video.

第一个实现和第二个实现的区别就像Fix AngleEuler Angle的区别,可以参考这个视频