web-dev-qa-db-ja.com

Eigenは、回転と平行移動を1つの行列に結合します

回転行列rot(Eigen :: Matrix3d)と平行移動ベクトルtransl(Eigen :: Vector3d)があり、両方を4x4変換行列にまとめたいと考えています。私は一生の間、Eigenでこれを行う方法を理解できません。アフィンはなんとか使えると思いますが、どういう仕組みなのかわかりません。

基本的に、 Eigenで行列(4x4)をどのように変換しますか?Eigenで変換型と行列型を乗算する の組み合わせが必要です。

私のコード(Affineがどのように機能するかを理解していないため、コンパイルされません)は次のようになります。

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

別の方法は、次のことを行うことです。

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;

このメソッドは、文字通り、回転行列を最初の3行と列にコピーし、平行移動ベクトルを4番目の列にコピーします。次に、右下の行列エントリを1に設定します。最終的な行列は次のようになります。

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

ここで、Rは回転行列からの対応する値であり、Tは平行移動ベクトルからの値です。

5
Timothy Murphy

コンパイルエラーも、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;
}
9
Blaz Bratanic

別の方法は、 Eigen :: 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();
}

次のように実装することもできます

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();
}

最初の実装と2番目の実装の違いは、Fix AngleEuler Angleの違いのようなもので、-を参照できます。 このビデオ

2
Yantao Xie

私にとって最後の答えはコンパイルされていません:エラーC2659: '=':左オペランドとして機能します

    Eigen::Vector3f x       
    Eigen::Matrix3f rot;
    Eigen::Matrix4f Trans;
    Trans.setIdentity();
    Trans.block<3, 3> = rot;
    Trans.rightCols<1> = x;
0
Xref_failed