前情提要
空间变换
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());
Pingback: C++库Eigen学习5:其他 - Fivyex's Blog