概述

在3D图形学中,几何变换大致分为三种:平移变换(Translation)、缩放变换(Scaling)、旋转变换(Rotation),而其中又以旋转变换(Rotation)最为复杂,通常旋转变换(Rotation)是有三种常用方式:矩阵旋转(Rotate Matrix)、欧拉角(Euler Angles)、四元数(Quaternion),下面我们会对三种旋转方法及其特点优缺点进行介绍。

矩阵旋转

矩阵是3D图形学中的重点,通常的数学表达方式如下图所示:

按上图所示,矩阵可以看作是向量的数组,而向量又是标量的数组,简单来说矩阵就是对向量进行坐标变换。

矩阵可以有任意多行、任意多列,一行的矩阵即行向量,一列的矩阵即列向量,一个列数和行数相等的矩阵我们称之为方阵,3D数学中矩阵几乎以方阵形式出现。

欧拉角

什么是欧拉角,作为三维空间中的旋转描述方式的一种,欧拉角采用旋转坐标系的方法让物体的旋转可以始终按照自身当前的坐标系来作为基准将连贯的旋转运动有序的分割开来,使其更加有助于人们更直观的理解。

在维基百科中对欧拉角的解释中有个动图非常清晰的展示了欧拉角完成旋转过程:

具体来说可理解为下图所示:

在图片上可以看到分别有两组坐标:xyz代表的全局坐标,XYZ代表的局部坐标,当物体运动时,全局坐标始终保持不变,而局部坐标随着物体一起运动。

我们把旋转分解一下就会得到以下步骤:

  • 物体绕全局的z轴旋转α角

  • 绕局部X轴(图中的N轴)旋转β角

  • 最后绕自己的Z轴旋转γ角

欧拉角可分为两种情况:

  • 静态:即绕世界坐标系三个轴的旋转,由于物体旋转过程中坐标轴保持静止,所以称为静态。

  • 动态:即绕物体坐标系三个轴的旋转,由于物体旋转过程中坐标轴随着物体做相同的转动,所以称为动态。

四元数

四元数作为图形学来解决旋转问题其实是不如欧拉角表示方式来的直接,欧拉角只用3个数字(偏航/yaw,俯仰/pitch,横滚/roll)即可表达,而四元数是需要四个数的,但是用欧拉角来处理旋转是有致命或不可回避的问题:万向锁。于是我们就可以通过将欧拉角转换成四元数来解决规避这个问题。

通俗的说,一个四元数(Quaternion)描述了一个喜欢转轴和一个旋转角度,当用一个四元数乘以一个向量时,实际上就是让该向量围绕着这个四元数所描述的旋转轴,转动这个四元数所描述的角度而得到的向量,如图:

四元数只需要一个规格化的4维向量表示,所以其在插值计算尤其是线性插值算法中处理平滑插值时非常简单易处理的,下图展示了简单的Bezier曲线例子:

差异

三种方法都有自己的优缺点,下面我们举个例子来说明一下,当前做相同绕Y轴做角度30度的旋转时,三种表示方式如下:

矩阵:

欧拉角:

Heading = 30

Pitch = 0

Bank = 0

四元数:

[0.9659 (0, 0.2588 0)]

可以看出如果使用矩阵来表达就需要9个数做存储,而且对应的计算相对复杂。欧拉角中heading代表Y轴旋转30度,Pitch、Bank不旋转为0,这种表示方式最简单直接,容易理解,只用3个数就能表达出来。而四元数,使用了4个数来表达,比矩阵简单,相对欧拉角只是复杂了一些。

三种方法各有各的优缺点,下面的表格为我们展示了各自的问题

功能/性质

矩阵

欧拉角

四元数

在坐标系间转换

不能

不能

连续或增量旋转

能,但是转换速度慢

不能

能,转换速度快

插值

基本不能

能,但可能遇到万向锁问题

能,且能平滑插值

易用程度

存储

9个数

3个数

4个数

对给定方位表达方式是否唯一

不是,对同一方位有无数种表达

不是,对同一方位有两种表达

可能导致非法

矩阵蠕变

任意三个数都能构成合法的欧拉角

可能会出现误差积累,从而产生非法的四元数

基于以上的介绍我们可以看出,3D图形学中的旋转是一个最复杂的难题,每个方法都有自己的优点和缺点,没有一种方法是可以保证处理所有问题的,要根据实际情况来选择不同的旋转方法,同时又要根据不同的情况在三种转换方法间做换算,不能只单一使用一种旋转方式来处理。

