欧拉角与四元数(计算,编程)

欧拉角

四元数计算公式

四元数的基本数学方程为 : q = cos (a/2) + i(x * sin(a/2)) + j(y * sin(a/2)) + k(z * sin(a/2)) 其中a表示旋转角度,(x,y,z)表示旋转轴

下面是如何把具体的四元数与旋转轴和旋转角度对应起来。

1.指出旋转轴和旋转角度,如何转化为四元素。

假定旋转轴是:RAxis = Z轴,换算成三维空间单位向量就是RAxis = [0 0 1],旋转60度

那么转化成四元数就是

q.w=cos(60°/2) = 0.866

q.x=RAix.x*sin(60°/2) = 0*0.5=0

q.y=RAix.y*sin(60°/2) = 0*0.5=0

q.z=RAix.z*sin(60°/2) = 1*0.5=0.5

例子验证:从三维空间中看,假定物体点A=[0 1 0],绕 RAxis = Z轴,旋转30度(假定顺时针为正,因为matlab就是顺时针为正,而下面的quat2dcm函数是matlab自带的)

那么物体点A旋转后在世界坐标系下的坐标将是B=[0.866 0.5 0],

如何用四元数计算出呢?思路是这样的:任何一个四元数对应着一个旋转3*3矩阵。

M=quat2dcm(q)*A‘=[0.866;0.5;0],关于quat2dcm在软件matlab里面有。

四元数编程

四元数的一种表示方式是: Q = xi + yj + zk + w

这儿i,  j,  k就可以看成3D 空间的3个坐标柱向量。  基于四元数的这种表示方式所以很直接他就可以被表示成一个标量w
再加上一个3维向量了。

Q = [w, v]

这里 v = xi + yj + zk

自然有一定编程经验的人会立即把这个小家伙用结构体来表示了如下:
struct quaternion
{
       double x, y, z, w;
}
这里我们没必要知道四元数的加减运算法则了,现在为了解决我们的目标(创建基于四元数的摄像机)我们第一步需要知道怎样把他标准化
。四元数的标准化和向量的标准化是一样的。目的都是将模变成1. |Q| = sqrt(w^2 + x^2 +y^2 + z^2)
下面是代码
double getLength(quaternion quat)
{
       return sqrt(quat.x * quat.x + quat.y * quat.y + quat.z * quat.z + quat.w * quat.w);
}

