原文链接

作者:天瑜

前言

在二维平面内,我们用(x, y)来表示点的位置,通过向坐标原始值累加偏移值即可将点移动。但在三维空间内除了位置偏移外,还存在着旋转变化,因此空间内的每个物体都具有至少两个基础特性:位置和方向。位置我们可以用坐标来表达,那么方向由什么概念来表达呢?

1.欧拉角(Euler Angles)

三维空间中物体的旋转变化,可以映射为坐标系的方向变化。换言之,我们去旋转一个空间内的物体,可以将其转化为旋转坐标系。所谓一图胜千言,直接看下图:

我们尽量用简明意赅的语言来描述图片所传达出来的信息。图中有两个三维坐标系,一个蓝色(xyz),另一个是红色(XYZ)。首先,我们先将蓝色坐标系沿z轴旋转α角度,再将蓝色坐标系沿新的x轴旋转β角度,最后将蓝色坐标系沿新Z轴旋转γ角度,就得到新的红色坐标系(XYZ)。如果将三次变换所围绕轴和角度记录下来,那么本次旋转的欧拉角为(z-x-z)-(α, β, γ)。对三种旋转轴顺序进行排列组合后,我们总结共有12种旋转顺序组合,也就是十二种欧拉角。

对于某些简单的旋转方式,比如先绕x轴旋转90度,再绕y轴旋转90度,最后绕x轴旋转-90度,得到的结果与直接围绕z轴旋转-90度结果相同。也就是说实现一个三维旋转不一定非要围绕xyz三个轴每个轴都旋转一次。因此可以对十二种欧拉角做如下分类:

  • 经典欧拉角:(z-x-z,x-y-x,y-z-y,z-y-z, x-z-x,y-x-y)
  • 泰特-布莱恩角:(x-y-z,y-z-x,z-x-y,x-z-y,z-y-x,y-x-z)

旋转轴顺序形如ABA的经典欧拉角适用于相对简单的旋转场景,而需要三个旋转轴的泰布莱恩角更多应用于复杂的旋转场景,比如航空航天领域。

2.旋转矩阵(Rotation Matrix)

线性代数中的矩阵不同于我们熟悉的形如y = ax + b的数学关系式,很容易被"古怪"的概念和各种"方框"搞的晕头转向。正因为矩阵不同于传统具体的数学关系式,在学习和理解矩阵需要转换思考方式。比如,我们可以用具体公式来描述曲线,像贝塞尔曲线、三角函数曲线,但他们都是基于二维平面的,如何用数学来描述线性三维空间内的变换呢?矩阵因此应运而生。

回到本文主题,旋转顺序和角度我们可以用欧拉角来表示,那么如何将其实际应用呢?答案是用旋转矩阵来表示旋转角。以前文坐标系转换为例,抽象出矩阵关系式:

依据矩阵除法求得M的值,即可得到旋转矩阵。在实际推导三维旋转矩阵之前,我们首先推导二维旋转矩阵,有助于我们更好的理解三维旋转矩阵:

原始向量op围绕o点旋转φ角度,原坐标(x, y)变为(x', y'),由图中标注可得:

由三角函数关系式可得:

依据矩阵乘法法则,以上关系式用矩阵表示为:

三维变换就是比二维变换多了一个z轴罢了,当空间内的物体围绕x轴旋转时,我们可以理解为在yz平面进行二维变换。实际推导过程与上式类似,只是x坐标保持不变:

得出围绕x轴的旋转矩阵为:

同理,当空间内的物体围绕y轴和z轴旋转时,记围绕xyz三轴的旋转角分别为θβγ(即欧拉角),矩阵分别为PMQ,有:

3.万向节死锁(Gimbal lock)

使用欧拉角来描述三维方向变化并不是完美的,很经典的例子就是炮台问题:

假设地面上有一个炮台,它可以与地面平行的360度环绕,围绕轴记为x轴,与地面垂直,也可以俯仰(仰视90度或俯视-90度),俯仰旋转时所围绕的轴记为y轴,与地面平行。正北地平线方向记做x=0, y=0。此时一个飞行器从正东x=90 y=10方向向炮台飞来,炮口跟踪瞄准了该飞行器。当飞行器飞到炮台头顶时,飞行器的坐标(同时也是炮口的指向)也从x=90 y=10逐渐递增到了x=90 y=90。突然飞行器向南飞行,但此时炮口垂直地面,无论如何旋转x轴炮口始终指向天顶。从数据的角度说,从正东的x=90x=180发生了不连续突变,然而飞行器的位置却是连续的。

究其根本原因,欧拉角的理论基础是分别计算围绕xyz三轴旋转角度后合并而成的,多种旋转方式的结果会对应同一个三维空间角度,导致在插值场景中使用欧拉角会出现不连续的死锁问题(如上文的大炮跟踪)。死锁问题与解决在3D空间轨迹跟踪等领域有广泛的应用,更多例子有兴趣的读者可以自行google。

如何解决死锁问题呢?答案是四元数。核心理念就是摆脱对围绕xyz旋转计算的依赖,空间内的旋转基于围绕任意轴计算,比如围绕(0, 4, 7)轴。不过四元数就是另一个复杂的话题了。

4.前端应用

在前端应用层,并非只有旋转这一种场景,除了旋转,还有平移、缩放等等。在上文中我们使用三阶矩阵来表达变换,但在更复杂的变换场景中通常使用四阶矩阵来做计算,例如设平移距离分别为TxTyTz,那么得到平移四阶矩阵:

