C++库Eigen学习4:几何

前情提要

C++库Eigen学习3:稀疏线性代数

空间变换

Eigen的几何模块包含两类几何变换

  • 抽象变换:旋转、平移、缩放,这些变换不以矩阵方式存储,但是可以与矩阵混用,且可以转换为矩阵
  • 投影或仿射变换矩阵:以矩阵方式存储

齐次变换的构造

Transform t(AngleAxis(angle,axis));
// 或
Transform t;
t = AngleAxis(angle,axis);
// 但不能
Transform t = AngleAxis(angle,axis);

变换类型

二维旋转

Rotation2D<float> rot2(angle_in_radian);

三维旋转(轴角)

AngleAxis<float> aa(angle_in_radian, Vector3f(ax,ay,az));

三维旋转(四元数)

Quaternion<float> q;  q = AngleAxis<float>(angle_in_radian, axis);

N维缩放

Scaling(sx, sy)
Scaling(sx, sy, sz)
Scaling(s)
Scaling(vecN)

N维平移

Translation<float,2>(tx, ty)
Translation<float,3>(tx, ty, tz)
Translation<float,N>(s)
Translation<float,N>(vecN)

N维仿射变换

Transform<float,N,Affine> t = concatenation_of_any_transformations;
Transform<float,3,Affine> t = Translation3f(p) * AngleAxisf(a,axis) * Scaling(s);

N维线性变换

Matrix<float,N> t = concatenation_of_rotations_and_scalings;
Matrix<float,2> t = Rotation2Df(a) * Scaling(s);
Matrix<float,3> t = AngleAxisf(a,axis) * Scaling(s);

关于旋转,变换一个矩阵应该用旋转矩阵,变换单个矢量的话应该用四元数,二维旋转和轴角常用于构建其他旋转变量

关于平移和缩放,用于简化变换变量的初始化过程

类型转换的例子如下

Rotation2Df r;  r  = Matrix2f(..);       // assumes a pure rotation matrix
AngleAxisf aa;  aa = Quaternionf(..);
AngleAxisf aa;  aa = Matrix3f(..);       // assumes a pure rotation matrix
Matrix2f m;     m  = Rotation2Df(..);
Matrix3f m;     m  = Quaternionf(..);       Matrix3f m;   m = Scaling(..);
Affine3f m;     m  = AngleAxis3f(..);       Affine3f m;   m = Scaling(..);
Affine3f m;     m  = Translation3f(..);     Affine3f m;   m = Matrix3f(..);

变换类型的常用API

连乘

gen1 * gen2;

变换乘向量

vec2 = gen1 * vec1;

变换的逆

gen2 = gen1.inverse();

球坐标插值

rot3 = rot1.slerp(alpha,rot2);

仿射变换

对点或矢量进行转换

对点进行变换

VectorNf p1, p2;
p2 = t * p1;

对矢量进行变换

VectorNf vec1, vec2;
vec2 = t.linear() * vec1;

对矢量进行一般变换

VectorNf n1, n2;
MatrixNf normalMatrix = t.linear().inverse().transpose();
n2 = (normalMatrix * n1).normalized();

对矢量进行纯旋转变换

n2 = t.linear() * n1;

访问内部数据

读写变换矩阵

t.matrix() = matN1xN1;    // N1 means N+1
matN1xN1 = t.matrix();

访问元素

t(i,j) = scalar;   <=>   t.matrix()(i,j) = scalar;
scalar = t(i,j);   <=>   scalar = t.matrix()(i,j);

平移部分

t.translation() = vecN;
vecN = t.translation();

线性部分

t.linear() = matNxN;
matNxN = t.linear();

旋转部分

matNxN = t.rotation();

变换的创建

平移

t.translate(Vector_(tx,ty,..));
t.pretranslate(Vector_(tx,ty,..));
t *= Translation_(tx,ty,..);
t = Translation_(tx,ty,..) * t;

旋转

t.rotate(any_rotation);
t.prerotate(any_rotation);
t *= any_rotation;
t = any_rotation * t;

缩放

t.scale(Vector_(sx,sy,..));
t.scale(s);
t.prescale(Vector_(sx,sy,..));
t.prescale(s);
t *= Scaling(sx,sy,..);
t *= Scaling(s);
t = Scaling(sx,sy,..) * t;
t = Scaling(s) * t;

剪切(仅限二维)

t.shear(sx,sy);
t.preshear(sx,sy);

连续变换

t.pretranslate(..).rotate(..).translate(..).scale(..);
t = Translation_(..) * t * RotationType(..) * Translation_(..) * Scaling(..);

欧拉角

Matrix3f m;
m = AngleAxisf(angle1, Vector3f::UnitZ())
    * AngleAxisf(angle2, Vector3f::UnitY())
    * AngleAxisf(angle3, Vector3f::UnitZ());

1人评论了“C++库Eigen学习4:几何”

  1. Pingback: C++库Eigen学习5:其他 - Fivyex's Blog

发表评论

您的电子邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据