第10章 3D中方位与角位移
3D中有很多方法来描述方位和角位移,本章将主要讲解的是,矩阵、欧拉角、四元数
,需要了解到其优缺点、工作原理,在不同情况选择最合适的描述,转换等
矩阵形式
- 优点
利用矩阵可以在物体和惯性坐标系间旋转向量
矩阵形式被图形API所使用
多角位移连接:知道A关于B的方位和B关于C的方位,利用矩阵可以知道A关于C的方位
矩阵的逆,撤销操作,旋转矩阵是正交的,所以可以很方便的求得逆矩阵 - 缺点
矩阵相对于欧拉角的三个数占用内存很大
不直观
矩阵可能是病态的
矩阵存在六阶冗余,矩阵描述方位,行必须为单位向量并且互相垂直
欧拉角
- 书中称为
heading-pitch-bank
分别代表y-x-z
,正方形由原点沿着方向看,逆时针
为正方向 - 缺点:
给定方位,表达式不唯一,具体表现为heading转360方位没有改变,数值却改变了
万向锁
先heading=45、pitch=90的结果和pitch=90、bank=45的结果相同(这个可以自己拿个东西试试),定义:角度为正负90的第二次旋转,使得第一次和第三次旋转轴相同
两个角度求插值特别困难,具体情况如,在没有进行欧拉角限制时,A=720,B=45,从A->B其实真实插值为45,但是直接插值就会旋转2圈多,但是限制欧拉角依然会产生问题,如下图,A和B只相差了20,但是A->B会绕大圈而不是小圈,解决这个问题可以将插值的角度限制在-180~+180
四元数
- 这个是大佬写的四元数讲解
- 四元数可以记为:
[w, v]
,展开为[w, (x, y, z)]
- 四元数与复数 记为:
a + bi
a为实部,b为虚部,并且满足一下计算
- 共轭复数
a + bi
和a - bi
互为共轭复数 - 复数的模
复数在2D平面上表现
首先认为在存在一个实轴和一个虚轴,具体如下
四元数
- 3个虚部 i、j、k
- 四元数任意角位移都有2个四元数表示,他们互为负,所以也存在2个
单位四元数
, - 四元数的乘法也就是叉乘和上面乘法一样
四元数的逆
就是其共轭复数除以他的模
四元数进行旋转
四元数的差
利用四元数的乘和逆,可以求得四元数的差,差定义为从一个方位到另一个方位的角位移
四元数的点乘
四元数点乘公式:[w1, v1]·[w2, v2] = w1w2 +v1v2
,其绝对值越大代表2个角位移越相似
四元数的对数、指数和标量的乘法(公式太多用到再补进来)
四元数的幂
- 当四元数q代表角位移,如果想得到1/3的角位移,可以使用
q
1
/
3
q^{1/3}
q1/3表示,
当四元数q等于绕x轴旋转30度
,那么 q 2 q^2 q2就代表绕x轴旋转60度
以此类推。注意:四元数是绕小圆弧
,所以 q 4 q^4 q4并不是绕x轴旋转240度,而是绕x逆方向旋转
四元数的 “Slerp”
- “Slerp” 球面线性插值,函数定义
slerp(q0, q1, t)
- 如何得到计算公式呢?分下面3个步骤
– 首先计算四元数q0和q1的差值,可以通过上面的公式 插值 q Δ = q 0 − 1 q 1 q\Delta = q0^{-1}q1 qΔ=q0−1q1,这里的 q 0 − 1 q0^{-1} q0−1可以通过四元数逆公式计算
– 然后计算插值的一部分,这里可以通过四元数的幂计算
– 最后加上插值的一部分,这里可以通过四元数乘法计算
最后得到公式 s l e r p ( q 0 , q 1 , t ) = q 0 ( q 0 − 1 q 1 ) t slerp(q0, q1, t) = q0(q0^{-1}q1)^t slerp(q0,q1,t)=q0(q0−1q1)t,而真正的实际用途中,将会在4D球面的弧形插值(想象成2D弧形插值就行了),具体后面代码中体现
四元数样条 “Squad” 用来描述控制点间的路径,这个在这本书超纲了,暂不讨论
四元数优缺点
- 提供平滑插值
- 快速连接和角位移求逆,矩阵同样可以实现,但是四元数可以更加快速方便求出
- 和矩阵转换更加快速,四元数转换到矩阵形式相较于欧拉角转换为矩阵形式更加快速
- 仅仅使用了4个数,矩阵使用了9个数
各方法比较
- 欧拉角虽然有很多问题,但是易用性不能被忽略,如果将易用性牺牲而优化将得不偿失
- 如果需要在各个坐标系之间转换,还是用矩阵好点
- 当需要保存大量方位数据(如动画)时,就使用欧拉角或者四元数,但是四元数转换成矩阵更加快速
- 平滑插值只能用四元数完成,如果用其他形式,可以转换为四元数后插值完毕,再转换回来
表达式之间的转换
- 最后讨论的是欧拉角、四元数、矩阵如何互相转换
欧拉角到矩阵的转换
- 欧拉角描述了一个旋转序列、分别计算出每个旋转矩阵再连接就可以转换成代表这个角位移的矩阵了
- 第8章学了,物体坐标系转换到惯性坐标系的矩阵,这个矩阵是旋转坐标系,那么角位移就是旋转坐标系矩阵的严格相反。旋转序列heading-pitch-bank分别代表y-x-z轴的旋转,刚好是旋转y、x、z轴坐标系矩阵的相反
- 角位移矩阵(惯性->物体)为:
H
P
B
HPB
HPB,旋转矩阵是正交(逆矩阵就是转置矩阵)的所以 物体->惯性矩阵=
B
−
1
P
−
1
H
−
1
B^{-1}P^{-1}H^{-1}
B−1P−1H−1,
H
P
B
HPB
HPB如下
从矩阵到欧拉角
根据上面求的从欧拉角转换矩阵,计算出heading-pitch-bank各个旋转角度就是欧拉角的值h、p、b
m
23
=
−
s
i
n
p
m_{23} = -sinp
m23=−sinp求得
p
=
a
s
i
n
(
−
m
23
)
p=asin(-m_{23})
p=asin(−m23),得到了p的角度,
c
o
s
p
cosp
cosp就可以得到进而算出其他两个角度(公式比较多,具体的到后面章节代码里展开)
从 四元数到矩阵 和 从矩阵到四元数
- 这里公式推导同样复杂,后面需要推导时再推
从欧拉角到四元数
- 后面再看,公式头疼呀