首页 > 代码库 > 浅析四元数
浅析四元数
什么是四元数呢?从数学上讲,四元数是复数的一种。所谓复数就是拥有实部和虚部的数。复数(a,b)定义了数a + bi ,i是所谓的虚数,a为实部,b为虚部,满足i²=-1 。对于复数(a,b)可以把b看做是y轴,把a看做是x轴。四元数拥有三个虚部,一个实部。对四元数(w, x,y,z),w是它的实部,x,y,z是它的虚部。知道了四元数的数学属性,不过为了方便我们的使用而已。比如说复数的共轭,通过使复数的虚部变负,可以计算它的共轭。对四元数来说,共轭的意义在哪儿呢?当四元数的模等于1的时候,它的共轭就等于它的逆。这样对于四元数求逆就变得非常简单了。因为我们通常只关心那些模为1的四元数。
为什么只使用模为1的四元数?先看看如何用轴-角关系描述一个四元数。假设四元数q =(w, x,y,z)表示绕指定轴n旋转角度θ,我们可以这样用轴角的方式表示它: q=(cos(θ/2), sin(θ/2)n)。这是四元数的一个最重要的基本概念—它的四个数究竟和角度、轴有什么关系。可以看到,w分量与cos(θ/2)有关系,虚部向量部分与sin(θ/2)有关系。当n为单位向量的时候,四元数的模² = w²+x²+y²+z² = cos(θ/2)² + sin(θ/2)² n² = cos(θ/2)² + sin(θ/2)² = 1。(根据三角函数定理,sinθ²+cosθ² = 1。) 既然n代表了旋转的轴,我们当然要使得n为单位向量才方便计算,这就是我们为什么只使用模为1的四元数。而四元数的逆又定义为用它的共轭除以它的模。这就是为什么说当四元数的模为一的时候它的共轭等于它的逆了。
四元数的运算有叉乘、点乘、求幂运算等。当我们想要像连接两个矩阵那样连接两个四元数所表示的旋转时,可以使用叉乘进行运算。四元数的点乘和向量的点乘非常相似,其结果是一个标量,分别用其实部相乘再加上虚部向量的点乘结果,得到的标量就是四元数点乘的结果。点乘用来计算两个四元数之间的角度。四元数q1 和 q2的夹角 θ 满足cosθ = q1·q2。 四元数求幂类似于实数求幂,比如q表示绕X轴旋转10°,q²就表示绕x轴旋转20°。对于四元数求幂需要注意我们可以求q²,但是不要在这个基础上进一步运算,比如(q²)²,结果可能不是我们预期的q的四次方。此外,假如已知q1,q2,q1q0 = q2,怎么求q0呢?很简单,用q2乘以q1的逆就可以了。q0 = q1^(-1)q2.注意四元数的叉乘不满足交换律,而且我们通常表示四元数叉乘不用*,使用ab,表示点乘时要用点(·)符号,如a·b。
四元数的一个重要用处就是球面线性插值,slerp。slerp能够在两个四元数之间平滑差值,并且没有欧拉角插值那些问题。计算插值可以参照下图:
如图所示,存在两个非零常数k0和k1,使得vt = k0v0 + k1v1。接下来应用三角公式可以求得vt。想象一个球面,所有模为1的四元数都存在于该平面上。
四元数能够独一无二的提供平滑插值的方法,这是欧拉角和矩阵办不到的。四元数的叉乘能够连接多个旋转,共轭可以更方便的求得逆向旋转,比矩阵的转置更方便一些。四元数使用四个数来表示,比矩阵更经济一些。四元数的主要问题是它非常不直观。而且浮点数的舍入和错误的数据输入可能使它不合法。
通常在使用增量旋转和平滑插值的时候建议使用四元数。进行坐标系间的向量变换时,我们只能使用矩阵。对于给定的方位,矩阵是唯一的,欧拉角有无数个表示方法,四元数有两种,互为负。欧拉角的优点是它总是合法的,而且非常直观,易于使用。当在世界中为物体指定方位时,最好使用直观的欧拉角。
浅析四元数