写在前面:

之前一直不明白四元数概念,原因是主动能动性作怪,一直用欧拉角的方式思考四元数。
再因数学基础不好,忘记复数虚部等概念。(现在也不明白为何要用到复数)。
但简单来说,四元数(w, x,y,z) 中,x,y,z 代表旋转轴,w代表旋转角度。

可以从dx中的 D3DXMatrixLookAtLH 函数上理解:

D3DXMATRIX D3DXMatrixLookAtLH(
	D3DXMATRIX 		  *pOut, 
	CONST D3DXVECTOR3 *pEye, 
	CONST D3DXVECTOR3 *pAt,     
	CONST D3DXVECTOR3 *pUp
);

上面API为函数原型,其中 pEye 为眼睛位置, pAt为观察目标位置,你可以理解成旋转轴;

至于pUp,网络上资料很多都只介绍它的通常为(0,1,0),却没说到为何是 (0,1,0)。
其实,pUp中的 x和y是向上方向的比例【这里比较难解释】,也就是跟旋转角度有关,如果旋转45度的话,pUp就是(1,1,0)同理旋转90度的话,pUp就是(1,0,0),其中z变量可以是任何值,但在变换中不起作用。

欧拉角转换成四元数的公式,其实就是将其分成三步。

  • 先绕x轴旋转xx度,
  • 再绕y轴旋转yy度,
  • 最后绕z轴旋转zz度。

四元数中将三个步骤进行叉成可以获得最终结果。至于四元数转换成欧拉角。。。表示还没明白。


四元数入门

旋转

我将说明使用了四元数(quaternion)的旋转的操作步骤

* 四元数的虚部,实部和写法

所谓四元数,就是把4个实数组合起来的东西。  
4个元素中,一个是实部,其余3个是虚部。

比如叫做Q的四元数,实部t而虚部是x,y,z构成,则像下面这样写:  

Q = (t; x, y, z) 

又,使用向量 V=(x,y,z),Q = (t; V) 也可以这么写。


正规地用虚数单位i,j,k的写法的话: ` Q = t + xi + yj + zk`

* 四元数之间的乘法

虚数单位之间的乘法 :  ii = -1, ij = -ji = k (其他的组合也是循环地以下同文) 

用这个规则一点点地计算很麻烦,所以请用像下面这样的公式计算:

	A = (a; U) 
	B = (b; V) 
	AB = (ab - U·V; aV + bU + U×V)

不过,`U·V` 是内积,`U×V`是外积的意思。

注意:一般 `AB!=BA` 所以乘法的左右要注意!
  • 3次元的坐标的四元数表示

    如要将某坐标(x,y,z)用四元数表示,
    则要这么写:P = (0; x, y, z)

    另外,即使实部是零以外的值,下文的结果也一样。用零的话省事所以我推荐。

* 旋转的四元数表示

以原点为旋转中心,旋转的轴是(α, β, γ),(但 α^2 + β^2 + γ^2 = 1), 

右手系的坐标定义的话,望向向量(α, β, γ)的前进方向反时针地转θ角的旋转,  
用四元数表示就是:

	Q = (cos(θ/2); α sin(θ/2),  β sin(θ/2),  γ sin(θ/2)) 
	R = (cos(θ/2); -α sin(θ/2), -β sin(θ/2), -γ sin(θ/2)) 

另外 R 叫 Q 的共轭四元数。 

四元数的另一个描述

quaternion 是一个标量和一个 3D 向量的组合。
q={ w,x,y,z},Ogre中一个默认的quaternion ={1,0,0,0} ,一般用于空间一点的旋转。

假设空间一点叫 p(x0,y0,z0), 将要旋转角度是 α , 旋转轴是(x,y,z), 那么:

p的四元数表示:p = {0,x0,y0,z0}
旋转矩阵 :    q = {cos(α/2), sina(α/2)Nx, sin(α/2)Ny, sin(α/2)Nz} (N为单位向量)

p点旋转后的结果: q*p*q-1

在数学上,quaternion 表示复数 w+xi+yj+zk,其中i,j,k都是虚数单位。

而复数乘法(叉乘)的几何意义实际上就是对复数进行旋转。

这也是OGRE为什么要用quaternion的原因(比Matrix更快捷更节省空间)

对最简单的二维复数 p=x+yi 来说,和另一个 q=(conα, sinα) 相乘,则表示把 p 沿逆时针方向旋转α:p’ = pq ,这是2D旋转.

如果要表示 3D 旋转,就需要 3D 复数了,于是就有了”四元数”,q=w+ix+jy+kz (i,j,k都是虚数)
其中j,j,k关系如下:

i2 = j2 = k2 = -1

i*j = k = -j*i
j*k = i = -k*j
k*i = j = -i*k

四元数加法:

q1 + q2 = (w1+w2) + (x1+x2)i + (y1+y2)j + (z1+z2)k

四元数乘法:

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*x1) j +
	(w1*z2 + x1*y2 – y1*x2 + z1*w2) k


Published

11 November 2012

Tags