当前位置: 首页 > news >正文

【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;

}

相关文章:

  • 【GAMES-104现代游戏引擎】4、引擎渲染基础(渲染基础数据、全局光照、PBR、阴影)
  • Linux中断概述
  • 【统计学习|书籍阅读】第一章 统计学习方法概论 p1-p24
  • 操作系统——计算机系统概述补充
  • pytorch 实现一个最简单的 GAN:用mnist数据集生成新图像
  • 七雄争霸武将技能搭配
  • 利用Python进行数据分析-Numpy入门基础知识
  • QML的Popup遇到的坑
  • 解数独 视频讲解 c++
  • kubernetes 网络
  • 运维流程化和标准化
  • LeetCode104. 二叉树的最大深度和N叉树的最大深度
  • Games104 引擎工具链笔记
  • 如何梳理当天的事情?
  • 【历年NeurIPS论文下载】一文了解NeurIPS国际顶会(含NeurIPS2022)
  • ➹使用webpack配置多页面应用(MPA)
  • C学习-枚举(九)
  • hadoop入门学习教程--DKHadoop完整安装步骤
  • Java知识点总结(JDBC-连接步骤及CRUD)
  • Mac 鼠须管 Rime 输入法 安装五笔输入法 教程
  • Nacos系列:Nacos的Java SDK使用
  • Netty 4.1 源代码学习:线程模型
  • PHP的类修饰符与访问修饰符
  • Webpack 4x 之路 ( 四 )
  • 创建一个Struts2项目maven 方式
  • 从PHP迁移至Golang - 基础篇
  • 类orAPI - 收藏集 - 掘金
  • 面试题:给你个id,去拿到name,多叉树遍历
  • 算法之不定期更新(一)(2018-04-12)
  • Salesforce和SAP Netweaver里数据库表的元数据设计
  • 从如何停掉 Promise 链说起
  • ​io --- 处理流的核心工具​
  • !!【OpenCV学习】计算两幅图像的重叠区域
  • # C++之functional库用法整理
  • # MySQL server 层和存储引擎层是怎么交互数据的?
  • #我与Java虚拟机的故事#连载06:收获颇多的经典之作
  • (2)关于RabbitMq 的 Topic Exchange 主题交换机
  • (C#)获取字符编码的类
  • (Mirage系列之二)VMware Horizon Mirage的经典用户用例及真实案例分析
  • (Python第六天)文件处理
  • (利用IDEA+Maven)定制属于自己的jar包
  • (亲测成功)在centos7.5上安装kvm,通过VNC远程连接并创建多台ubuntu虚拟机(ubuntu server版本)...
  • (一) storm的集群安装与配置
  • (原)记一次CentOS7 磁盘空间大小异常的解决过程
  • (转)jdk与jre的区别
  • (转)原始图像数据和PDF中的图像数据
  • ***php进行支付宝开发中return_url和notify_url的区别分析
  • ./configure、make、make install 命令
  • .Mobi域名介绍
  • .NET CORE 3.1 集成JWT鉴权和授权2
  • .NET 中 GetProcess 相关方法的性能
  • /proc/vmstat 详解
  • [ CTF ] WriteUp- 2022年第三届“网鼎杯”网络安全大赛(朱雀组)
  • [ 蓝桥杯Web真题 ]-布局切换
  • [2023年]-hadoop面试真题(一)