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

博客转载自: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

任意旋转矩阵: 
任何一个旋转可以表示为依次绕着三个旋转轴旋三个角度的组合。这三个角度称为欧拉角。 
三个轴可以指固定的世界坐标系轴,也可以指被旋转的物体坐标系的轴。三个旋转轴次序不同,会导致结果不同。

2.2 欧拉角

欧拉角有两种: 
静态:即绕世界坐标系三个轴的旋转,由于物体旋转过程中坐标轴保持静止,所以称为静态。 
动态:即绕物体坐标系三个轴的旋转,由于物体旋转过程中坐标轴随着物体做相同的转动,所以称为动态。 
使用动态欧拉角会出现万向锁现象;静态欧拉角不存在万向锁的问题。

对于在三维空间里的一个参考系,任何坐标系的取向,都可以用三个欧拉角来表现。参考系又称为实验室参考系,是静止不动的。而坐标系则固定于刚体,随着刚体的旋转而旋转。

如图1,设定xyz-轴为参考系的参考轴。称xy-平面与XY-平面的相交为交点线,用英文字母(N)代表。zxz顺规的欧拉角可以静态地这样定义:

α 是x-轴与交点线的夹角,
β 是z-轴与Z-轴的夹角,
γ 是交点线与X-轴的夹角。

图中三个欧拉角分别为:(α,β,γ); 
蓝色的轴为:xyz轴 
红色的轴为:XYZ轴 
绿色的线为交线:N 
α∈[0,2π],β∈[0,π],γ∈[0,2π]

很可惜地,对于夹角的顺序和标记,夹角的两个轴的指定,并没有任何常规。科学家对此从未达成共识。每当用到欧拉角时,我们必须明确的表示出夹角的顺序,指定其参考轴。

实际上,有许多方法可以设定两个坐标系的相对取向。欧拉角方法只是其中的一种。此外,不同的作者会用不同组合的欧拉角来描述,或用不同的名字表示同样的欧拉角。因此,使用欧拉角前,必须先做好明确的定义。

欧拉角的基本思想是将角位移分解为绕三个互相垂直轴的三个旋转组成的序列。所以,欧拉旋转的三个角,可以对应于三个旋转矩阵。 
Yaw(偏航):欧拉角向量的y轴 
Pitch(俯仰):欧拉角向量的x轴 
Roll(翻滚): 欧拉角向量的z轴

Unity3D中,欧拉旋转是按照ZYX的顺序旋转的。(不同的旋转顺序最终得到的结果是不一样的,要引起重视。给定一组欧拉角角度值,比如yaw=45度,pitch=30度,roll=60度,按照yaw-pitch-roll的顺序旋转和按照yaw-roll-pitch的顺序旋转,最终刚体的朝向是不同的!换言之,若刚体需要按照两种不同的旋转顺序旋转到相同的朝向,所需要的欧拉角角度值则是不同的!)

欧拉角的缺点

1、 欧拉角的表示方式不唯一。给定某个起始朝向和目标朝向,即使给定yaw、pitch、roll的顺序,也可以通过不同的yaw/pitch/roll的角度组合来表示所需的旋转。这其实主要是由于万向锁(Gimbal Lock)引起的;
2、欧拉角的插值比较难;
3、计算旋转变换时,一般需要转换成旋转矩阵,这时候需要计算很多sin, cos,计算量较大;

2.2.1 由欧拉角求旋转矩阵

设三个轴x,y,z的欧拉角分别为θx,θy,θz,正弦值、余弦值分别为sx,cx,sy,cy,sz,cz那么旋转矩阵为:

2.2.2 由旋转矩阵求欧拉角

解方程可得:

注:atan2()为C++中的函数,atan2(y,x) 求的是y/x的反正切,其返回值为[-pi,+pi]之间的一个数。

2.3 四元数

四元数(Quaternions)是由爱尔兰数学家哈密顿(William Rowan Hamilton)在1843年提出。

三维空间的任意旋转,都可以用绕三维空间的某个轴旋转过某个角度来表示,即所谓的Axis-Angle表示方法。这种表示方法里,Axis可用一个三维向量(x,y,z)来表示,θ可以用一个角度值来表示,直观来讲,一个四维向量(θ,x,y,z)就可以表示出三维空间任意的旋转。注意,这里的三维向量(x,y,z)只是用来表示axis的方向朝向,因此更紧凑的表示方式是用一个单位向量来表示方向axis,而用该三维向量的长度来表示角度值θ。这样以来,可以用一个三维向量(θ∗x,θ∗y,θ∗z)就可以表示出三维空间任意的旋转,前提是其中(x,y,z)是单位向量。这就是旋转向量(Rotation Vector)的表示方式,OpenCV里大量使用的就是这种表示方法来表示旋转(见OpenCV相机标定部分的rvec)。

  • 单位向量(x,y,z)旋转θ角度后的四元数:

对于三维坐标的旋转,可以通过四元数乘法直接操作,与旋转矩阵操作可以等价,但是表示方式更加紧凑,计算量也可以小一些。

2.3.1 四元数基本概念

  • 四元数的复数定义:
q=q0+q1i+q2j+q3k=[s,v]
其中 q0,q1,q2,q3均为实数, s=q0,v=[q1,q2,q3],i2=j2=k2=−1
对于 i,j,k 本身的几何意义可以理解为一种旋转,其中 i 代表 x 轴与 y 轴相交平面中 x 轴正向向 y 轴正向的旋转, j 旋转代表 z 轴与 x 轴相交平面中 z 轴正向向 x 轴正向的旋转,k 旋转代表 y 轴与 z 轴相交平面中 y 轴正向向 z 轴正向的旋转, −i,−j,−k 分别代表 i,j,k 的反向旋转。

四元数的模

四元数的优点