三维坐标系带偏航角俯仰角_浅谈三维旋转的三种方法及差异相关推荐

  1. oracle hash join outer,CSS_浅谈Oracle中的三种Join方法,基本概念 Nested loop join: Outer - phpStudy...

    浅谈Oracle中的三种Join方法 基本概念 Nested loop join: Outer table中的每一行与inner table中的相应记录join,类似一个嵌套的循环. Sort mer ...

  2. java虚拟机类加载机制浅谈_浅谈Java虚拟机(三)之类加载机制

    在<浅谈Java虚拟机>这篇文章中,我们提到了JVM从操作系统方面来说,可以将其看做是一个进程,分别有类加载器子系统,执行引擎子系统和垃圾收集子系统.这一篇文章就简单的来谈一下类加载器子系 ...

  3. workbench设置单元坐标系_浅谈Ansys中的几种坐标系

    这篇简短的文章是我多年前在仿真论坛任ansys版主时发表的,时隔多年,同事正好咨询关于ansys坐标系的知识,就将此贴翻出来解他困惑,自己也重温下当年的技术贴,发给大家,希望对学习ansys的初学者有 ...

  4. 怎么向easyui grid里面插入空数据_浅谈数据结算(三)

    1. 第二章:栈和队列 通过下面的思维导图来依次分享「栈和队列」里面重要知识点. 2. 第一节:栈 1. 栈的定义: 栈(stack):只允许在一端进行插入或删除操作的线性表. 栈顶(Top):线性表 ...

  5. 计算机组成原理哈工大期末_浅谈计算机组成原理(三)

    1. 第二章:存储系统 通过下面的思维导图来依次分享「存储系统」里面重要知识点. 2. 第一节:存储器的结构 1. 主存储器:简称主存,又称内存储器(内存),用来存放计算机运行期间所需的大量程序和数据 ...

  6. arm中断保护和恢复_浅谈ARM处理器的七种异常处理

    昨天的文章,我们谈了ARM处理器的七种运行模式,分别是:用户模式User(usr),系统模式System(sys),快速中断模式(fiq),管理模式Supervisor(svc),外部中断模式(irq ...

  7. 自定义http报头_浅谈http协议(三):HTTP 报文及其结构

    很多开发者天天跟http打交道,却不知道http报文长什么样子,结构是怎么样的,是时候普及一下了.用于 HTTP 协议交互的信息被称为 HTTP 报文,请求端(客户端)的 HTTP 报文叫做请求报文: ...

  8. java四种内部类区别_浅谈Java中的四种内部类

    如果你看过一些JDK和框架源码的话,就经常会发现一般在类的定义中,都会再定义一些其他的类,这些类也同样会被编译成字节码文件,这样的类就被叫做 内部类 ,按照一般的分法,大致可以分为以下四类: 成员内部 ...

  9. 浅谈整数拆分的四种方法

    DP 对于拆分为 < = n <=\sqrt n <=n ​部分,直接背包,对于 > n >\sqrt n >n ​的部分由于最多只有 n \sqrt n n ​个 ...

最新文章

  1. 微信小程序 自定义导航栏,只保留右上角胶囊按钮
  2. linux设置网卡队列,CentOS 修改网卡队列长度
  3. Lintcode99 Reorder List solution 题解
  4. opencv中的一些陷阱 坑死我了~~~~(_)~~~~
  5. 与微软.NET创始人Scott Guthrie面对面,“红衣教主”亲身传授推动成功转型的洪荒之力
  6. JS中ptototype和__proto__的关系
  7. python以20字符宽居中输出,Python 字符串内置方法(一)
  8. SQL Server数据库partition by 与ROW_NUMBER()函数使用详解[转]
  9. Linux下idea 配置Android SDK
  10. Stroustrup 谈 C++ 11的新特性
  11. 一个合理的生产环境的 Web 应用程序应该是什么样子的
  12. 天天学习: 关于美资,台资和国企比较分析
  13. matlab 单相整流电路,基于MATLAB的单相桥式整流电路研究
  14. 窗宽窗位与其处理方法
  15. 奶爸日记17 - 长兴岛橘子
  16. win7 快捷键 收集
  17. 活久见!程序员开发进度太慢被公司告上法庭,索赔 90 万!
  18. 深度学习从入门到精通——MTCNN人脸侦测算法
  19. k8s tekton 实现CI流程,从git到docker registry
  20. [POI2007]ZAP-Queries 莫比乌斯反演(模板)

热门文章

  1. 轻触开源(一)-Java泛型Type类型的应用和实践
  2. 八、图形与图像处理(2)
  3. 好好学一遍JavaScript 笔记(一)
  4. NAND FLASH Controler for IMX31
  5. Web测试中容易被忽略的Charset问题
  6. 飞鸽传书内部排序算法的性能比较
  7. 今天的不一会儿的飞鸽传书
  8. 卡巴斯基公布7月中国地区20大恶意软件排行
  9. 我看中国软件---规模篇
  10. 30个Python常用极简代码,拿走就用,赶紧收藏!