欧拉角和四元数表示
4.7.2 四元数、欧拉角、旋转矩阵之间的相互转换
满足乘法结合律,分配律,但是不满足交换律:
4.7 物体朝向的四元数表示和插值技术
四元数的范数:
四元数的逆:
四元数的共轭:
4.7 物体朝向的四元数表示和插值技术
四元数的性质:
4.7 物体朝向的四元数表示和插值技术
四元数的性质:
4.7.2 四元数旋转矩阵之间的相互转换
4.6 物体朝向的欧拉角表示和插值技术
在插值朝向时会带来问题:
4.6 物体朝向的欧拉角表示和插值技术
在插值朝向时会带来问题: 结果并非唯一
4.6 物体朝向的欧拉角表示和插值技术
解决办法: 角位移一个旋转可以表示为绕一空间轴n旋转 角。
4.7 物体朝向的四元数表示和插值技术
四元数的定义: 四元数可表示矢量和物体的旋转,并没有冗余信息,它提供了一种 比旋转矩阵更为有效的方法。在计算机图形学和计算机 动面领域中表示物体的旋转和朝向方面尤为便利。 设Q是实数域上的四维向量空间,其正交基底(1,0, 0 ,0),(0,1, 0,0),(0,0,l,0),(0,0,0,1) 分别用e,i,j,k表示
三个欧拉角对应的齐次旋转矩阵为
4.6 物体朝向的欧拉角表示和插值技术
复合成旋转矩阵
:
若不了解这个特定的次序,有可能得到和意愿不同的反转。
4.6 物体朝向的欧拉角表示和插值技术
欧拉角在应用中的缺点:
1.用欧拉角难以建立任意的朝向
2.在插值朝向时会带来问题
4.6 物体朝向的欧拉角表示和插值技术
“万向节死锁”现象,即自由度的突然丧失:
4.7 物体朝向的四元数表示和插值技术
. e
e e
i i
j j
k k
i
j
i
j
-e
-k
k
-e
-j
i
k
k
j
-i
-e
即e作为乘法单位元,而i,j,k按i->j->k->i的次序,相邻两单位元按箭头顺 序相乘等于第三单位元,与箭头顺序反方向相乘则等于第三个单位元的负元.
4.7 物体朝向的四元数表示和插值技术
计算机动画的算法基础
4.6 物体朝向的欧拉角表示和插值技术 4.7 物体朝向的四元数表示和插值技术 4.7.1 四元数的定义及基本性质 4.7.2 四元数、欧拉角、旋转矩阵之间的相互转换
任 歆
4.6 物体朝向的欧拉角表示和插值技术
物体朝向最常见的表示方法为欧拉角,如图:
4.6 物体朝向的欧拉角表示和插值技术
四元素与欧拉角
1.欧拉角在四元数出现之前先看下欧拉角:对于在三维空间里的一个参考系,任何坐标系的取向,都可以用三个欧拉角来表现。
为了后面的角度不混乱,我们要先区分参考系和坐标系的概念。
参考系即为大地参考系,是静止不动的。
而坐标系则固定于四轴飞行器,随着四轴飞行器的旋转而旋转。
按照右图所示。
设定xyz-轴为四轴上的参考轴,XYZ-轴则是大地的参考轴。
右图即为四轴相对地面进行了一定旋转,xy-平面与XY-平面的相交线为交点线,用英文字母(N)代表。
我们可以这样定义欧拉角:α是x-轴与交点线的夹角β是z-轴与Z-轴的夹角γ是交点线与X-轴的夹角这样我们就可以用三个欧拉角:(α,β,γ)其取值为0-360来描述四轴飞行器相对于大地的参考系的姿态角度了。
三个欧拉角:(α,β,γ)。
蓝色的轴是xyz-轴,红色的轴是XYZ-坐标轴。
绿色的线是交点线(N) 。
2.轴角欧拉角使用roll,pitch,yaw来表示这些分量的旋转值。
需要注意的是,这里的旋转是针对大地参考系说的,这意味着第一次的旋转不会影响第二、三次的转轴,简单的说,三角度系统无法表现任意轴的旋转,只要一开始旋转,物体本身就失去了任意轴的自主性,这也就导致了万向节锁(Gimbal Lock)的问题。
什么是Gimbal Lock?正如前面所说,因为欧拉描述中针对x,y,z的旋转描述是世界坐标系下的值,所以当任意一轴旋转90°的时候会导致该轴同其他轴重合,此时旋转被重合的轴可能没有任何效果,这就是Gimbal Lock,还有一种是轴角的描述方法,这种方法比欧拉描述要好,它避免了Gimbal Lock,它使用一个3维向量表示转轴和一个角度分量表示绕此转轴的旋转角度,即(x,y,z,angle),一般表示为(x,y,z,w)或者(v,w)。
(x,y,z)为旋转轴,w为旋转角度。
但这种描述法却不适合插值。
轴角的表示方法:那么轴、角的描述方法又有什么问题呢?虽然轴、角的描述解决了Gimbal Lock,但这样的描述方法会导致差值不平滑,差值结果可能跳跃,欧拉角描述同样有这样的问题。
gl-matrix 欧拉角和四元数相互转化
欧拉角和四元数是在计算机图形学和游戏开发中常用的两种旋转表示方法,它们可以相互转化,用于描述物体的旋转姿态。
gl-matrix 是一种专门用于线性代数的JavaScript 库,提供了便利的函数来处理矩阵、向量、旋转等操作。
在 gl-matrix 中,也提供了欧拉角和四元数相互转化的函数,方便开发者在使用这两种表示方法时进行转换。
本文将介绍 gl-matrix 中欧拉角和四元数的相互转化方法,并结合实际案例进行详细讲解。
1. 欧拉角和四元数的概念在计算机图形学和游戏开发中,欧拉角和四元数是用来描述物体旋转的常用方法。
欧拉角是通过旋转顺序和旋转角度来描述物体在三维空间中的旋转姿态,一般包括绕 x 轴、y 轴和 z 轴的旋转角度。
而四元数是一种复数的扩展,可以用来表示三维空间中的旋转,其具有较好的数学性质和计算性能。
2. gl-matrix 中的欧拉角和四元数表示gl-matrix 是一种快速、轻量级且又开放源代码的数学库,用于矢量和矩阵运算。
在 gl-matrix 中,欧拉角和四元数都是以数组的形式来表示的。
欧拉角可以用一个包含三个旋转角度的数组来表示,而四元数则可以用包含四个元素的数组来表示。
3. 欧拉角和四元数相互转化的原理欧拉角和四元数是两种不同的旋转表示方法,它们之间存在着一定的转换关系。
在 gl-matrix 中,提供了方便的函数来实现欧拉角和四元数的相互转化。
欧拉角转四元数的原理是先将欧拉角转化为旋转矩阵,再将旋转矩阵转化为四元数;而四元数转欧拉角的原理是先将四元数转化为旋转矩阵,再将旋转矩阵转化为欧拉角。
4. 在 gl-matrix 中实现欧拉角和四元数的相互转化接下来,我们将通过一个具体的案例来演示在 gl-matrix 中如何实现欧拉角和四元数的相互转化。
假设我们有一个物体,其初始的欧拉角为 [0, 0, 0],我们需要将其转化为四元数表示。
我们可以使用 gl-matrix 提供的函数 'quat.create()' 来创建一个四元数:```javascriptvar quaternion = quat.create();```我们可以使用 gl-matrix 提供的函数 'quat.fromEuler()' 来将欧拉角转化为四元数:```javascriptvar euler = [0, 0, 0];quat.fromEuler(quaternion, euler[0], euler[1], euler[2]);```通过上述操作,我们就可以将初始的欧拉角 [0, 0, 0] 转化为对应的四元数表示。
四元数
1.轴、角转四元数公式:q = [cos(Q/2), sin(Q /2)v] v是旋转轴矢量,Q是旋转角度2.欧拉角转四元数:qroll = [cos (y/2), (sin(y/2), 0, 0)]qpitch = [cos (q/2), (0, sin(q/2), 0)]qyaw = [cos(f /2), (0, 0, sin(f /2)]pitch(俯仰),yaw(偏航),roll(滚转)3.四元数转旋转矩阵:| 1 - 2y2 - 2z2 2yz + 2wx 2xz - 2wy | Rm = | 2xy - 2wz 1 - 2x2 - 2z2 2yz - 2wx | | 2xz + 2wy 2yz - 2wx 1 - 2x2 - 2y2|4.矩阵转四元数代码:MatToQuat(float m[4][4], QUAT * quat){float tr, s, q[4];int i, j, k;int nxt[3] = {1, 2, 0};tr = m[0][0] + m[1][1] + m[2][2];// check the diagonalif (tr > 0.0){s = sqrt (tr + 1.0);quat->w = s / 2.0;s = 0.5 / s;quat->x = (m[1][2] - m[2][1]) * s;quat->y = (m[2][0] - m[0][2]) * s;quat->z = (m[0][1] - m[1][0]) * s;}else{// diagonal is negativei = 0;if (m[1][1] > m[0][0]) i = 1;if (m[2][2] > m[i][i]) i = 2;j = nxt[i];k = nxt[j];s = sqrt ((m[i][i] - (m[j][j] + m[k][k])) + 1.0); q[i] = s * 0.5;if (s != 0.0) s = 0.5 / s;q[3] = (m[j][k] - m[k][j]) * s;q[j] = (m[i][j] + m[j][i]) * s;q[k] = (m[i][k] + m[k][i]) * s;quat->x = q[0];quat->y = q[1];quat->z = q[2];quat->w = q[3];}}5.四元数转矩阵代码:QuatToMatrix(QUAT * quat, float m[4][4]){float wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2;// calculate coefficientsx2 = quat->x + quat->x;y2 = quat->y + quat->y;z2 = quat->z + quat->z;xx = quat->x * x2;xy = quat->x * y2;xz = quat->x * z2;yy = quat->y * y2;yz = quat->y * z2;zz = quat->z * z2;wx = quat->w * x2;wy = quat->w * y2;wz = quat->w * z2;m[0][0] = 1.0 - (yy + zz);m[1][0] = xy - wz;m[2][0] = xz + wy;m[3][0] = 0.0;m[0][1] = xy + wz;m[1][1] = 1.0 - (xx + zz);m[2][1] = yz - wx;m[3][1] = 0.0;m[0][2] = xz - wy;m[1][2] = yz + wx;m[2][2] = 1.0 - (xx + yy);m[3][2] = 0.0;m[0][3] = 0;m[1][3] = 0;m[2][3] = 0;m[3][3] = 1;}6.欧拉角转四元数代码:EulerToQuat(float roll, float pitch, float yaw, QUAT * quat) {float cr, cp, cy, sr, sp, sy, cpcy, spsy;// calculate trig identitiescr = cos(roll/2);cp = cos(pitch/2);cy = cos(yaw/2);sr = sin(roll/2);sp = sin(pitch/2);sy = sin(yaw/2);cpcy = cp * cy;spsy = sp * sy;quat->w = cr * cpcy + sr * spsy;quat->x = sr * cpcy - cr * spsy;quat->y = cr * sp * cy + sr * cp * sy; quat->z = cr * cp * sy - sr * sp * cy; }四元数乘法QuatMul(QUAT *q1, QUAT *q2, QUAT *res){ float A, B, C, D, E, F, G, H;A = (q1->w + q1->x)*(q2->w + q2->x);B = (q1->z - q1->y)*(q2->y - q2->z);C = (q1->w - q1->x)*(q2->y + q2->z);D = (q1->y + q1->z)*(q2->w - q2->x);E = (q1->x + q1->z)*(q2->x + q2->y);F = (q1->x - q1->z)*(q2->x - q2->y);G = (q1->w + q1->y)*(q2->w - q2->z);H = (q1->w - q1->y)*(q2->w + q2->z);res->w = B + (-E - F + G + H) /2;res->x = A - (E + F + G + H)/2;res->y = C + (E - F + G - H)/2;res->z = D + (E - F - G + H)/2;}四元数插值QuatSlerp(QUAT * from, QUAT * to, float t, QUAT * res){float to1[4];double omega, cosom, sinom, scale0, scale1;// calc cosinecosom = from->x * to->x + from->y * to->y + from->z * to->z + from->w * to->w;// adjust signs (if necessary)if ( cosom <0.0 ){ cosom = -cosom; to1[0] = - to->x;to1[1] = - to->y;to1[2] = - to->z;to1[3] = - to->w;} else {to1[0] = to->x;to1[1] = to->y;to1[2] = to->z;to1[3] = to->w;}// calculate coefficientsif ( (1.0 - cosom) > DELTA ) {// standard case (slerp)omega = acos(cosom);sinom = sin(omega);scale0 = sin((1.0 - t) * omega) / sinom; scale1 = sin(t * omega) / sinom;} else {// "from" and "to" quaternions are very close// ... so we can do a linear interpolationscale0 = 1.0 - t;scale1 = t;}// calculate final valuesres->x = scale0 * from->x + scale1 * to1[0]; res->y = scale0 * from->y + scale1 * to1[1]; res->z = scale0 * from->z + scale1 * to1[2]; res->w = scale0 * from->w + scale1 * to1[3]; }。
四元数与欧拉角(RPY角)的相互转换
四元数与欧拉⾓(RPY⾓)的相互转换RPY⾓与Z-Y-X欧拉⾓ 描述坐标系{B}相对于参考坐标系{A}的姿态有两种⽅式。
第⼀种是绕固定(参考)坐标轴旋转:假设开始两个坐标系重合,先将{B}绕{A}的X轴旋转γ,然后绕{A}的Y轴旋转β,最后绕{A}的Z轴旋转α,就能旋转到当前姿态。
可以称其为X-Y-Z fixed angles或RPY⾓(Roll, Pitch, Yaw)。
Roll:横滚 Pitch: 俯仰Yaw: 偏航(航向) 由于是绕固定坐标系旋转,则旋转矩阵为(cα is shorthand for cosα, sα is shorthand for sinα,and so on.)R XYZ(γ,β,α)=R Z(α)R Y(β)R X(γ)=cαcβcαsβsγ−sαcγcαsβcγ+sαsγsαcβsαsβsγ+cαcγsαsβcγ−cαsγ−sβcβsγcβcγ 另⼀种姿态描述⽅式是绕⾃⾝坐标轴旋转:假设开始两个坐标系重合,先将{B}绕⾃⾝的Z轴旋转α,然后绕Y轴旋转β,最后绕X轴旋转γ,就能旋转到当前姿态。
称其为Z-Y-X欧拉⾓,由于是绕⾃⾝坐标轴进⾏旋转,则旋转矩阵为:R Z′Y′X′(α,β,γ)=R Z(α)R Y(β)R X(γ)=cαcβcαsβsγ−sαcγcαsβcγ+sαsγsαcβsαsβsγ+cαcγsαsβcγ−cαsγ−sβcβsγcβcγ 可以发现这两种描述⽅式得到的旋转矩阵是⼀样的,即绕固定坐标轴X-Y-Z旋转(γ,β,α)和绕⾃⾝坐标轴Z-Y-X旋转(α,β,γ)的最终结果⼀样,只是描述的⽅法有差别⽽已。
In gerenal: three rotations taken about fixed axes yield the same final orientation as the same three rotations taken in opposite order about the axes of the moving frame.Axis-Angle与四元数 绕坐标轴的多次旋转可以等效为绕某⼀转轴旋转⼀定的⾓度。
ue欧拉角和四元数
ue欧拉角和四元数
欧拉角和四元数都是用于描述物体在三维空间中的旋转姿态的数学工具。
欧拉角是通过连续的旋转操作将一个物体从一个固定的坐标系转到另一个坐标系的方法。
它由三个角度组成,分别是绕X轴的旋转角度(俯仰角)、绕Y轴的旋转角度(偏航角)和绕Z轴的旋转角度(翻滚角)。
欧拉角的优点是简单直观,容易理解和计算。
然而,当连续旋转的操作次序发生变化时,会引入万向锁问题,导致计算结果出现不确定性。
四元数是一种复数扩展的数学工具,用于表示三维空间中的旋转。
它由一实部和三个虚部组成,实部表示旋转的角度,虚部表示旋转的轴向。
四元数的优点是在进行连续旋转计算时没有万向锁问题,且计算效率高。
然而,四元数的运算复杂度较高,对于直观理解和可视化展示不如欧拉角直观。
欧拉角和四元数在计算机图形学、机器人工程和飞行模拟等领域广泛应用。
根据具体的需求和应用场景,选择适合的旋转表示方法是很重要的。
四元数和欧拉角
四元数和欧拉角
四元数与欧拉角:
1、四元数
四元数是一种数学物体,它由ONE个实部和THREE个虚部组成。
实部是非负实数,其余的THREE个部分是虚数。
四元数的表达式可以表示为:Q=a+bi+cj+dk (a、b、c、d是实实部)。
它们有助于以三维空间中的方式表示方向和旋转。
离散空间中表示四元数,当旋转发生时,它们保持一致。
2、欧拉角:
欧拉角是一种三维旋转矢量,可以用来表示不同方向之间的关系。
它将旋转分成THREE个不同的轴,分别为X轴、Y轴和Z轴。
每个轴都有自己的旋转角度,比如X轴有X角度,Y轴有Y角度,Z轴有Z角度。
欧拉角的表达式可以写作:[X,Y,Z],其中X、Y、Z分别表示每个轴的旋转角度。
欧拉角与四元数之间的差别在于欧拉角表示的是不同方向间的关系,而四元数表示的是不同方向的空间旋转。
可以说四元数和欧拉角均是用来表示旋转有关信息的,但是又是有所差别的。
下面我们来总结下它们两者之间的区别:
1)表示方式不同:欧拉角表示的是不同方向间的关系,而四元数是表
示不同方向的空间旋转;
2)用途不同:欧拉角被广泛应用于3D图形学处理领域,可以很方便
地实现3D模型的几何变换;而四元数方便地表示空间任意的旋转变换,是用来表达机器人的运动控制中的基本角度表示方式;
3)值域不同:欧拉角的值域为[0,2π),而四元数的值域为[-1,1];
4)叠加角度表示方法不同:四元数是可以用乘法表达累加旋转;而欧
拉角只能使用加法来表达叠加旋转。
四元数 旋转举证 转 欧拉角
四元数旋转举证转欧拉角四元数是一种描述三维空间旋转的数学工具,它是由一个标量和三个虚数构成的,可以视为在四维空间中的点。
与欧拉角相比,四元数旋转具有更好的可靠性和稳定性,并且能够避免万向锁问题(Gimbal lock)。
然而,在实际应用中,许多场景仍然需要将四元数转换为欧拉角进行使用。
那么,如何将四元数转化为欧拉角呢?首先需要明确的是,四元数存在多种表示方式,如单位四元数表示旋转的角度和旋转轴,而其他形式的四元数则不一定具有相同的意义。
因此,在进行四元数与欧拉角转换时,需要根据具体的物理问题和数学约定来选择适当的表示方式。
在将四元数转换为欧拉角时,通常可以采用两种方法,分别为转轴-角度法和旋转矩阵法。
对于两种方法,都需要先将四元数转换为旋转轴和旋转角度或旋转矩阵。
其中,转轴-角度法可以较为简便地进行转换,但存在无法唯一确定欧拉角的问题。
而旋转矩阵法能够确定唯一的欧拉角,但其计算较为繁琐。
对于转轴-角度法,首先需要使用四元数求出旋转轴和旋转角度。
具体方法为将四元数表示为$q=(cos\theta,sin\theta n)$,其中$\theta$为旋转角度,$n$为旋转轴的单位向量。
然后,可以通过反三角函数求出欧拉角,如pitch=$arctan(2(q_wq_x+q_yq_z),(1-2(q_x^2+q_y^2)))$,yaw=$arcsin(2(q_wq_y-q_xq_z))$,roll=$arctan(2(q_wq_z+q_xq_y),(1-2(q_y^2+q_z^2)))$。
在进行转换时,需要注意欧拉角的计算顺序,常见的有Z-Y-X顺序(即roll-pitch-yaw)和X-Y-Z顺序(即yaw-pitch-roll)等。
对于旋转矩阵法,需要求出四元数对应的旋转矩阵,然后通过将旋转矩阵分解为三个正交基向量再计算出欧拉角。
具体方法为将四元数表示为$q=(q_w,q_x,q_y,q_z)$,则其对应的旋转矩阵为:$$\begin{bmatrix}1-2(q_y^2+q_z^2) & 2(q_xq_y-q_zq_w) & 2(q_xq_z+q_yq_w)\\2(q_xq_y+q_zq_w) & 1-2(q_x^2+q_z^2) & 2(q_yq_z-q_xq_w)\\2(q_xq_z-q_yq_w) & 2(q_yq_z+q_xq_w) & 1-2(q_x^2+q_y^2)\end{bmatrix}$$然后,可以利用正交矩阵的特点来分解出三个正交基向量。
三维空间旋转坐标表示
三维空间旋转坐标表示
在三维空间中,旋转坐标通常用欧拉角、旋转矩阵或四元数来表示。
1. 欧拉角:欧拉角是用来描述三维空间中旋转的一种方法,它使用三个角度值(通常用α、β和γ表示)来表示一个物体的方位。
其中,α表示物体绕着垂直于纸面的轴线旋转的角度,β表示物体绕着平行于纸面的轴线旋转的角度,γ表示物体绕着通过旋转轴线的垂直轴线旋转的角度。
2. 旋转矩阵:旋转矩阵是一种用来描述三维空间中旋转的数学工具,它是一个3x3的方阵,可以表示一个绕着某个轴旋转一定角度的旋转操作。
旋转矩阵的表示方法有很多种,其中最常用的是单位矩阵和绕着Z轴旋转的矩阵。
单位矩阵表示不进行任何旋转,而绕着Z轴旋转的矩阵则可以用来表示绕着Z轴旋转一定角度的操作。
3. 四元数:四元数是一种用来描述三维空间中旋转的数学工具,它由一个实数和三个虚数组成,可以表示一个绕着某个轴旋转一定角度的旋转操作。
四元数的表示方法有很多种,其中最常用的是单位四元数和绕着Z轴旋转的四元数。
单位四元数表示不进行任何旋转,而绕着Z轴旋转的四元数则可以用来表示绕着Z轴旋转一定角度的操作。
总之,三维空间的旋转坐标表示方法有很多种,具体使用哪种方法取决于具体的应用场景和需求。
四元数转欧拉角公式
四元数转欧拉角公式1 四元数简介四元数是一种数学上的扩张,它可以用来表示旋转、仿射变换、坐标变换等多种数学表示。
四元数由一个标量和一个三维向量组成,其中标量称为实部,三维向量称为虚部。
2 四元数转欧拉角欧拉角是指绕三个坐标轴的旋转角度,分别称为滚动角、俯仰角和偏向角。
将四元数转换为欧拉角可以用以下公式:psi = atan2(2(q0*q1 + q2*q3), 1 - 2(q1*q1 + q2*q2))theta = asin(2(q0*q2 - q3*q1))phi = atan2(2(q0*q3 + q1*q2), 1 - 2(q2*q2 + q3*q3))其中psi、theta、phi分别对应欧拉角的偏向角、俯仰角和滚动角,q0、q1、q2、q3为四元数的四个分量。
3 四元数转欧拉角的原理通过四元数和欧拉角的定义,我们可以知道,欧拉角相当于描述了三个坐标轴的旋转,而四元数可以表示任意旋转。
因此,我们可以使用四元数来表示欧拉角相应的旋转,然后通过比较四元数和欧拉角的定义,推出它们之间的关系式。
4 四元数转欧拉角的应用四元数转欧拉角常常用于3D游戏、计算机图形学等领域。
在3D 游戏中,我们需要获取角色的坐标和旋转信息,通过四元数转换欧拉角可以获得相应的旋转角度;在计算机图形学中,我们需要将三维模型转换为投影到二维屏幕上的二维图像,通过四元数转换欧拉角可以对三维对象进行旋转变换。
5 结论四元数和欧拉角是两种不同的数学表达方式,但它们之间存在一定的关系,通过转换可以实现相互转换。
四元数转换为欧拉角的公式虽然有些复杂,但是在实际应用中可以轻松地进行计算,并且可以提高程序的效率和可读性。
欧拉角与四元数
四元数与旋转一.四元组基础Q(x,y,z,w),其中x,y,z用来确定旋转轴,w为旋转的角度Q=w+xi+yj+zk,i,j,k为三个虚轴的单位分量I*j=kJ*k=i;K*i=j;叉乘:c=a × b=| i j k||a1 b1 c1||a2 b2 c2|=(b1c2-b2c1,c1a2-a1c2,a1b2-a2b1)c也为一个向量,且c的长度为|a||b|sin(theta),垂直于a和b所在的平面,方向由右手法则来判定,用右手的四指先表示向量a的方向,然后手指朝着手心的方向摆动到向量b的方向,大拇指所指的方向就是向量c 的方向1.四元组相乘:Q1=w1+x1i+y1j+z1k=(w1,v1)Q2=w2+x2i+y2j+z2k=(w2,v2)Q1*Q2=(w1*w2-<v1,v2>,w1*v2+w2*v1+v1xv2)( w1+x1i+y1j+z1k)*( w2+x2i+y2j+z2k)=w1*w2-x1*x2-y1*y2-z1*z2+(W1*x2+x1*w2+y1*z2-z1-y2)i+(y1*w2+w1*y2+z1*x2-x1*z2)j+(w1*z2+z1*w2+x1*y2-y1*x2)k对于其中的轴部分,假如v1//v2,则有v1 x v2=0(平行向量的叉乘结果为0)2.四元组的点乘,点乘积为数值:Q1.*Q2=w1*w2+<v1,v2>=w1*w2+x1*x2+y1*y2+z1*z2;3.数乘s为一实数,q为四元组,则有sq=qs4.共轭p=(w,v),则p*=(w,-v)(pq)*=q*p*N(q)=w2+x2+y2+z2q-1=q*/N(q)---------------显然可得qq-1=(1,0)二.使用四元数旋转向量假如有一表示向量的四元组q=(w,v),对其应用旋转量p后的结果为:q’=pqp-1=(w,v’)从上可以看出,计算的结果q’的实部和q的实部是相等的,并且有N(v)=N(v’)如果N(q)=1,则可以令q=(cosa,usina),u也为一个单位向量,则q’是q绕u旋转2a个弧度的结果假如S(q)表示q的实部,则有2S(q)=q+q*2S(pqp-1)= pqp-1+( pqp-1)*=pqp*+(pqp*)*=pqp*+pq*p*=p(q+q*)p*=2S(q)(这里由于p是单位四元数,所以有p-1等于p*)欧拉角到四元数的转换定义pitch, yaw, roll分别为绕X轴、Y轴、Z轴的旋转弧度float p = pitch * PIOVER180 / 2.0;float y = yaw * PIOVER180 / 2.0;float r = roll * PIOVER180 / 2.0;float sinp = sin(p);float siny = sin(y);float sinr = sin(r);float cosp = cos(p);float cosy = cos(y);float cosr = cos(r);this->x = sinr * cosp * cosy - cosr * sinp * siny;this->y = cosr * sinp * cosy + sinr * cosp * siny;this->z = cosr * cosp * siny - sinr * sinp * cosy;this->w = cosr * cosp * cosy + sinr * sinp * siny;normalise();三.使用matlab进行相关计算计算两个向量v1和v2之间的旋转量四元数p,使得v1应用p后到达v2假如v1转到v2的旋转轴为v,旋转角为theta,则q=[v*cos(theta/2)sin(theta/2)]Matlab代码:function q=vector2q(v1,v2)%..normalize....len1=sqrt(v1*v1');len2=sqrt(v2*v2');v1=v1/len1;v2=v2/len2;angle=v1*v2';axis=cross(v1,v2);alen=sqrt(axis*axis');axis=axis/alen;t=acos(angle);t=t/2;q(1)=axis(1)*sin(t);q(2)=axis(2)*sin(t);q(3)=axis(3)*sin(t);q(4)=cos(t);end计算出了q之后,可以获得对应的旋转矩阵,旋转矩阵的计算Matlab里面的矩阵是以列为主顺序的function r=q2rot(q)w=q(4);x=q(1);y=q(2);z=q(3);r=zeros(3,3);r(1,1)=1-2*y*y-2*z*z;r(1,2)=2*x*y+2*w*z;r(1,3)=2*x*z-2*w*y;r(2,1)=2*x*y-2*w*z;r(2,2)=1-2*x*x-2*z*z;r(2,3)=2*z*y+2*w*x;r(3,1)=2*x*z+2*w*y;r(3,2)=2*y*z-2*w*x;r(3,3)=1-2*x*x-2*y*y;r=r';end同时,也可以根据四元数来计算欧拉角function R=q2euler(q)w=q(4);x=q(1);y=q(2);z=q(3);t11=2*(w*x+y*z);t12=1-2*(x*x+y*y);R(1)=atan2(t11,t12);t2=2*(w*y-z*x);R(2)=asin(t2);t31=2*(w*z+x*y);t32=1-2*(y*y+z*z);R(3)=atan2(t31,t32);end计算出来的欧拉角rx,ry,rz,分别为绕X轴、Y轴和Z轴的旋转角,假如有:Rotq=q2rot(q)R=q2euler(q)[rotx roty rotz]=Rotation(R)可以发现Rotq==rotz*roty*rotx从这里可以看出,上面使用四元数这样计算出来的旋转矩阵的旋转顺序分别是X轴、Y轴和Z轴的ra=pi/4;qz=[0 0 -sin(ra) cos(ra)] %绕z旋转-90度qy=[0 sin(ra) 0 cos(ra) ] %绕y旋转90度qyz=qmult(qy,qz)r=q2euler(qyz)上面的r得出的结果为r = -1.5708 0.0000 -1.5708也就是说其几何意义变成先绕X轴旋转-90度,再绕Z轴旋转-90度,而根据qy和qz的相乘我们实际进行的操作却是先绕Z轴旋转-90度,再绕Y轴旋转90度,但是结果却是这两种操作等价,这说明由四元数到欧拉角可以有多个解两个四元数,假如它们的方向是相反的,用它们作用于向量得到的新向量的值仍然相等q1=[0.024666 -0.023954 0.504727 0.862594];arm=[-8.881719 6.037597 -2.36776];q2=-q1;rot1=q2rot(q1);rot2=q2rot(q2);v1=rot1*arm'v2=rot2*arm'上面计算出来的v1等于v2四元数的余弦值为它们的内积假如余弦值小于0,则需要将其中的一个取反,因为上面我们知道一个四元数和它的反方向的四元数对一个向量起相同的作用四元数的相乘,代表旋转的累积pq=p*q;rotp=q2rot(p);rotq=q2rot(q);rotpq=q2rot(pq);rotmul=rotp*rotq;这里rotpq与rotmul相等四. OGRE中Quaternion类的几个函数1.四元数到旋转向量void Quaternion::ToRotationMatrix (Matrix3& kRot) const1 - 2*qy2 -2*qz22*qx*qy -2*qz*qw2*qx*qz +2*qy*qw2*qx*qy + 2*qz*qw 1 - 2*qx2 -2*qz22*qy*qz -2*qx*qw2*qx*qz -2*qy*qw 2*qy*qz +2*qx*qw1 - 2*qx2 -2*qy22.旋转量到四元数根据1中的表格,有:4 *(1-qx2-qy2-qz2) = 1 + m00 + m11 + m22又qw2=1-qx2-qy2-qz2,可得4 *qw2= 1 + m00 + m11 + m22这里解qw必须保证1 + m00 + m11 + m22>=0,如果不是的话,就构造其他的等式来计算,OGRE中分成两种情况,一种是m00 + m11 + m22>=0,就可以直接先解出qw,否则的采用另外的等式计算3.Local axisVector3 xAixs(void) const;取得旋转矩阵的第一列,旋转矩阵和一个向量相乘的话,第一列的数据均和向量的x分量相乘Vecotr3 yAxis(void) const;取得旋转矩阵的第二列,旋转矩阵和一个向量相乘的话,第二列的数据均和向量的y分量相乘Vecotr3 zAxis(void) const;取得旋转矩阵的第三列,旋转矩阵和一个向量相乘的话,第三列的数据均和向量的z分量相乘。
