如何找到一个基底变换的变换矩阵

how to find the transformation matrix of a change of basis with Eigen

本文关键字:变换 一个 何找      更新时间:2023-10-16

我正在移植一个程序到Eigen。

现在我必须重写一个方法,将3D变换矩阵从一个由原点和两个轴定义的坐标系a返回到另一个仍然由原点和两个轴定义的坐标系。

我想知道在本征中是否有一种方法可以找到这个矩阵。我浏览了参考指南,但没有找到任何有用的方法…


更多细节:

我移植到Eigen的方法接受6个点(向量)(fr0, fr1, fr2, to0, to1, to2)。"fr0"为CS1(坐标系1)的原点,"fr1"为定义CS1的一个轴的点,"fr2"为定义CS1的第二个轴的点;"to0"是CS2的原点,以此类推……

好的,我找到了解决方案,我把它贴在这里供参考。我希望它也能对别人有用。

实际上是盖尔的回答引发了正确的解决方案,所以非常感谢他,为他+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-between-two-3d-cartesian-coordinate-systems

无需特殊函数,只需使用逗号初始化器:

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

这假设两个轴X和Y是酉正交的。0为原点

您还可以查看几何模块以获取更高级的空间转换类和函数,如Transform<>类。下面是使用Affine3f类型定义而不是原始矩阵的相同示例:

Affine3f M;
M.linear() << X, Y, X.cross(Y);
M.translation(O);