标准化的四元数 Q* = Q/|Q| = [w/|Q|, v/|Q|];
这儿是代码:
quaternion normalize(quaternion quat)
{
       double Length = length(quat);
       quat.x /= Length;
       quat.y /= Length;
       quat.z /= Lenght;
       quat.w /= Length;
       return quat;
}
下来我们需要知道怎样计算一个四元数的共轭四元数, 共轭四元数暂且用Q‘ 来代替吧。
Q‘ = [w, -v]
这儿是计算共轭四元数的代码:
quaternion conjugate(quaternion quat)
{
       quat.x = -quat.x;
       quat.y = -quat.y;
       quat.z = -quat.z;
       quat.w = -quat.w;
       return quat;
}
下面的事情就是看看怎样计算四元数的成绩了,这个貌似有点小小的复杂。
假设有四元数C , A , B 现在我们要计算 C= A* B;
具体的运算规则如下:
C.x = |A.w * B.x + A.x * B.w + A.y * B.z - A.z * B.y|
C.y = |A.w * B.y - A.x * B.z + A.y * B.w + A.z * B.x|
C.z = |A.w * B.z + A.x * B.y - A.y * B.x + A.z * B.w|
C.w = |A.w * B.w - A.x * B.x - A.y * B.y - A.z * B.z|
这儿是代码:
quaternion mult(quaternion quat)
{
      quaternion C;
      C.x = A.w*B.x + A.x*B.w + A.y*B.z - A.z*B.y;
      C.y = A.w*B.y - A.x*B.z + A.y*B.w + A.z*B.x;
      C.z = A.w*B.z + A.x*B.y - A.y*B.x + A.z*B.w;
      C.w = A.w*B.w - A.x*B.x - A.y*B.y - A.z*B.z;
      return C;
}
主要的运算讲完了,下面就要进入正题了。 现在我们是要创建摄像机了请注意。很明显在3D空间里面代表一个摄像机
就需要对这个摄像机进行定位,定向了。所以为了精确的创建摄像机,我们使用3个3维向量来代表摄像机的位置Position,观察方向View,
和摄像机的UP(这个没必要介绍吧)。对于一个第一人称的摄像机来说,我们现在就只需要考虑摄像机的旋转问题了,
使用四元数我们就可以把一个向量绕任意的柱旋转, 为了达到这个目的我们就需要首先将View向量转化成四元数,然后定义一个旋转四元数,最后应用这个旋转四元数到View四元数上就行了。下面请看具体的步骤。
为了获得View四元数,我们就要使用[w, v]来代表了。当然标量w 就设成0了。v 很显然就是View向量了。
因此四元数V(我们转化的View四元数) V = [0, View]
然后正如上面所说我们下面就要创建那个旋转四元数了,为了创建这个四元数,你就得明确你要绕哪个向量旋转了,还有旋转的角度。我们把这个柱向量(就是绕哪个向量旋转)叫做A,把旋转的角度用theta表示,那么任务即将完成了,我们创建的旋转四元数R就可以表示成:
3DVector A = [x, y , z];
R.x = A.x * sin(theta/2);
R.y = A.y * sin(theta/2);
R.z = A.z * sin(theta/2);
R.w = cos(theta/2);
下来就要进行旋转计算了:
先看看我们现在知道的量:
1. 我们有3维的View向量, 我们有View四元数 V = [0, View]
2. 假设我们要绕A向量来旋转theta度,我们有旋转四元数R来定义这次旋转。
3. 记住旋转完后我们得到的东西仍然是一个View四元数,这个自然是个新的View四元数了。我们假设他是W
所以旋转操作就是:
W = R * V * R‘
这里R是旋转四元数, V是View四元数, R‘ 是旋转四元数R的共轭四元数(其运算前面以讲了)
现在我们仅仅提取新的View四元数W的向量部分。 NewView = [W.x, W.y, W.z]
所以综上所述我们就可以创建函数来进行旋转变换:
void RotateCamera(float angle, float x, float y, float z)
{
       quaternion temp, quat_view, result;// quat_view是View四元数, temp是旋转四元数
     //  下面的三行使用旋转柱和角度计算旋转四元数
       temp.x = x * sin(angle/2);
       temp.y = y * sin(angle/2);
       temp.z = z * sin(angle/2);
       temp.w = cos(angle/2);
       // 计算View四元数
       quat_view.x = View.x; // View 是View向量
       quat_view.y = View.y;
       quat_view.z = View.z;
       quat_view.w = 0;
       //  进行旋转变换
       result = mult(mult(temp, qaut_view), conjugate(temp));
       // 得到新的View向量
       View.x = result.x;
       View.y = result.y;
       View.z = result.z;
}
至此完成。相信有一定OpenGL或D3D基础的人,很容易就把这个翻译成代码了。

时间: 2024-10-14 10:26:18

欧拉角与四元数(计算,编程)的相关文章

欧拉角与四元数转换——编程

三.四元数到欧拉角的转换 arctan和arcsin的结果是 ,这并不能覆盖所有朝向(对于 角 的取值范围已经满足),因此需要用atan2来代替arctan. 四.在其他坐标系下使用在其他坐标系下,需根据坐标轴的定义,调整一下以上公式.如在Direct3D中,笛卡尔坐标系的X轴变为Z轴,Y轴变为X轴,Z轴变为Y轴(无需考虑方向). 2.2.3 四元数计算出欧拉角的程序设计float q0 = 1, q1 = 0, q2 = 0, q3 = 0; //定义四元素void IMU_Update(vo

【3D计算机图形学】变换矩阵、欧拉角、四元数

[3D计算机图形学]变换矩阵.欧拉角.四元数 旋转矩阵.欧拉角.四元数主要用于:向量的旋转.坐标系之间的转换.角位移计算.方位的平滑插值计算.   一.变换矩阵: 首先要区分旋转矩阵和变换矩阵: 旋转矩阵:向量绕某一个轴旋转,用3x3的矩阵表示. 变换矩阵:向量的移动.旋转.缩放,用4x4的矩阵表示. 这里额外补充一个知识,就是三维坐标变换是用4x4矩阵(采用齐次坐标)而不是3x3矩阵的原因是:统一平移和缩放(本来是向量加法来描述)为矩阵乘法的形式来计算.所以旋转矩阵也扩展为4x4矩阵,这样一来

三维空间旋转(欧拉角、四元数、旋转矩阵)