非奇异表达(和欧拉角之类的表示相比)
比矩阵更紧凑(更快速)
单位四元数的对可以表示四维空间中的一个旋转

  四元数与群

所有单位四元数的集合组成一个三维球S3和在乘法下的一个群(李群)。S3是行列式为1的实正交3x3正交矩阵的群SO(3,R)的双面覆盖,因为每两个单位四元数通过上述关系对应于一个转动。群S3和SU(2)同构,SU(2)是行列式为1的复酉2x2矩阵的群。

设A={q=q0+q1i+q2j+q3k|q0,q1,q2,q3均为实数},则A是一个环,并且是一个格,A中存在24个四元数,而它们是施莱夫利符号为{3,4,3}的正二十四胞体的顶点。

  四元数的运算

 

 四元数乘法的性质

1、满足结合律
2、不满足交换律
3、乘积的模等于模的乘积
4、乘积的逆等于各个四元数的逆以相反的顺序相乘

2.3.2 四元数求旋转矩阵

  • 已知四元数:

2.3.3 旋转矩阵求四元数

四元数的详细解释:https://www.3dgep.com/understanding-quaternions/#Introduction

原文地址:https://www.cnblogs.com/delphi-xe5/p/12244569.html

时间: 2024-10-01 19:07:17

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

3D图形学在游戏开发中的,矩阵,四元数,欧拉角之间的底层转换算法。

在游戏开发的过程中难免会遇到欧拉角和四元数直接的转换问题,如果有些过shader的朋友,肯定也遇到过四元数,欧拉角和矩阵直接的转换问题,这里我把这几种格式直接的转换算法写在这里有需要的朋友可以拿去有,别忘了,点赞关注.废话不多说,直接上代码. 四元数转矩阵的底层算法: public Quaternion QuaternionMatrix(float w, float x, float y, float z) { Matrix4x4 matrix = new Matrix4x4(); matrix

java整型数与网络字节序的 byte[] 数组转换关系

java整型数与网络字节序的 byte[] 数组转换关系 工作项目需要在java和c/c++之间进行socket通信,socket通信是以字节流或者字节包进行的,socket发送方须将数据转换为字节流或者字节包,而接收方则将字节流和字节包再转换回相应的数据类型.如果发送方和接收方都是同种语言,则一般只涉及到字节序的调整.而对于java和c/c++的通信,则情况就要复杂一些,主要是因为java中没有unsigned类型,并且java和c在某些数据类型上的长度不一致. 本文就是针对这种情况,整理了j

android那些事之Bitmap、InputStream、Drawable、byte[]、Base64之间的转换关系

1 // 将Bitmap转换成InputStream(压缩率quality.100表示不压缩.10表示压缩90%) 2 public InputStream Bitmap2InputStream(Bitmap bm, int quality) { 3 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 4 bm.compress(Bitmap.CompressFormat.PNG, quality, baos); 5 InputSt

Docker误区+技巧+转换关系

Docker误区+技巧+转换关系 1. 误区:容器重启或者机器重启会丢失容器内的数据 根据https://docs.docker.com/faq/上的问答和本人的实践,在docker容器内创建文件和安装软件,做下面的操作都不会丢失数据和软件:A. exitsudo docker start b430d6f4ff00 B. sudo docker stop b430d6f4ff00sudo docker start b430d6f4ff00 C. reboot host https://docs.

PCB 奥宝LDI 输出正负片转换关系

今天继续对P2 奥宝LDI改造,在文件输出的时候遇到了一个正负片转换问题,研究了半天一直没有得到解决, 回来后前前后后整理今天参数输出与输出的关系,最终还梳理清楚了, 今天小结:一项技术只要用心去研究,最终可以透彻;回头来看也不过如此.哈哈 这边将奥宝LDI 输出正负片转换关系整理如下;      留个记号 原文地址:https://www.cnblogs.com/pcbren/p/9326373.html

matlab练习程序(求向量间的旋转矩阵与四元数)

问题是这样,如果我们知道两个向量v1和v2,计算从v1转到v2的旋转矩阵和四元数,由于旋转矩阵和四元数可以互转,所以我们先计算四元数. 我们可以认为v1绕着向量u旋转θ?角度到v2,u垂直于v1-v2平面. 四元数q可以表示为cos(θ/2)?+sin(θ/2)?u,即:q0?=cos(θ/2)?,q1?=sin(θ/2)?u.x,q2=sin(θ/2)?u.y,q3=sin(θ/2)?u.z 所以我们求出u和θ/2即可,u等于v1与v2的叉积,不要忘了单位化:θ/2用向量夹角公式就能求. ma

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

//欧拉角转四元数 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

关于旋转矩阵欧拉角的理解和基础

描述四轴的姿态不是我们作为旁观者那样简单,而需要站在机器的角度去看,假设现在只能通过陀螺仪获取.那么怎么去获取飞行器的姿态了? 要了解当前的姿态,就需要两个坐标系,只有知道了两个坐标系的相对位置才能了解空间中真正的位置. 一个就是相对不变的 空间参考系S 和 跟随刚体一起运动的 附体参考系B.那么我们干才的姿态问题就变为了解刚体的取向问题了, 在这个问题中就涉及到两个坐标系之间的转换,这里的原理其实和我昨天提到的向量的旋转是类似的. 1.那么什么是空间坐标系S ,什么又是附体参考系B 了? 假如

字典、列表、字符串转换关系

python 列表转为字典的两个小方法 1.现在有两个列表,list1 = ['key1','key2','key3']和list2 = ['1','2','3'], 把他们转为这样的字典:{'key1':'1','key2':'2','key3':'3'} >>>list1 = ['key1','key2','key3'] >>>list2 = ['1','2','3'] >>>dict(zip(list1,list2)) {'key1':'1','