四元数基础
1、定义。
typedef struct D3DXQUATERNION { FLOAT x; FLOAT y; FLOAT z; FLOAT w;} 3DXQUATERNION;
DIRECTX9文档中定义,令q为一四元数,theta为绕轴axis旋转的角度,则:
q.x = sin(theta/2) * axis.x
q.y = sin(theta/2) * axis.y q.z = sin(theta/2) * axis.z q.w = cos(theta/2)可以简单写为:q = [sin(theta/2)axis, sin(theta/2)w] 或者 [x,y,z,w] 或者[v,w]
2、负四元数-q 。
-q = [-q.x, -q.y, -q.z, -q.w]
3D几何意义:轴变换了方向,角度也换了方向,刚好 -q = q。这个特性比较郁闷,在3D中任意方位,都有2种不同的四元数表示方法,竟然不是唯一的。
3、单位四元数q = [0,0,0,1].
3D几何意义:好像还看不出有什么几何意义。补充:用处是为了表示旋转0角度,一般用在变量初始化,和矩阵的单位初始话一个道理。
D3DXQuaternionIdentity
D3DXQuaternionIsIdentity
4、四元数的长度或者模 ||q||。
D3DXQuaternionLengthSq 长度的平方 = x*x + y*y + z*z + w*w;
D3DXQuaternionLength 长度,上式的平方根。
根据3D中四元数的定义,只有单位长度的四元数才有意义。尽管在DIRECTX中很多公式并不要求单位四元数,但是我们必须明白,只有单位四元数才有意义。补充:单位四元数的长度为1.
D3DXQuaternionNormalize,这个公式是求标准四元数,类似矢量的正则化。
5、共轭: [-x, -y, -z, w]。逆:共轭除于长度,记为q-1 。
共轭: D3DXQuaternionConjugate
逆:D3DXQuaternionInverse
3D几何意义:相当于转了一个相反的角。由于3D中只有单位长度的四元数才有意义,共轭和逆是一样的。
6、四元数的点积。
D3DXQuaternionDot
q1.q2 = [v1,w1].[v2,w2]=v1.v2 + w1.w2 = x1x2+y1y2+z1z2+w1w2;
3D几何意义:绝对值越大,2个方位越近似,夹角的余弦。补充:对于单位四元数,有-1 <= a.b <= +1,我们一般只关心其绝对值,和矢量点乘类似,绝对值越大,表示2个角度的角位移越小(即相似)。
7、四元数的叉积,一般我们说四元数的乘,指的就是这个叉积。
D3DXQuaternionMultiply
[v1,w1] X [v2,w2] = [w1v2 + w2v1 + v1 X v2, w1w2 - v1.v2];
=[ w1x2 + x1w2 + z1y2 - y1z2,
w1y2 + y1w2 + x1z2 - z1x2,
w1z2 + z1w2 + y1x2 - x1y2,
w1w2 - x1x2 - y1y2 - z1z2 ]
特性:
a、 结合律 (ab)c = a(bc). 交换律不满足ab != ba
b、 ||q1 q2|| = ||q1|| ||q2|| 这个说明:单位四元数相乘的结果还是单位四元数。
c、 (ab)-1 = b-1a-1. 这个和矩阵的逆是一样的。同理:
(Q1Q2...Q(n-1)Qn)-1 = Qn-1Q(n-1)-1...Q2-1Q1-1
8、四元数的差:一个方位到另一个方位的角位移。方位a旋转到b的角位移为d,则ad = b. 经过推导:d = a-1b
这个差找不到相应的DIRECTX公式。
在DirectX中提供了从欧拉角到四元数,从四元数到矩阵(Direct3D用旋转来实现旋转)的变换函数。下面参看:/Microsoft DirectX SDK/Include/d3dx9math.h的函数声明
=======================================================================================
从四元数变换到轴与旋转角
// Compute a quaternin's axis and angle of rotation. Expects unit quaternions.
void WINAPI D3DXQuaternionToAxisAngle
( CONST D3DXQUATERNION *pQ, D3DXVECTOR3 *pAxis, FLOAT *pAngle );
从旋转矩阵构造一个四元数
// Build a quaternion from a rotation matrix.
D3DXQUATERNION* WINAPI D3DXQuaternionRotationMatrix
( D3DXQUATERNION *pOut, CONST D3DXMATRIX *pM);
从一个轴与旋转角构造一个四元数
// Rotation about arbitrary axis.
D3DXQUATERNION* WINAPI D3DXQuaternionRotationAxis
( D3DXQUATERNION *pOut, CONST D3DXVECTOR3 *pV, FLOAT Angle );
从欧拉角构造一个四元数
// Yaw around the Y axis, a pitch around the X axis,
// and a roll around the Z axis.
D3DXQUATERNION* WINAPI D3DXQuaternionRotationYawPitchRoll
( D3DXQUATERNION *pOut, FLOAT Yaw, FLOAT Pitch, FLOAT Roll );
下面我们来看看如何使用:若某物体要绕Y轴旋转fYaw,绕X轴旋转fPitch,绕Z轴旋转fRoll,那么对应的旋转矩阵matRot可以这么计算:
D3DXQUATERNION qR;
D3DXMATRIX matRot; D3DXQuaternionRotationYawPitchRoll(&qR, fYaw, fPitch, fRoll); D3DXMatrixRotationQuaternion(&matRot, &qR);
//Rotation about arbitrary axis.绕轴旋转
D3DXQUATERNION* WINAPI D3DXQuaternionRotationAxis ( D3DXQUATERNION *pOut, CONST D3DXVECTOR3 *pV, FLOAT Angle );
矩阵分解为比例,旋转和位移三个分量:HRESULT WINAPI D3DXMatrixDecompose
( D3DXVECTOR3 *pOutScale, D3DXQUATERNION *pOutRotation, *pOutTranslation, CONST D3DXMATRIX *pM );