姿态角(欧拉角) 姿态角即RPY(roll, pitch,yaw)又叫欧拉角,是由三个角组成的. 俯仰角(pitch) 翻滚角(roll) 偏航角(yaw) 其中最直观的就是其绕刚体自身的X.Y.Z三个轴分别旋转的角度,这就是欧拉角(Euler Angle)表示方法. 需要注意的是,欧拉角的表示方式里,yaw.pitch.roll的顺序对旋转的结果是有影响的. 给定一组欧拉角角度值,比如yaw=45度,pitch=30度,roll=60度,按照yaw-pitch-roll的顺序旋转和按照yaw-

Unity复杂的旋转-欧拉角和四元数

一.欧拉角欧拉角最容易表示,用三个变量X,Y,Z可以直观的表示绕着某个轴的旋转角度. 在Unity里就是Transform组件的Rotation里的X Y Z三个变量代表了欧拉角 二.四元数四元数相比于欧拉角就比较复杂了,由四个变量组成(在Unity中称为X,Y,Z,W),但是这些变量的值不代表旋转角度,所以可能给你一个向量(0.7,0,0,0.7)你并不知道实际旋转的角度,当然四元数的详细解释需要数学方面的深入研究,有兴趣的可以自行查找有关资料 因为在Unity没有可视化界面可以调整四元数(因

旋转矩阵、欧拉角、四元数理论及其转换关系

博客转载自:http://blog.csdn.net/lql0716/article/details/72597719 1. 概述 旋转矩阵.欧拉角.四元数主要用于表示坐标系中的旋转关系,它们之间的转换关系可以减小一些算法的复杂度. 本文主要介绍了旋转矩阵.欧拉角.四元数的基本理论及其之间的转换关系. 2.原理 2.1 旋转矩阵 对于两个三维点 p1(x1,y1,z1),p2(x2,y2,z2),由点 p1 经过旋转矩阵 R 旋转到 p2,则有 注:旋转矩阵为正交矩阵RRT=E 任意旋转矩阵: 

飞控姿态解算中,欧拉角与四元数之间的转换

//欧拉角转四元数 void cjx_from_euler(float roll, float pitch, float yaw) { float cr2 = cosf(roll*0.5f); float cp2 = cosf(pitch*0.5f); float cy2 = cosf(yaw*0.5f); float sr2 = sinf(roll*0.5f); float sp2 = sinf(pitch*0.5f); float sy2 = sinf(yaw*0.5f); q1 = cr2

欧拉角转四元数

二.欧拉角  欧拉角指的是:以世界坐标系为参考坐标系(一定记住是世界坐标系),使用x,y,z三个值来分别表示绕(世界的)x轴.y轴.z轴 旋转的角度量值.其取值是在[0, 360]间.一般用roll, pitch, yaw来表示这些分量的旋转值.因为是以世界坐标系为参考坐标系,因此每一次的旋转都不会影响到后续的旋转转轴.即:它无法表示任意轴的旋转. 一直以为  x轴是pitch   y是yaw ,z 是roll的,今天受到教训了,搞了很久 原来,x轴对应的roll,y轴对应的是pitch  ,z

Matrix4x4矩阵变换、欧拉角转四元数、角度转弧度

Matrix4x4 1 // 重置矩阵 2 void MatrixIdentity(float m[4][4]) 3 { 4 m[0][0] = 1; m[0][1] = 0; m[0][2] = 0; m[0][3] = 0; 5 m[1][0] = 0; m[1][1] = 1; m[1][2] = 0; m[1][3] = 0; 6 m[2][0] = 0; m[2][1] = 0; m[2][2] = 1; m[2][3] = 0; 7 m[3][0] = 0; m[3][1] = 0;

(转)三维旋转:旋转矩阵,欧拉角,四元数

如何描述三维空间中刚体的旋转,是个有趣的问题.具体地说,就是刚体上的任意一个点P(x, y, z)围绕过原点的轴(i, j, k)旋转θ,求旋转后的点P\'(x\', y\', z\'). 旋转矩阵 旋转矩阵乘以点P的齐次坐标,得到旋转后的点P',因此旋转矩阵可以描述旋转, ?????x′y′z′1?????=R??????xyz1?????[x′y′z′1]=R?[xyz1] 绕x,y,或z轴旋转θ的矩阵为: Rx(θ)=???1000cosθsinθ0?sinθcosθ???Rx(θ)=[1