旋转的表达方式有很多种,有欧拉角,旋转矩阵,轴角,四元素等等,今天要学习的就是游戏开发中最常用的四元素。
在讲四元素之前,我们先来看下简单的欧拉角和轴向角。
欧拉角使用最简单的x,y,z值来分别表示在x,y,z轴上的旋转角度,其取值为0-360(或者0-2pi),一般使用roll,pitch,yaw来表示这些分量的旋转值。需要注意的是,这里的旋转是针对世界坐标系说的,这意味着第一次的旋转不会影响第二、三次的转轴。
欧拉角容易出现的问题是 1)不易在任意方向的旋转轴插值; 2)万向节死锁;3)旋转的次序无法确定。
轴角用一个以单位矢量定义的旋转角,再加上一个标量定义的旋转角来表示旋转。通常的表示[x,y,z,theta],前面三个表示轴,最后一个表示角度。表示非常直观,也很紧凑。
轴角最大的一个局限就是不能进行简单的插值,此外,轴角形式的旋转不能直接施于点或矢量,必转换为矩阵或者四元素。
四元素感觉上就是轴角的进化,也是使用一个3维向量表示转轴和一个角度分量表示绕此转轴的旋转角度,即(x,y,z,w), 其中
乘法
给定两个四元数p和q,分别代表旋转P和Q,则乘积pq表示两个旋转的合成(即旋转了Q之后再旋转P),并不是用加法。四元数的乘法定义如下,利用简单的分配律就是了:
q1 * q2 =
(w1*w2 - x1*x2 - y1*y2 - z1*z2) +
(w1*x2 + x1*w2 + y1*z2 - z1*y2) i +
(w1*y2 - x1*z2 + y1*w2 + z1*x2) j +
(w1*z2 + x1*y2 - y1*x2 + z1*w2) k
由于q = w + x i + y j + z k中可以分为纯量w与向量x i + y j + z k,所以为了方便表示,将q表示为(S, V),其中S表示纯量w,V表示向量x i + y j + z k,所以四元数乘法又可以表示为:
q1 * q2 = (S1 + V1)*(S2 + V2) = S1*S2 - V1.V2 + V1XV2 + S1*V2 + S2*V1
求模
N(q) = |q| = x2 + y2 + z2 + w2
单位化
Normalize( q ) = q/ | q | = q / (x2 + y2 + z2 + w2)
求共轭
q*=(-x, -y, -z, w)
求逆
对于向量逆的定义, q-1 =q*/|q|2
对于单位四元素,分母为1,q-1 = q* =(-x, -y, -z, w)
用四元数旋转矢量
给定一个矢量v,再给定一个旋转的单位四元素q,让v旋转q。
首先将v改写成四元素的形式v = (x, y ,z, 0), 接下来要旋转v须用q前乘以矢量v,再后乘以q-1。
v‘ = qvq-1
当然用后面乘以共轭的q也是一样的,因为都是单位四元素。
对于旋转多个四元数,比如 R=R1R2R3. 则
注意顺序。
四元数的线性插值和球面线性插值
四元素的可以方便地进行插值是四元素最大的优势。线性插值最为简单,效率也很高。给定两个旋转四元素qa和qb代表旋转A和旋转B,找到旋转A到旋转B之间的 t 的旋转:
注意这里的 t 实际上是是沿弦上走了t,而不是在球面上走t,这样就会导致当 t 以恒定速度改变时,角度的变化并非恒定.
为了解决这个问题,就出现了球面线性插值。给定四元素q和q,
其中theta是两个四元素的夹角,
四元素转欧拉角
欧拉角转四元素
四元素转旋转矩阵
游戏引擎架构 第四章
Computer Graphics: 四元數與旋轉 - http://openhome.cc/Gossip/ComputerGraphics/QuaternionsRotate.htm