DIRECTX中的四元数

四元数是从复数中演变过来的,不过,感觉四元数的研究好像还不是很系统。好在,我们只要会用四元数就可以了,更深的复数概念完全可以不必理会。四元数最大的好处就是线性插值,其次是可以避免欧拉角表示方位时的所谓万向锁(Gimbal Lock)问题。这里把自己的学习小结一下。
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公式。
9、四元数的对数、指数运算。

D3DXQuaternionLn,描述为:
A unit quaternion, is defined by:
Q == (cos(theta), sin(theta) * v) where |v| = 1
The natural logarithm of Q is, ln(Q) = (0, theta * v)

D3DXQuaternionExp,描述为:
Given a pure quaternion defined by:
Q = (0, theta * v);
This method calculates the exponential result.
exp(Q) = (cos(theta), sin(theta) * v)
10、四元数的插值--slerp
D3DXQuaternionSlerp
四元数的精华就是可以线性平滑的进行插值。slerp__ Spherical Liear Interpolation.
令矢量v0 v1之间的夹角为a, vt = k0v0 + k1v1;
则:k0 = sin((1-t)a)/sin(a); k1 = sin(ta)/sin(a);
其中,二四元数之间的夹角余弦可以用点积来计算:x1x2+y1y2+z1z2+w1w2;
11、四个四元数之间的插值__Squad。很显然是为了插值平滑平保证过渡点之间连续(DIRECTX 文档说是保证过渡点间的切线连续,可以理解为矢量插值的二阶连续)。用到如下2个公式:
D3DXQuaternionSquadSetup
D3DXQuaternionSquad
DIRCTX 文档中的例子:
The following example shows how to use a set of quaternion keys (Q0, Q1, Q2, Q3) to compute the inner quadrangle points (A, B, C). This ensures that the tangents are continuous across adjacent segments.
A B Q0 Q1 Q2 Q3
The following code example demonstrates how you can interpolate between Q1 and Q2.
// Rotation about the z-axis
D3DXQUATERNION Q0 = D3DXQUATERNION(0, 0, 0.707f, -.707f);
D3DXQUATERNION Q1 = D3DXQUATERNION(0, 0, 0.000f, 1.000f);
D3DXQUATERNION Q2 = D3DXQUATERNION(0, 0, 0.707f, 0.707f);
D3DXQUATERNION Q3 = D3DXQUATERNION(0, 0, 1.000f, 0.000f);
D3DXQUATERNION A, B, C, Qt;
FLOAT time = 0.5f;
D3DXQuaternionSquadSetup(&A, &B, &C, &Q0, &Q1, &Q2, &Q3);
D3DXQuaternionSquad(&Qt, &Q1, &A, &B, &C, time);
注意:
1 C is +/- Q2 depending on the result of the function. (这点我还是不太明白哦?)
2 Qt is the result of the function.
The result is a rotation of 45 degrees around the z-axis for time = 0.5.

DIRCTX9 的例子:SkinnedMesh Sample.

12、四元数和矩阵的变换
a. 矩阵变换到四元数,D3DXQuaternionRotationMatrix
b. 更一般的,矩阵分解为比例,旋转和位移三个分量:HRESULT WINAPI D3DXMatrixDecompose
( D3DXVECTOR3 *pOutScale, D3DXQUATERNION *pOutRotation,
D3DXVECTOR3 *pOutTranslation, CONST D3DXMATRIX *pM );
c. 四元数变换到矩阵
D3DXMATRIX* WINAPI D3DXMatrixRotationQuaternion
( D3DXMATRIX *pOut, CONST D3DXQUATERNION *pQ);
13、四元数和欧拉角的变换
a. 欧拉角到四元数
// 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 );
b.绕轴旋转
// Rotation about arbitrary axis.
D3DXQUATERNION* WINAPI D3DXQuaternionRotationAxis
( D3DXQUATERNION *pOut, CONST D3DXVECTOR3 *pV, FLOAT Angle );
很不幸,还没有发现四元数到欧拉角的变换公式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值