3D图形:矩阵、欧拉角、四元数与方位的故事


概述


又研究了将近两个星期的3D图形到了我最想研究的地方了,因为欧拉角与四元数的原因导致OpenGL ES的研究进度变缓,研究完这一块,我将教大家如何使用OpenGL ES做一个自转加公转的正立方体.效果如下.



方向、方位与角位移的区别


在说矩阵、欧拉角与四元数三种与角位移的关系之前,我们先来说说 方向、方位与角位移的区别.

在现实生活中,我们很少区分"方向"和"方位"的区别(非路痴观点),比如一个朋友来看望你,但是他可能在某一个公交站下车了,你去接他,但是找不到他,你急忙给他来一个电话"兄弟,你在哪个方向呢?"或者说是"兄弟,你在哪个方位呢?",如果不细细品味这两句话,其实感觉差异不是太大.通过一痛电话的扯,然后你们成功的面基了,但是你们却并不会在意"方向"和"方位"的区别.那么在几何中,这两者到底有什么差异呢?

这里我就盗用一下书上的例子,比如一个向量如果沿着自己的方向选择是不会改变自身任何属性的,如下图所示,因为向量是只有方向没有方位的.


那么对于一个物体,情况却是不一样的,一个物体如果朝向某一个方向的时候,然后自转,那么这个物体是会发生空间上的改变的,如下图一个锥体的自转,那么它的空间位置是发生改变的,也就是锥体的方位发生了改变了.

上面让我们对物体的方向和方位的区别有了一个大体上的了解,那么我们在空间中如何描述一个方位呢?这就需要使用到角位移了.

我们先说一个类似的例子,我们该如何描述空间中一个物体的位置呢?必须要把物体放在特定的坐标系中(好像很生涩).比如,如果我们说在一个坐标系中,有一个点是[1,1,1],那么你会非常轻易的想到了这个点在空间中的位置.描述空间位置其实就是描述相对于给定参考点(坐标原点)的位移.

其实,描述一个物体的方位是一样的,我们是不可能凭空描述一个物体的方位,我盟需要一个已知方位的参考量,通过这个参考量的旋转得到当前方位,那么旋转的量就叫做角位移.通过概念我们知道,角位移就是用来描述方位的,类似于速度就是用来描述物体运动快慢的一样.当然了,这里我要声明的一点就是虽然角位移是用来描述方位的,但是两者是不同的.例如,我们可以这么说,一个物体的方位是如何如何的;一个物体是通过某个已知方位经过角位移XXX旋转得到.所以说,方位是用来描述一个单一的"状态".但是角位移是用来描述两个状态之间的差异.

那么,我们在实际中如何描述方位与角位移呢?具体而言,我们使用矩阵和四元数来表示"角位移",用欧拉角来表示方位.接下来,我们逐一介绍一下.


使用矩阵表示角位移


在3D环境中,描述坐标系中方位的方式就是列出这个坐标系的基向量,当然了,这些基向量是用其他表示的,并不是它本身的基向量,比如当前转换完成的坐标系的三个基向量p [1,0,0] q[0,1,0] r[0,0,1],这是使用本身的坐标系表示,如果放在其他坐标系中表示当前的三个基向量可能就会发生改变.这是因为参照点选择的不同.至于基向量是如何改变的就需要在3D图形:矩阵与线性变换说过的旋转矩阵的相关知识了.这个就不过多的解释了.比如下图,由向量p,q,r组建的新的坐标系用原来的坐标系表示确实如图右边所示.

其实对于我们开发来说,我们只需要知道方位是可以使用3X3矩阵来表示的.矩阵表示的是转换后的基向量即可.接下来我们说一下使用矩阵来表示角位移有什么样的优势和缺点.我就直接拿书上所讲的了,各位看官莫怪莫怪.

