【Eigen】Chapter4 几何模块 Geometry

Chapter4 Geometry

(1)空间变换

​ 在本节中,将介绍几何模块提供的许多可能性,以处理2D和3D旋转以及射影或仿射变换。

​ Eigen的Geometry模块提供了两种不同的几何变换:

​ 1 抽象的变换,例如旋转(轴角或四元数表示),平移,缩放。这些转换未表示为矩阵,但是仍然可以将它们与表达式中的矩阵和向量混合,并根据需要将它们转换为矩阵。

​ 2 射影或仿射变换矩阵:请参见Transform类。这些确实是矩阵。注意, 如果要使用OpenGL 4x4矩阵,则需要Affine3f和Affine3d。

​ 可以从抽象转换构造一个Transform:Transform t(AngleAxis(angle,axis));

​ 或像这样:

Transform t;
t = AngleAxis(angle,axis);

​ 但是注意,不幸的是,由于C ++的工作方式,不能这样做:Transform t = AngleAxis(angle,axis);

​ 说明:在C ++语言中,这将要求Transform具有一个来自AngleAxis的非显式转换构造函数,但是我们真的不想在此允许隐式转换。

​ 1)变换的类型

变换类型典型的初始化代码
2D旋转Rotation2D<float> rot2(angle_in_radian);
3D旋转的轴角方法AngleAxis<float> aa(angle_in_radian, Vector3f(ax,ay,az));
3D旋转的四元数方法Quaternion<float> q; q = AngleAxis<float>(angle_in_radian, axis);
N维缩放Scaling(sx, sy, sz)
N维平移Translation<float,3>(tx, ty, tz)
N维仿射 Transform<float,3,Affine> t = Translation3f(p) * [AngleAxisf](a,axis) * [Scaling]
N维线性变换Matrix<float,3> t = AngleAxisf(a,axis) * Scaling(s);

​ 关于旋转的注意事项

​ 要变换多个矢量,首选旋转矩阵,而对于其他用法,四元数是紧凑,快速和稳定的首选表示形式。最后,Rotation2D和AngleAxis主要是创建其他旋转对象的便捷类型。

关于平移和缩放的注意事项

​ 像AngleAxis一样,这些类旨在简化线性(Matrix)和仿射(Transform)变换的创建/初始化。但是,与使用效率低下的AngleAxis不同,编写任何类型的转换作为输入的通用高效算法可能仍然很有趣。

​ 上述任何转换类型都可以转换为相同性质的任何其他类型,或者转换为更通用的类型。以下是一些其他示例:

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

​ 2)仿射变换

​ 本部分介绍仿射变换,概念上,仿射变换是一个非奇异线性变换 linear()与一个平移变换t的复合,可能是因为x’ = linear()*x + t ;所以linear()是线性部分

将变换应用于点VectorNf p1, p2; p2 = t * p1;
将变换应用于向量VectorNf vec1, vec2;vec2 = t.linear() * vec1;
应用一个更一般的变换作用在normal vectorVectorNf n1, n2;MatrixNf normalMatrix = t.linear().inverse().transpose();n2 = (normalMatrix * n1).normalized();
将纯旋转变换作用在一个 normal vectorn2 = t.linear() * n1;
OpenGL compatibility 3DglLoadMatrixf(t.data());
OpenGL compatibility 2DAffine3f aux([Affine3f::Identity]());aux.linear().topLeftCorner<2,2>() = t.linear();aux.translation().start<2>() = t.translation();glLoadMatrixf(aux.data());

​ 3)欧拉角

Matrix3f m;
m = AngleAxisf(angle1, Vector3f::UnitZ())
    * AngleAxisf(angle2, Vector3f::UnitY())
    * AngleAxisf(angle3, Vector3f::UnitZ());
(2)十四讲中的例子
#include <iostream>
#include <cmath>
#include <Eigen/Core>
#include <Eigen/Geometry>

int main()
{
    //------------1 声明旋转矩阵与向量并初始化-----------
    Eigen::Matrix3d rotation_matrix = Eigen::Matrix3d::Identity();
    std::cout << "rotation_matrix = \n" << rotation_matrix << std::endl;
    Eigen::AngleAxisd rotation_vector(M_PI / 4, Eigen::Vector3d(0, 0, 1));
    std::cout.precision(3);     //输出三位有效数字
    std::cout << "rotation_vector_matrix = \n" << rotation_vector.matrix() << std::endl;
    rotation_matrix = rotation_vector.toRotationMatrix();

    //-------------2 对v进行操作-------------
    Eigen::Vector3d v(1, 0, 0);
    Eigen::Vector3d v_rotated = rotation_vector * v;
    std::cout << "(1, 0, 0) after rotation (by matrix) = \n" << v_rotated.transpose() << std::endl;
    v_rotated = rotation_matrix * v;
    std::cout << "(1, 0, 0) after rotation (by matrix) = \n" << v_rotated.transpose() << std::endl;

    //-------------3 欧拉角------------------
    Eigen::Vector3d euler_angle = rotation_matrix.eulerAngles(2, 1, 0);
    std::cout << "yaw pitch roll = " << euler_angle.transpose() << std::endl;

    //-------------4 欧氏变换----------------
    Eigen::Isometry3d T = Eigen::Isometry3d::Identity();
    T.rotate(rotation_vector);
    T.pretranslate(Eigen::Vector3d(1, 3, 4));
    std::cout << "Transform matrix = \n" << T.matrix() << std::endl;
    //-------------5 坐标变换----------------
    Eigen::Vector3d v_transformed = T * v;
    std::cout << "v transformed = " << v_transformed.transpose() << std::endl;
    //-------------6 四元数------------------
    Eigen::Quaterniond q = Eigen::Quaterniond(rotation_vector);
    std::cout << "quaterniond from rotation vector = " << q.coeffs().transpose() << std::endl;
    q = Eigen::Quaterniond(rotation_matrix);
    std::cout << "quaterniond from rotation matrix = " << q.coeffs().transpose() << std::endl;

    v_rotated = q * v;
    std::cout << "(1, 0, 0) after rotation  = \n" << v_rotated.transpose() << std::endl;
    std::cout << "should be equal to " << (q * Eigen::Quaterniond(0, 1, 0, 0) * q.inverse()).coeffs().transpose() << std::endl;

}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值