三阶矩阵的运算已经很繁琐,四阶更让人头皮发麻。万幸的是矩阵计算早已工程化了,不必手工操作底层矩阵运算。以代表性的 three.js 为例,它有很多封装成熟的 api 可供使用,大大降低了开发前端3D应用的成本。还有函数库glmatrix,开发者只关心输入输出即可。

了解欧拉角和矩阵变换随便只是开发3D应用的第一步,更宽广的世界依然需要我们不懈探索。

转载于:https://juejin.im/post/5cc2c24ae51d456e6d1334ef

3D应用开发中的欧拉角和旋转矩阵相关推荐

  1. Unity 3D - 游戏开发中的Lua

    Unity 3D - 游戏开发中的Lua : 本文作者:秦元培, 本文出处:http://blog.csdn.net/qinyuanpei/article/details/39826323 前言 : ...

  2. 3D游戏开发中的矩阵详解

    矩阵很多同学没有接触过,所以感觉很难,很复杂,其实只要学过矩阵的同学都知道,矩阵运算并不难.今天我们给大家讲讲游戏开发中的矩阵的运算. 这里有个游戏开发交流小组 大家可以一起来学习交流哦 1:矩阵是什 ...

  3. matlab 欧拉角 方向余弦,旋转矩阵、欧拉角之间转换

    学习过程中涉及欧拉角和旋转矩阵的转换,索性整理学习一下欧拉角四元数和旋转矩阵的概念以及matlab中的互相转换 本文摘自各大课本,博客,自己学习整理使用,侵删 MATLAB矩阵乘法从左到右依次相乘 用 ...

  4. 3D渲染技术分享:3D游戏开发渲染调试高级技巧

    零.本文主要知识点 友情劝退:全文7400+字 如果知识点里没有你想要的,那可以直接拉到底,与评论区大神一战. 最初的计划是想写一篇关于KylinsGraphicsDebugger实现原理的文章,但感 ...

  5. 【备注】【C24】《Android 3D游戏开发技术详解与典型案例》PDF 下载

    [C24]<Android 3D游戏开发技术详解与典型案例>PDF 下载 目前市面上的Android技术书籍还比较少,Android3D游戏开发的书籍更是没有.因此,在现在市面上,Andr ...

  6. Android+3D游戏开发技术详解与典型案例

    内容导读 本书共分两篇,第一篇介绍了Android 3D游戏开发的基础知识,主要对OpenGL ES的相关内容进行了介绍. 章 名主 要 内 容 第1章 英雄还看今朝-Android简介本章介绍了市场 ...

  7. Android 3D游戏开发技术宝典pdf

    下载地址:网盘下载 <Android 3D游戏开发技术宝典:OpenGL ES 2.0>内容简介:随着智能手机移动嵌入式平台硬件性能的不断提升,3D游戏应用也逐渐普及开来.<Andr ...

  8. 《Android 3D游戏开发技术宝典——OpenGL ES 2.0》.(吴亚峰).[PDF]ckook

    图书作者: 吴亚峰 图书编号: 9787115277701 图书格式: PDF 出 版 社: 人民邮电出版社 出版年份: 2012 图书页数: 700-800 [内容简介] 随着智能手机移动嵌入式平台 ...

  9. 22. Unity - 3D游戏开发小计01 --- 修复动画BUG、更改环境光照、导航网格、相机跟随、场景渲染后期处理

    1. 导入玩家角色模型 素材来自于unity官网:3D Beginner:Tutorial Resources 在3D游戏开发中,三维物体模型一般会有团队内的其它成员提供,包括模型本身和动画文件等.我 ...

最新文章

  1. 10、计算机图形学——几何介绍(曲面的分类以及示例)
  2. 王峰记忆法 解密王峰记忆法之迷
  3. python数据类型描述_【文山玩Python】用python的数据类型,来简单的描述世界
  4. 向量点积(Dot Product)
  5. 图谱实战 | 李翔:美团到店综合知识图谱的构建与应用
  6. [机器学习-总结] 什么是准确率, 精确率,召回率和(精确率和召回率的调和平均)
  7. linux 进目录输入密码,scp在Linux主机之间复制文件/目录不用输入密码
  8. idea中使用github
  9. java final域_【Java】final 域的内存语义
  10. jquey 阻止表单提交
  11. 2022年最新《谷粒学院开发教程》:6 - 整合SpringCloud
  12. VS2017 离线安装包下载
  13. 如何减小电压跟随器输出电阻_运算放大器和比较器还傻傻分不清楚?一篇图文教你轻松辨认...
  14. python提示syntaxerror什么意思_“SyntaxError:print”调用中缺少括号在Python中是什么意思?...
  15. 安迪种树 前缀和 差分
  16. 申宝股票-A股长期向好趋势未
  17. 计算机退休工资排名,广州2017退休工资计算器的介绍_广州2017养老金计算方法
  18. SpringBoot+Vue+mybatis生成pdf文件(表头跟页码,适应上传linux服务器后的操作)
  19. ABAP EWM HU打包
  20. python中列表(list)的基本操作

热门文章

  1. [转]static和final的区别
  2. spring注解记录
  3. 2015/12/12 考了PAT,又回来玩Python了。
  4. ibatis的缓存机制
  5. SQL Server数据库事务处理详解(MSDN网上资源)
  6. ruby操作常用数据库 - 使用DBI[翻译 转帖]
  7. HttpClient4 TIME_WAIT和CLOSE_WAIT
  8. 15.2. 网络监控
  9. Rancher Labs联手NeuVector,提供容器管理与安全解决方案
  10. [Linux/Ubuntu] vi/vim 使用方法讲解