使用矩阵表示角位移的优势
  • 可以立即进行向量的旋转.后面使用四元数进行空间变化其实是和使用对应的矩阵的空间变化的效果是一样的.
  • 矩阵的形式被图形API所使用.这一点我们从OpenGL ES 就可以看出来了,无需过多解释了.
  • 多个角位移连接.我们知道使用矩阵进行空间变换是可以连续进行多个的.那么角位移也是一样的.
  • 矩阵的逆.这个比较好理解,如果我们进行了一次旋转变换(也就是空间方位的变化),那么如何回到原来的方位呢,只要再乘上一次矩阵的逆即可,前面说过矩阵的逆是有这样的功能的.
使用矩阵表示角位移的缺点
  • 矩阵可能占有更多内存.这其实是由比较性的,这种比较是要与欧拉角做比较,与欧拉角比较矩阵所占的内存将会更多.
  • 难以使用.这个确实是,你想想,如果现在你要x轴旋转80°,你还要想想它对应的向量是多少.一痛计算之后,才能得到对用的值,后面直接看到这个矩阵的时候还要接着计算,看看它是如何变换的.这样使用起来是不是非常的恶心?
  • 并非所有矩阵都能描述方位.这一点,我将单独写一篇来讨论这个问题.现在还不是太了解,见谅.

当然了,我们使用矩阵来表示角位移只是作为了解而已,接下来,我们看一下如何使用欧拉角表示方位的.


欧拉角表示方位与万向锁问题


很多人在大学中可能会接触到矩阵,但是欧拉角可能是接触的比较少,最少作为一个学物理的我是这样的.一开始觉得欧拉角比较难理解,但是看了3D图形之后,发现用欧拉角表示方位将会比矩阵更加的直观而且易于使用.下面我们就看一下欧拉角相关的知识.(下面的基本概念跟书上的差不多,因为我觉得书上写个就很好了,所以我就没有再次总结,所以只是写了一遍.)

首先,欧拉角的基本思想是将角位移分解为绕三个互相垂直轴的三个旋转组成的序列.那么这个三个互相垂直的轴是如何定义的呢?其实任意三个轴和任意顺序都是可以的,但是最常用的就是使用笛卡尔坐标系并且按照一定顺序组成的旋转序列.最常用的约定,就是所谓的"heading-pitch-bank"约定,在这个系统中,一个方位被定义为heading角,一个pitch角,一个bank角.其中,在左手坐标系中,我们把heading角定义为绕y轴旋转量,pitch角为绕x轴旋转量,bank角为绕z轴旋转量.旋转法则遵守左手法则(具体请参考3D图形:矩阵与线性变换中的旋转模块).它的基本思想是让物体开始于"标准"方位,就是物体坐标轴和惯性坐标轴对齐.让物体做heading、pitch、bank旋转之后达到最终的空间方位.

例如下图一个锥体,一开始它自身坐标轴与惯性坐标轴是一致.

然后我把heading角设置为45°.根据左手法则(通常使用,但是决定每个旋转的正方向不一定要准守右手或者左手定则),它是会做顺时针旋转.

接着物体的坐标系就发生如下的改变了.锥体的自身坐标轴不再与惯性坐标轴一致,x,z轴都发生了对应的改变.当然了,物体的空间方位也发生了对应的改变.

然后接下来就是pitch、bank旋转,分别是绕x轴旋转和z轴旋转,跟heading旋转是类似的,最后得到锥体的最终的空间方位.这里需要注意的是不管是 heading旋转、 pitch旋转还是bank旋转,旋转的坐标轴都是自身的坐标轴!不是惯性坐标轴!

