HTML clipboard
四元数记法
一个四元数包含一个标量和一个3D向量分量,经常记标量分量为w,记向量分量为单一的 v 或分开的x、y、z。两种记法分别如下:
[w v ]
[w, (x, y, z)]
在某些情况下,用 v 这样的短记法更方便,但在另一些情况下,"扩展"的记法会更清楚。
也可以将四元数竖着写,有时这会使等式的格式一目了然,"行"或"列"四元数没有明显的区别。
四元数和复数
复数对(a, b)定义了数a+bi,i是所谓的虚数,满足i2 = -1:a称作实部,b称作虚部。任意实数k都能表示为复数(k,
0)=k + 0i。
复数能够相加、相减、相乘,如公式10.1所示:
![](http://www.cppblog.com/images/cppblog_com/lovedday/4213/o_add_sub.jpg)
通过使虚部变负,还能够计算复数的共轭,记法如公式10.2:
![](http://www.cppblog.com/images/cppblog_com/lovedday/5988/o_complex_conjugate.jpg)
还能够计算复数的模。这个运算的记法和解释与实数的绝对值类似,实际上,如果将实数表示成复数,它们将产生相同的结果。公式10.3是计算复数大小的公式:
![](http://www.cppblog.com/images/cppblog_com/lovedday/5988/o_magnitude_complex.jpg)
复数集存在于一个2D平面上,可以认为这个平面有两个轴:实轴和虚轴。这样,就能将复数(x,
y)解释为2D向量。用这种方法解释复数时,它们能用来表达平面中的旋转。看看复数p绕原点旋转角度θ的情况,如图10.9所示:
![](http://www.cppblog.com/images/cppblog_com/lovedday/5988/o_rotate_complex.jpg)
为进行这个旋转,引入第二个复数 q = (cosθ, sinθ)。现在,旋转后的复数p'能用复数乘法计算出来:
p = x + yi
q = cosθ + i sinθ
p' = pq = (x + yi)(cosθ + i sinθ) = (xcosθ - ysinθ) + (xsinθ + ycosθ)i
引入复数q和用2x2旋转矩阵达到的效果是一样的,但复数提供了另一种有趣的记法。
四元数扩展了复数系统,它使用三个虚部i, j, k。它们的关系如下:
![](http://www.cppblog.com/images/cppblog_com/lovedday/5988/o_four_yuan.jpg)
一个四元数[w, (x, y, z)]定义了复数
w+xi+yj+zk,很多标准复数的性质都能应用到四元数上。更重要的是,和复数能用来旋转2D中的向量类似,四元数也能用来旋转3D中的向量。
四元数和轴-角对
欧拉证明了一个旋转序列等价于单个旋转。因此,3D中的任意角位移都能表示为绕单一轴的单一旋转(这里的轴是一般意义上的旋转轴,不要和笛卡尔坐标轴混淆。显然,旋转轴的方向是任意的)。当一个方位用这种形式来描述时称作轴-角描述法(实际上,能将轴-角形式作为描述方位的第四种表达方式。但是,轴-角对很少用到,经常被欧拉角或四元数替代)。
设 n 为旋转轴,对于旋转轴来说长度并不重要,将 n 定义为单位长度会比较方便。根据左手或右手法则, n 的方向定义了哪边将被认为是旋转"正"方向。设θ为绕轴旋转的量,因此,轴-角对( n ,
θ)定义了一个角位移:绕 n 指定的轴旋转θ角。
四元数能被解释为角位移的轴-角对方式。然而, n 和θ不是直接存储在四元数的四个数中,它们的确在四元数里,但不是那么直接。公式10.4列出了四元数中的数和 n ,θ的关系,两种四元数加法都被使用了。
![](http://www.cppblog.com/images/cppblog_com/lovedday/5988/o_quaternion.jpg)
记住, q 的w分量和θ有关系,但它们不是一回事。同样, v 和 n 也有关系但不完全相同。
负四元数
四元数能求负,做法很直接,将每个分量对变负,见公式10.5:
- q = -[w (x y z)] = [-w (-x -y -z)] = -[w v ]
= [-w - v ]
公式10.5 四元数求负
q 和- q 代表的实际角位移是相同的,很奇怪吧!如果我们将θ加上360度的倍数,不会改变 q 代表的角位移,但它使 q 的四个分量都变负了。因此,3D中的任意角位移都有两种不同的四元数表示方法,它们互相为负。
单位四元数
几何上,存在两个"单位"四元数,它们代表没有角位移,[1, 0 ]和[-1, 0 ](注意粗体 0 ,它们代表零向量)。当θ是360度的偶数倍时,有第一种形式,cos(θ/2)=1;θ是360度的奇数倍时,cos( θ /2)=-1。在两种情况下,都有sin(θ/2)=0,所以 n 的值无关紧要。它的意义在于:
当旋转角θ是360度的整数倍时,方位并没有改变,并且旋转轴也是无关紧要的。
数学上,实际只有一个单位四元数:[1, 0 ]。用任意四元数 q 乘以单位四元数[1,
0 ],结果仍是 q 。任意四元数 q 乘以另一个"几何单位"[-1,
0 ]时得到- q 。几何上,因为 q 和- q 代表的角位移相同,可认为结果是相同的。但在数学上, q 和- q 不相等,所以[-1,
0 ]并不是"真正"的单位四元数。
四元数的模
和复数一样,四元数也有模。记法和公式都和向量类似,如公式10.6所示:
![](http://www.cppblog.com/images/cppblog_com/lovedday/5988/o_quaternion_magnitude.jpg)
让我们看看它的几何意义,代入 θ 和 n ,可得到:
![](http://www.cppblog.com/images/cppblog_com/lovedday/5988/o_cal_quaternion_mag.jpg)
n 为单位向量,所以:
![](http://www.cppblog.com/images/cppblog_com/lovedday/5988/o_cal_quaternion_mag2.jpg)
应用三角公式sin2x + cos2x = 1,得到:
![](http://www.cppblog.com/images/cppblog_com/lovedday/5988/o_cal_quaternion_mag3.jpg)
如果为了用四元数来表示方位,我们仅使用符合这个规则的单位四元数。
四元数共轭和逆
四元数的共轭记作 q *,可通过让四元数的向量部分变负来获得,见公式10.7:
![](http://www.cppblog.com/images/cppblog_com/lovedday/5988/o_quaternion_conjugate.jpg)
四元数的逆记作 q ^-1,定义为四元数的共轭除以它的模,见公式10.8:
![](http://www.cppblog.com/images/cppblog_com/lovedday/5988/o_quaternion_inverse.jpg)
四元数的逆和实数的倒数有着有趣的对应关系。对于实数a,它的逆a-1为1/a,从另一方面说,aa-1 = a-1a
= 1。四元数的逆也有着同样的性质,一个四元数 q 乘以它的逆 q -1,即可得到单位四元数[1,
0 ]。
公式10.8是四元数逆的正式定义,但我们只使用单位四元数,所以四元数的逆和共轭是相等的。
共轭非常有趣,因为 q 和 q *代表相反的角位移。很容易验证这种说法,使 v 变负,也就是使旋转轴反向,它颠倒了我们所认为的旋转正方向。因此, q 绕轴旋转θ角,而 q *沿相反的方向旋转相同的角度。