【3D数学基础:图形与游戏开发】笔记 第10章 3D中的方位与角位移
参考资料&原文链接
参考书籍:【3D数学基础:图形与游戏开发】 ISBN7-302-10946XTP.7262
(美) etcher Dun著、(美) an Arberry 清华大学出版社
3D中的方向、方位与角位移
方向
直观地说,我们知道,物体的“方位”主要描述的是物体的朝向。
向量有“方向”但没有“方位”。无论如何旋转这个向量都等于原来的向量,因为向量的属性只有“大小”,而没有“厚度”和“宽度”。
方位与角位移
此物体转动的时候,“方位”发生了变化,称为旋转,旋转的量称为“角位移”。
旋转的三种表示方法
矩阵
前面已经介绍过了,点击这里前往。
欧拉角
欧拉角的基本思想是将角位移分解为绕三个互相垂直轴的三个旋转组成的序列。这听起来很复杂,其实它是非常直观的(事实上,易于使用正是它的主要优点之一)。
本书使用“heading-pitch-bank”约定。
有些书籍也使用“yaw(偏航角)- pitch(俯仰角)- roll(翻滚角)”约定。
它们之间的对应关系是:x轴对应heading/yaw、y轴对应pitch/pitch、z轴对应bank/roll。
前面说过欧拉角的基本思想,所以欧拉角旋转需要分三次旋转,每次旋转对应一个轴:
万向锁
关于万向锁,这个视频讲的很清楚,点击前往。
这个问题容易在欧拉角插值的时候发生。
正常的时候是这样的:
翻滚角:
俯仰角:
偏航角:
当ptich轴为±90°时,此时yaw与roll在同一平面,这时对这两个轴施加旋转都不会真正的让物体转动,相当于roll和yaw被锁住了。
万向锁的实质是一个x、y、z轴的层级问题,注意父轴转动的时候里面嵌套着的子轴也会跟着一起转动。
这个问题无论如何都不能真正解决,只能尽力避免,例如:在遇到万向锁问题的时候调整一下旋转的次序。
四元数
先复习一下复数,因为复数和四元数高度相似。
复数
形式为:a+bi
a称为实部,b称为虚部。
复数和复数之间可以相互加减乘。
加减的规则是对应实部和虚部相加减即可。
乘则是用分配律计算,再用i2 = -1即可。
复数共轭
即将虚部符号乘以-1,记作:p*:
例如:p=(a+bi),则p* = (a-bi)
复数的模
即||p||:
复数与旋转
用复数乘法就可以将一个向量旋转(并拉伸)到一个角度:
四元数的记法
用三个虚维度来描述空间,而实数则在第四个维度,实数垂直于全部的三个虚轴。
用一个标量分量w和一个3D向量分量(x,y,z),即:
[w,v]或[w,(x,y,z)]
四元数与复数
需要三个虚部。即:[w,(x,y,z)] = w+xi+yj+zk
其中:i2=j2=k2=ijk=-1
四元数与轴-角对
设n为任意旋转轴,q绕n旋转θ度,则轴-角对为(n,θ),定义了一个角位移:绕n指定的轴旋转了θ度:
负四元数
即将每个分量都取负。
-q和q代表的实际角度(角位移)是相同的,例如θ加上360°不会改变角位移,但它使q的四个分量都变负了,所以在3D空间中任意角位移都有两种不同的表示方法,他们互相为负。
单位四元数
即[1,(0,0,0)]或[1,0]。
它代表没有旋转(即角位移)。它的相当于实数里面的1、矩阵里面的单位矩阵。
四元数的模
与向量的模、复数的模完全相同。
把轴-角对的n和θ带入到四元数模的公式里:
四元数的模几何意义是:当n为单位向量时(||n|| = 1),||q|| = 1,称为单位(规范化)四元数。
四元数的逆
四元数的逆p-1与实数的逆类似。例如:a的逆a-1为1/a,即a-1a=1,则q-1q=[1,(0,0,0)](单位四元数)。
四元数叉乘
注意:
-
四元数叉乘满足结合律。即:q(rs) = (qr)s。
-
四元数叉乘不满足交换律。即:qr != rq。
-
叉乘后的新四元数的模等于原四元数的模相乘。即:||qr|| = ||q|| ||r||。
此结论保证了两个单位四元数相乘结果还是单位四元数。
-
叉乘后的逆等于各个四元数的逆以相反的顺序相乘,与矩阵的逆的计算相似,并且也可以扩展。即:(ab)-1 = b-1a-1。
四元数的共轭
四元数的共轭q*与复数共轭相同,将虚部求负即可。
注意:v是旋转轴,这里将v变成负的,意思就是说将旋转轴的方向变成负的了。
所以四元数的共轭表示的是向相反的方向进行旋转(即颠倒旋转轴的正方向)。
我们经常用四元数表示绕着v方向旋转,而用它的共轭表示绕着v的反方向旋转。
四元数与旋转
p是3D中的一任一点,用四元数来表示。
q表示旋转轴n和旋转角度θ。
p'表示将 点p 绕着 由q表示的旋转轴和旋转角度θ进行旋转 后的新的点。
下图表示了先将点p绕着由a表示的旋转轴和旋转角度θ进行旋转,再绕着由b表示的旋转轴和旋转角度θ进行旋转,它符合前面说的叉乘公式(叉乘后的逆等于各个四元数的逆以相反的顺序相乘):
四元数“差”
一个方位a和另一个方位b之间有一个角位移d的差距。即从方位a旋转角度d就能到方位b,或者说方位a与方位b之间的夹角是d。
我们将它叫做“差”,但在数学上实际上是除法,因为角度差计算一般来说要用减法,但是在四元数却是用的除来表示差。计算方式是:
四元数点乘
与向量的点乘相同。
四元数的对数、指数、和标量乘运算
这三种运算我们很少直接使用。
首先,让我们重写四元数的定义,引入一个新的变量a,等于半角θ/2:
a=θ/2
四元数对数:
四元数指数:
四元数和标量相乘:
四元数求幂
四元数能作为底数,记作qt(不要和指数运算混淆,指数运算具接受一个四元数作为参数,而四元数求幂有两个参数——四元数和指数)。四元数求幂的意义类似于实数求幂。
这对四元数求幂非常有用,因为它可以从角位移中抽取“一部分”。例如,四元数q代表一个角位移。现在想要得到代表1/3这个角位移的四元数,可以这样计算:q1/3。
指数超出[0,1]范围外的几何行为和预期的一样(但有一个重要的注意事项)。例如,q2代表的角位移是q的两倍。假设q代表绕x轴顺吋针旋转30°,那么q代表绕x轴顺时针旋转60°。q-1/3代表绕x轴逆时针旋转10°。
它的定义是:
四元数插值
当令3D数学中四元数存在的理由是由于一种称作serp的运算,它是球面线性插值的缩写 Spherical Linear Interpolation) slerp运算非常有用,因为它可以在两个四元数间平滑插值slerp运算避免了欧拉角插值的所有问题。
slerp的基本思想是沿着4D球面上连接两个四元数的弧插值(这就是球面线性插值这个名称的由来)。
各表示方法的优缺比较
补充说明:
- 易用程度:即直观程度,是否符合人的思维习惯。例如欧拉角就很符合人的思维习惯,人一眼就能看出来它们分别在哪个轴上面旋转了多少度。
- 表达式不唯一:例如在欧拉角中(127°+180°)与127°表达的旋转角度一致。
- 四元数能和矩阵快速转换。
- 欧拉角使用简单插值可能会导致过多旋转,物体将会沿“长弧”旋转。
各个方法的选择建议
- 为世界中的物体指定方位时,欧拉角最简单。
- 如果需要在坐标系之间转换向量,那么就选择矩阵形式。
- 需要大量保存方位数据如动画)时,就使用欧拉角或四元数。欧拉角将少占用25%的内存。但它在转换到矩阵时要稍徽慢一些。
- 如果动画数据需要嵌套坐标系之间的连接,四元数可能是最好的选择。
- 平滑的插值只能用四元数完成。如果您用其他形式,也可以先转换到四元数然后再插值
插值完毕后再转换回原来的形式。
各个表达式之间的转换
略。
参考资料&原文链接
本文标签
游戏开发
、3D数学基础:图形与游戏开发
、Unreal Engine
、游戏开发基础
、数学
、游戏开发数学基础
、书籍笔记
、笔记
。