上面,看完了"heading-pitch-bank"约定系统是如何做空间方位的旋转改变的,接下来,我们来瞅瞅关于欧拉角的其他约定.

  • "heading-pitch-bank"约定系统是有多个名字的,其中的有一组叫做"roll-pitch-yaw",其中roll等同于bank,yaw等价于heading.我们知道"heading-pitch-bank"约定是让方位从惯性坐标系到最终的物体自身坐标系,但是"roll-pitch-yaw"约定却是刚好相反.它是从最终的物体坐标系到最开始的惯性坐标系的旋转变换.
  • 任意的三个轴都能作为旋转轴,但是使用笛卡尔坐标轴是最有意义的,这句话我就不过多解释了,我们在上面的例子中已经深有体会了.
  • 决定每一个旋转的正方向不一定必须遵守左手或者右手法则,这样遵守只是习惯而已.
  • 旋转是可以以不同的顺序进行的, "heading-pitch-bank"约定系统只是更比较如何人的习惯而已.因为一个物体放在一个水平面上,如果进行旋转操作的话,我们首先想到的是物体按照垂直轴进行旋转操作.也就是heading旋转.

上面我们对欧拉角的接下来,我们看一下欧拉角的优点和缺点.透露一点,其实欧拉角的缺点就是引起万向锁的原因.

欧拉角表示方位的优点
  • 欧拉角使用起来非常的简单方便,它比四元数以及矩阵更加的生动形象.因为欧拉角使用都是角度,对于人来说旋转还是使用角度比较直观.
  • 最简洁的表达方式.在3D中,欧拉角用3个数就可以表达方位,四元数则要用4个数,而矩阵是最多的,需要9个数.
  • 任意三个数都是合法的,任意的三个数都是能构成合法的欧拉角,矩阵和四元数可不一定是这样的.
欧拉角表示方位的缺点
  • 给定的方位表达方式不唯一.我们虽然说任意三个数组成的欧拉角都是合法的,但是比如heading旋转360°和选择720°,物体的方位是一直的,虽然欧拉角的数值是发生了改变的.
  • 两个角度求插值非常的困难.比如方位A的heading角度为720°,方位B的角度为45°.那么heading值差了多少呢?没错就是45°,因为720°就是旋转了两周而已,但是实际上我们操作的时候需要选择将近两周.如下图所示.

万向锁问题

其实是使用欧拉角会出现一个非常有趣的现象,那就是万向锁,我们看一下"heading-pitch-bank"系统这个系统中,如果pitch角度为±90°,那么就出事了,会出现什么问题呢?heading角与bank角如果相同,那么你会发现物体最终的方位是一致的,这怎么可能,这就比较尴尬了,其实类似于这种旋转pitch角度为±90°中,物体是缺失一个旋转轴的.也就是说,当pitch角度为±90°,那么bank是0.只有heading一个旋转轴起作用,是不是懵圈了?没问题,下面我要分享一个视频,我觉得这个视频会比文字更加生动形象,请对照上面的文字自行研究.

欧拉旋转—万向节锁视频传送门🚪


四元数与复数


看完使用矩阵和欧拉角表示方位.接下来,我们就看一下四元数,四元数一个新的概念出现在我的眼前的时候我在想,他否是因为有四个数才叫四元数,确实,四元数实际是一个标量分量和一个3D向量分量组成用来表示方位.四元数的两种记法如下所示:[ω,ν],[ω,(x,y,z)].
复数,真心好久没用了.高中的时候我们就开始接触简单的复数了,现在简单说一下复数,其实我也顺道复习一下了.
首先,复数的形式为a+bi,其中i²=-1,a称作实部(实数部分),b称作虚部(虚数部分).对于复数的运算,我们主要说说复数的模,复数的模可以很好的表示2D中的旋转变换,我们先看看前面说到过的2D环境中的旋转矩阵.

然后,我们再看一下,一个示例,假设一个复数v = (x,y)旋转θ度得到v',如下图所示.

为了完成此次的旋转,我们需要引入第二个复数 q = (cosθ,sinθ),现在旋转之后的复数v'就可以使用复数的乘法计算出来了.计算过程如下所示.
v = x +yi
q = cosθ +isinθ
v' = vq = (x +yi)(cosθ +isinθ) = (xcosθ-ysinθ)+(xsinθ+ycosθ)i
跟上面的2D环境中旋转矩阵效果是一样的.只是形式不相同而已.

