2

プログラムをEigenに移植しています。

ここで、原点と2つの軸によって定義される1つの座標系Aから、原点と2つの軸によって定義される2番目の座標系に3D変換行列を返すメソッドを書き直す必要があります。

その行列を見つける方法がEigenにあるかどうか疑問に思いました。リファレンスガイドを閲覧しましたが、まだ便利な方法が見つかりませんでした...


詳細:

私がEigenに移植している方法は、6ポイント(ベクトル)(fr0、fr1、fr2、to0、to1、to2)を受け入れます。「fr0」はCS1(座標系1)の原点、「fr1」はCS1の軸を定義する点、「fr2」はCS1の2番目の軸を定義する点です。「to0」はCS2の原点であり、以下同様です。

4

2 に答える 2

6

わかりました、解決策を見つけたので、参考のためにここに投稿します。他の人にも役立つことを願っています。

実際、ggaelの答えは正しい解決策を引き起こしました。彼に感謝し、+1してください。


#include <Eigen/Geometry>

typedef Eigen::Affine3d Transformation;
typedef Eigen::Vector3d   Point;
typedef Eigen::Vector3d  Vector;
typedef Eigen::Translation<double,3>  Translation;

Transformation findTransformBetween2CS(Point fr0,Point fr1,Point fr2,Point to0,Point to1,Point to2) {

  Transformation T, T2, T3 = Transformation::Identity();
  Vector3d x1,y1,z1, x2,y2,z2;

  // Axes of the coordinate system "fr"
  x1 = (fr1 - fr0).normalized(); // the versor (unitary vector) of the (fr1-fr0) axis vector
  y1 = (fr2 - fr0).normalized();

  // Axes of the coordinate system "to"
  x2 = (to1 - to0).normalized();
  y2 = (to2 - to0).normalized();

  // transform from CS1 to CS2 
  // Note: if fr0==(0,0,0) --> CS1==CS2 --> T2=Identity
  T2.linear() << x1, y1, x1.cross(y1); 

  // transform from CS1 to CS3
  T3.linear() << x2, y2, x2.cross(y2); 

  // T = transform to CS2 to CS3
  // Note: if CS1==CS2 --> T = T3
  T.linear() = T3.linear() * T2.linear().inverse(); 


  T.translation() = t0;

  return T;

}

インスピレーションは、次の投稿からも得られました。

https://gamedev.stackexchange.com/questions/26084/transform-b​​etween-two-3d-cartesian-coordinate-systems

于 2013-03-07T17:09:10.967 に答える
4

そのための特別な関数は必要ありません。カンマ初期化子を使用するだけです。

Matrix4f M;
M << X, Y, X.cross(Y), O,
     0, 0, 0,          1;

これは、2 つの軸 X と Y がユニタリで直交していると仮定しています。Oが由来です。

Transform<> クラスのような、より高度な空間変換クラスと関数については、ジオメトリモジュールを参照することもできます。生の行列の代わりに Affine3f typedef を使用した同じ例を次に示します。

Affine3f M;
M.linear() << X, Y, X.cross(Y);
M.translation(O);
于 2013-03-06T18:01:56.790 に答える