上面说了这么一大堆,那么到底四元数和复数有着怎样的关系呢?其实一个四元数[w,(x,y,z)]定义了复数w +xi +yj +zk,也就是说一个四元数是包含着一个实部和三个虚部.
其实四元数的出现也是有故事的,我直接把书上搬过来,当做在枯燥的学习中的一个轻松时刻吧(实际上,然并卵😂😂😂),爱尔兰的数学家哈密尔顿其实一直想把复数复数从2D扩展到3D,一开始他认为,3D中的复数应该有一个实部和两个虚部,然后他没有创造出这种一个实部两个虚部有意义的复数.1843年,在他去演讲的路上他突然意识到应该有三个虚部而不是两个虚部.他把这种新复数类型行者的等式刻在了Broome桥上.这样四元数就诞生了.等式如下所示.
i² = j² = k² = -1
ij = k,ji = -k
jk = i,kj = -i
ki = j,ik = -j


四元数和轴-角对


我们已经知道了矩阵和欧拉角的情况,现在我们就看一下四元数是如何表示角位移的.在3D环境中任意的一个角位移都可以理解为绕某个轴旋转一定的角度,在3D图形:矩阵与线性变换这个里面曾经说过一个3D中绕任意轴旋转的公式(还记得当初那个验证过程吗,愣是搞了一天😭,具体验证过程就不说了,请查看原来的文章).公式如下所示.其中,θ代表着旋转角度,n代表着旋转轴.因此轴-角对(n,θ)定义了一个角位移:绕n指定的轴旋转θ角.

四元数的解释其实就是角位移的轴-角对方式,但是呢,n和θ并不是直接放入到四元数中的.它们的形式如下所示.

q = [ cos (θ/2) sin(θ/2)n ]
=[ cos (θ/2) ( sin(θ/2)nx sin(θ/2)ny sin(θ/2)nz ) ]

那么问题来了,为什么不直接放入四元数中呢?这是有原因的,这个原因,我将会在下一篇四元数的相关运算中来说明一下.现在只要知道四元数的解释其实就是角位移的轴-角对方式即可.

</b>

结束


自己写完这篇文章总算是对矩阵、欧拉角、四元数、角位移、方位有了一个大体的了解了.整体下来发现真心枯燥的,但是还是坚持了下来了,希望小伙伴也能坚持看完,不懂的或者有疑问可以与骚栋一起探讨.3D图像下一篇我将接着研究本篇的四元数,不过是与四元数的运算相关的知识.希望大家持续关注.

最后还是要附上<<3D数学基础 图形与游戏开发>>的pdf版的传送门.

--> <<3D数学基础 图形与游戏开发>>传送门🚪


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,719评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,337评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 142,887评论 0 324
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,488评论 1 266
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,313评论 4 357
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,284评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,672评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,346评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,644评论 1 293
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,700评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,457评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,316评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,706评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,261评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,648评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,859评论 2 335

推荐阅读更多精彩内容

  • 1 前言 OpenGL渲染3D模型离不开空间几何的数学理论知识,而本篇文章的目的就是对空间几何进行简单的介绍,并对...
    RichardJieChen阅读 6,849评论 1 11
  • 什么是方位? 物体的“方位”主要描述的是物体的朝向,但是“方位”和“方向”不是同一个概念,例如,向量有方向没有方位...
    xiaoxingyun阅读 2,925评论 0 0
  • 欧拉旋转、四元数、矩阵旋转之间的差异 除了欧拉旋转以外,还有两种表示旋转的方式:矩阵旋转和四元数旋转。接下来我们比...
    AndrewFan阅读 2,481评论 0 3
  • 在我们的3D数学中,如果使用矩阵来旋转的话就会显得十分的复杂和笨拙。计算中使用最为广泛的旋转方式为欧拉角。  欧拉...
    Levi_Wan阅读 5,107评论 0 4
  • 行者悟道大光明 慧心妙语法意诚 诚意法语妙心慧 明光大道悟者行 禅舞•光明
    姜冠阅读 228评论 0 1