Unity 3D中欧拉角与四元数关系的研究
- 格式:pdf
- 大小:686.79 KB
- 文档页数:6
Unity 笔记向量的减法unity旋转的方式:1、欧拉角:沿自身角度旋转的度数unity欧拉角其实是四元数2、四元数:(1,1,1,1)Transform 组件作用:1、控制游戏对象的变换位置旋转缩放2、维持父子关系脚本组件:(添加到游戏对象上以实现用户自定义的一些功能)1、自动继承MonoBehaviour类2、类名必须与脚本名一致3、transform.parent; 获取/重新指定当前游戏对象父对象的transform组件4、transform.root; 获取当前游戏对象的根父对象5、transform.Find(”Cube“); 获取当前游戏对象叫做Cube的对象6、transform.FindChild(“Cube”); 获取当前游戏对象叫做Cube的对象,如果多个默认返回第一个7、transform.Position:世界坐标系中的位置8、transform.locaPosition:局部坐标系中的位置9、transform.rotation; 世界坐标系中的位置四元数10、transform.localRotation; 局部坐标系中的位置四元数11、transform.localScale; x,y,z轴缩放比例操作12、transform.Translate;对象的位置移动操作13、transform.Rotate; 对象的轴旋转操作14、transform.eulerAngles=new Vector3(0f,45f,0f); 欧拉角- 属性回调方法Unity C#脚本默认方法继承MonoBehaviour被叫做运行时类,运行时不能手动实例化public class hello : MonoBehaviour //默认继承MonoBehaviour 类{// Use this for initialization //在游戏开始的第一帧运行一次void Start(){}// Update is called once per frame //每一帧调用一次void Update(){}}Unity脚本生命周期系统自带9 个回调方法这写方法都不是MonoBehaviour中定义的方法,而是通过反射调用的一些事件一:游戏开始的第一帧执行一次的方法:Awake:在游戏开始的第一帧执行一次,你的脚本组件无论是可用还是不可用,它都会执行,在Awake中做一些初始化操作On Enable:当脚本组件激活的时候执行一次被调用Update之前调用一次Start,做一些初始化操作,初始化public成员Fixed Update:每0.02秒执行一次,固定时间间隔默认0.02秒调用,一般我们会把处理物理的代码放在这里Update:每帧执行一次,执行的次数取决于计算机的配置(用于写人物移动逻辑)(用于写摄像机移动逻辑),在Update方法调用完之后调用OnGUI方法中每帧执行两次,游戏开始到结束持续执行On Disable:当脚本组件处于不可用状态的时候执行一次,取消激活状态后调用On Destroy:当脚本组件被销毁时,执行一次常用调式方法:1、Print() 属于MonoBehaviour类的成员2、DEbug.Log () 独立,密封的类常用调式方法Ctrl+shift+N 新建空物体Debug.DrawLine() 创建一条射线//画一条射线Debug.DrawRay(new Vector3(0,0,0),new Vector3(0,0,1),Color.red);设置脚本执行顺序:Edit - Project Settings - Scripe Execution OrderUnity自身也有一个object类常用类一、Game Object 游戏对象类01:gameObject this. 获取当前脚本所挂载的游戏对象,在属性面板中能够修改的组件都能通过脚本进行修改获取1、gameObject.activeSelf:游戏对象激活状态2、gameObject:表示当前脚本组件所挂载的游戏对象,返回true或false3、gameObject.SetActive(false):设置游戏对象的激活状态4、; 表示游戏对象的名称5、gameObject.tag; 表示游戏对象的标签6、yer; 表示游戏对象的层7、GameObject.Find("Main Camera");通过游戏对象的名称进行查找,返回的是一个游戏对象8、GameObject.FindWithTag("Player");通过游戏对象的标签查找游戏对象,返回一个游戏对象9、GameObject.FindGameObjectsWithTag("Hot"); 通过游戏对象的标签查找多个游戏对象,返回一个游戏对象数组10、gameObject.AddComponent<>(); 给游戏对象添加指定类型的组件11、GameObject.Destroy(gameObject); 立刻销毁游戏对象12、GameObject.Destroy(gameObject,5f); 延时销毁游戏对象 float类型的参数销毁当前脚本所挂载的游戏对象获取组件的方法:普通的成员方法// 1 找到摄像机对象声明一个对象进行接收GameObject camera = GameObject.FindWithTag("MainCamera");//2 找到摄像机身上的组件 <>表示得到组件的类名称无参数,小括号float dp = camera.GetComponent<Camera>().depth;//打印结果Debug.Log(dp);//找到Cube 输出位置坐标Vector3 pos = GameObject.Find("Cube").GetComponent<Transform>().position;Debug.Log(pos);transform:表示当前游戏组件所挂载的游戏对象身上的Transform组件this.GetComponent<GameObjectClass>();获取当前游戏对象身上的组件对于父物体与子物体的坐标位置,子物体分别有相对于父物体的世界坐标点与自己的坐标点//让物体产生移动transform.position+=new Vector3(0,0,0.01f); //每秒走0.01秒transform.Translate(new Vector3(0, 0, 0.01f));//与上一个一样的效果//让物体产生旋转transform.Rotate(new Vector3(1, 0, 0)); //让物体每帧延x轴转1度transform.eulerAngles += new Vector3(0, 0, 2);//与上一个一样的效果//绕着一个物体旋转transform.RotateAround(new Vector3(0,0,0),new Vector3(0,1,0),50 );星球的自转与公转publicclass StarRun : MonoBehaviour{//星球的直径publicfloat radius = 0.5f;//星球的材质颜色public Color color;//星球自转的速度publicfloat rotationSpeed = 3f;//星球的公转速度publicfloat rotationAroundSpeed = 3f;//公转所绕行的星球public Transform aroundPoint;void Start(){//设置球体半径,半径为1的时候*半径*2等于直径transform.localScale = Vector3.one*radius*2;//星球的材质,设置球体的颜色GetComponent<MeshRenderer>().material.color = color;}void Update(){Rotation();AroundRotation();}///<summary>///自转///</summary>void Rotation(){//设置星球的自转transform.Rotate(Vector3.up*rotationSpeed);}///<summary>///公转///</summary>void AroundRotation(){//设置星球的公转,位置,方向,速度transform.RotateAround(aroundPoint.position, Vector3.up, rotationAroundSpeed); }}坦克发射子弹1:publicclass FireMoeBullet : MonoBehaviour{//Bullet预设体public GameObject bullet;void Update(){Fire();}//子弹Bullte发射的方法void Fire(){if (Input.GetMouseButtonUp(0)) //如果按下了鼠标左键{//通过预设体在炮筒方向生成一个子弹bullet,强制转换GameObject currentBullet = (GameObject) Instantiate(bullet, transform.GetChild(3).position, Quaternion.identity); //给子弹一个方向currentBullet.GetComponent<MoveBullte>().dir = transform.forward;}}}2:publicclass MoveBullte : MonoBehaviour{//bullet移动publicfloat moveSpeed = 10f;publicfloat deadTime = 3f;public Vector3 dir;void FixedUpdate(){//定时销毁当前子弹对象Destroy(gameObject, deadTime);}void Update(){//子弹移动transform.position += dir*moveSpeed*Time.deltaTime;}}二、Input类获取用户事件时使用一般都写在Update 方法中0表示左键,1表示右键,2表示中键滚轮【一Mouse方法鼠标】1、GetMouseButtonDown(0) 获取鼠标按下的事件2、GetMouseButton(1) 获取鼠标持续按下的事件3、GetMouseButtonUp(2) 获取鼠标弹起的事件4、fieldOfView=60 视野角度【二GetKey方法键盘】1、GetKey(KeyCode.W) 获取按键持续按下的事件2、GetKeyDown(KeyCode.W) 获取按键按下的事件3、GetKeyUP(KeyCode.W) 获取按键弹起的事件4、如果一个值类型常量为公有的,那么unity脚本面板比脚本文件拥有更大的优先级。
在Unity 3D中,实现物体旋转有多种方式,如旋转矩阵、欧拉角和四元数等[1]。
旋转需要两个基本参量轴和角,物体从一个方位旋转到另一个方位可以采用多次改变轴和角的方式,依次旋转。
其中,有一种旋转方式是只绕一个轴旋转一次就能达到指定方位,且旋转角度在﹣180°~180°之间,称这样的旋转方式为最短旋转。
任意指定两个方位,要找出其中的最短旋转并不是一件容易的事。
本文将给出最短旋转的数学描述以及在Unity 3D中实现最短旋转的方法。
最短旋转的数学描述刚体的运动包括平动和转动。
描述刚体的空间位置,用三维空间坐标点(x,y,z)表示,在Unity 3D中有3个基本坐标系,分别是世界坐标系、惯性坐标系与本地坐标系。
相应的,描述刚体的旋转状态,即方位,是本地坐标系与惯性坐标系所形成的角度变化,采用欧拉角来描述。
由于本文不涉及平移,因此为方便讨论,将惯性坐标系和世界坐标系重合。
众所周知,“两点之间线段最短”,同样两个方位之间也存在类似的关系,即最短旋转,两点之间的距离用两点位置之差来描述。
相应的,两个方位之间的最短旋转用两个方位的四元数之比来描述。
如果方位a的四元数为q1,方位b的四元数为q2,刚体从方位a旋转到方位b的最短旋转的四元数为q,则q = q2÷q1。
设四元数q的4个分量分别是(x,y,z,w),该四元数隐含了旋转轴向量n和旋转角d,设轴向量n 的3个分量为(nx,ny,nz)。
一般将轴n和角d写成“轴角对”的形式,即(n,d)=(nx,ny,nz,d )。
四元数q=(x,y,z,w)与轴角对(n,d)=(nx,ny,nz,d )之间的关系为:q = (x,y,z,w) = (nx*sin(d/2),ny*sin(d/2),nz*sin(d/2),cos(d/2))在Unity 3D中,改变欧拉角和改变四元数是两种基本的旋转方式,Unity 3D提供了Lerp和Slerp 两种插值函数,在两个方位之间进行采样插值。
四元数和欧拉角的关系四元数和欧拉角的关系一、四元数四元数是一种数学结构,用来表达旋转运动。
一个四元数通常由一个实部和三个虚部构成,可以表示为:q=a+bi+cj+dk其中,a是实部,b、c、d是虚部,i、j、k是虚数单位。
二、欧拉角欧拉角是一种常用的旋转表达方法,常用于描述物体的朝向和旋转。
欧拉角可以分为三个分量,分别是绕x轴的旋转角度、绕y轴的旋转角度和绕z轴的旋转角度。
三、四元数和欧拉角的转换关系四元数和欧拉角之间存在一种转换关系,可以互相转换。
下面分别介绍四元数转欧拉角和欧拉角转四元数的计算方法。
1. 四元数转欧拉角四元数转欧拉角的计算方法如下:首先,计算旋转矩阵R,通过四元数的实部和虚部计算得到:R =(1−2c 2−2d 22bc −2ad 2bd +2ac 2bc +2ad 1−2b 2−2d 22cd −2ab 2bd −2ac 2cd +2ab 1−2b 2−2c 2)然后,通过旋转矩阵R 求解得到对应的欧拉角,具体计算方法略。
2. 欧拉角转四元数欧拉角转四元数的计算方法如下:首先,通过欧拉角计算旋转矩阵R ,具体计算方法略。
然后,根据旋转矩阵R 计算得到对应的四元数,具体计算方法略。
四、总结四元数和欧拉角是描述旋转运动的两种常用方法,它们之间存在一种转换关系。
通过四元数可以计算得到对应的欧拉角,通过欧拉角也可以计算得到对应的四元数。
在具体应用中,我们可以根据需要选择合适的表达方法来描述旋转运动。
1. 四元数转欧拉角四元数转欧拉角的计算方法如下:首先,计算旋转矩阵R ,通过四元数的实部和虚部计算得到:R =(1−2c 2−2d 22bc −2ad 2bd +2ac 2bc +2ad 1−2b 2−2d 22cd −2ab 2bd −2ac 2cd +2ab 1−2b 2−2c 2)然后,通过旋转矩阵R 求解得到对应的欧拉角。
一个常用的方法是使用反正切函数和反正弦函数来计算角度,具体计算方法如下:• 绕x 轴的旋转角度(俯仰角):θx =atan2(2(bc +ad ),1−2(b 2+c 2))• 绕y 轴的旋转角度(偏航角):θy =asin(2(bd −ac )) • 绕z 轴的旋转角度(翻滚角):θz =atan2(2(cd +ab ),1−2(c 2+d 2))2. 欧拉角转四元数欧拉角转四元数的计算方法如下:首先,通过欧拉角计算旋转矩阵R 。
3D图形:矩阵、欧拉角、四元数与方位的故事概述又研究了将近两个星期的3D图形到了我最想研究的地方了,因为欧拉角与四元数的原因导致OpenGL ES的研究进度变缓,研究完这一块,我将教大家如何使用OpenGL ES做一个自转加公转的正立方体.效果如下.方向、方位与角位移的区别在说矩阵、欧拉角与四元数三种与角位移的关系之前,我们先来说说方向、方位与角位移的区别.在现实生活中,我们很少区分"方向"和"方位"的区别(非路痴观点),比如一个朋友来看望你,但是他可能在某一个公交站下车了,你去接他,但是找不到他,你急忙给他来一个电话"兄弟,你在哪个方向呢?"或者说是"兄弟,你在哪个方位呢?",如果不细细品味这两句话,其实感觉差异不是太大.通过一痛电话的扯,然后你们成功的面基了,但是你们却并不会在意"方向"和"方位"的区别.那么在几何中,这两者到底有什么差异呢?这里我就盗用一下书上的例子,比如一个向量如果沿着自己的方向选择是不会改变自身任何属性的,如下图所示,因为向量是只有方向没有方位的.那么对于一个物体,情况却是不一样的,一个物体如果朝向某一个方向的时候,然后自转,那么这个物体是会发生空间上的改变的,如下图一个锥体的自转,那么它的空间位置是发生改变的,也就是锥体的方位发生了改变了.上面让我们对物体的方向和方位的区别有了一个大体上的了解,那么我们在空间中如何描述一个方位呢?这就需要使用到角位移了.我们先说一个类似的例子,我们该如何描述空间中一个物体的位置呢?必须要把物体放在特定的坐标系中(好像很生涩).比如,如果我们说在一个坐标系中,有一个点是[1,1,1],那么你会非常轻易的想到了这个点在空间中的位置.描述空间位置其实就是描述相对于给定参考点(坐标原点)的位移.其实,描述一个物体的方位是一样的,我们是不可能凭空描述一个物体的方位,我盟需要一个已知方位的参考量,通过这个参考量的旋转得到当前方位,那么旋转的量就叫做角位移.通过概念我们知道,角位移就是用来描述方位的,类似于速度就是用来描述物体运动快慢的一样.当然了,这里我要声明的一点就是虽然角位移是用来描述方位的,但是两者是不同的.例如,我们可以这么说,一个物体的方位是如何如何的;一个物体是通过某个已知方位经过角位移XXX旋转得到.所以说,方位是用来描述一个单一的"状态".但是角位移是用来描述两个状态之间的差异.那么,我们在实际中如何描述方位与角位移呢?具体而言,我们使用矩阵和四元数来表示"角位移",用欧拉角来表示方位.接下来,我们逐一介绍一下.使用矩阵表示角位移在3D环境中,描述坐标系中方位的方式就是列出这个坐标系的基向量,当然了,这些基向量是用其他表示的,并不是它本身的基向量,比如当前转换完成的坐标系的三个基向量p [1,0,0] q[0,1,0] r[0,0,1],这是使用本身的坐标系表示,如果放在其他坐标系中表示当前的三个基向量可能就会发生改变.这是因为参照点选择的不同.至于基向量是如何改变的就需要在3D图形:矩阵与线性变换说过的旋转矩阵的相关知识了.这个就不过多的解释了.比如下图,由向量p,q,r组建的新的坐标系用原来的坐标系表示确实如图右边所示.其实对于我们开发来说,我们只需要知道方位是可以使用3X3矩阵来表示的.矩阵表示的是转换后的基向量即可.接下来我们说一下使用矩阵来表示角位移有什么样的优势和缺点.我就直接拿书上所讲的了,各位看官莫怪莫怪.使用矩阵表示角位移的优势•可以立即进行向量的旋转.后面使用四元数进行空间变化其实是和使用对应的矩阵的空间变化的效果是一样的.•矩阵的形式被图形API所使用.这一点我们从OpenGL ES 就可以看出来了,无需过多解释了.•多个角位移连接.我们知道使用矩阵进行空间变换是可以连续进行多个的.那么角位移也是一样的.•矩阵的逆.这个比较好理解,如果我们进行了一次旋转变换(也就是空间方位的变化),那么如何回到原来的方位呢,只要再乘上一次矩阵的逆即可,前面说过矩阵的逆是有这样的功能的.使用矩阵表示角位移的缺点•矩阵可能占有更多内存.这其实是由比较性的,这种比较是要与欧拉角做比较,与欧拉角比较矩阵所占的内存将会更多.•难以使用.这个确实是,你想想,如果现在你要x轴旋转80°,你还要想想它对应的向量是多少.一痛计算之后,才能得到对用的值,后面直接看到这个矩阵的时候还要接着计算,看看它是如何变换的.这样使用起来是不是非常的恶心?•并非所有矩阵都能描述方位.这一点,我将单独写一篇来讨论这个问题.现在还不是太了解,见谅.当然了,我们使用矩阵来表示角位移只是作为了解而已,接下来,我们看一下如何使用欧拉角表示方位的.欧拉角表示方位与万向锁问题很多人在大学中可能会接触到矩阵,但是欧拉角可能是接触的比较少,最少作为一个学物理的我是这样的.一开始觉得欧拉角比较难理解,但是看了3D图形之后,发现用欧拉角表示方位将会比矩阵更加的直观而且易于使用.下面我们就看一下欧拉角相关的知识.(下面的基本概念跟书上的差不多,因为我觉得书上写个就很好了,所以我就没有再次总结,所以只是写了一遍.)首先,欧拉角的基本思想是将角位移分解为绕三个互相垂直轴的三个旋转组成的序列.那么这个三个互相垂直的轴是如何定义的呢?其实任意三个轴和任意顺序都是可以的,但是最常用的就是使用笛卡尔坐标系并且按照一定顺序组成的旋转序列.最常用的约定,就是所谓的"heading-pitch-bank"约定,在这个系统中,一个方位被定义为heading角,一个pitch角,一个bank角.其中,在左手坐标系中,我们把heading角定义为绕y轴旋转量,pitch角为绕x轴旋转量,bank角为绕z轴旋转量.旋转法则遵守左手法则(具体请参考3D图形:矩阵与线性变换中的旋转模块).它的基本思想是让物体开始于"标准"方位,就是物体坐标轴和惯性坐标轴对齐.让物体做heading、pitch、bank旋转之后达到最终的空间方位.例如下图一个锥体,一开始它自身坐标轴与惯性坐标轴是一致.然后我把heading角设置为45°.根据左手法则(通常使用,但是决定每个旋转的正方向不一定要准守右手或者左手定则),它是会做顺时针旋转.接着物体的坐标系就发生如下的改变了.锥体的自身坐标轴不再与惯性坐标轴一致,x,z轴都发生了对应的改变.当然了,物体的空间方位也发生了对应的改变.然后接下来就是pitch、bank旋转,分别是绕x轴旋转和z轴旋转,跟heading旋转是类似的,最后得到锥体的最终的空间方位.这里需要注意的是不管是 heading旋转、 pitch旋转还是bank旋转,旋转的坐标轴都是自身的坐标轴!不是惯性坐标轴!上面,看完了"heading-pitch-bank"约定系统是如何做空间方位的旋转改变的,接下来,我们来瞅瞅关于欧拉角的其他约定.•"heading-pitch-bank"约定系统是有多个名字的,其中的有一组叫做"roll-pitch-yaw",其中roll等同于bank,yaw等价于heading.我们知道"heading-pitch-bank"约定是让方位从惯性坐标系到最终的物体自身坐标系,但是"roll-pitch-yaw"约定却是刚好相反.它是从最终的物体坐标系到最开始的惯性坐标系的旋转变换.•任意的三个轴都能作为旋转轴,但是使用笛卡尔坐标轴是最有意义的,这句话我就不过多解释了,我们在上面的例子中已经深有体会了.•决定每一个旋转的正方向不一定必须遵守左手或者右手法则,这样遵守只是习惯而已.•旋转是可以以不同的顺序进行的,"heading-pitch-bank"约定系统只是更比较如何人的习惯而已.因为一个物体放在一个水平面上,如果进行旋转操作的话,我们首先想到的是物体按照垂直轴进行旋转操作.也就是heading旋转.上面我们对欧拉角的接下来,我们看一下欧拉角的优点和缺点.透露一点,其实欧拉角的缺点就是引起万向锁的原因.欧拉角表示方位的优点•欧拉角使用起来非常的简单方便,它比四元数以及矩阵更加的生动形象.因为欧拉角使用都是角度,对于人来说旋转还是使用角度比较直观.•最简洁的表达方式.在3D中,欧拉角用3个数就可以表达方位,四元数则要用4个数,而矩阵是最多的,需要9个数.•任意三个数都是合法的,任意的三个数都是能构成合法的欧拉角,矩阵和四元数可不一定是这样的.欧拉角表示方位的缺点•给定的方位表达方式不唯一.我们虽然说任意三个数组成的欧拉角都是合法的,但是比如heading旋转360°和选择720°,物体的方位是一直的,虽然欧拉角的数值是发生了改变的.•两个角度求插值非常的困难.比如方位A的heading角度为720°,方位B的角度为45°.那么heading值差了多少呢?没错就是45°,因为720°就是旋转了两周而已,但是实际上我们操作的时候需要选择将近两周.如下图所示.万向锁问题其实是使用欧拉角会出现一个非常有趣的现象,那就是万向锁,我们看一下"heading-pitch-bank"系统这个系统中,如果pitch角度为±90°,那么就出事了,会出现什么问题呢?heading角与bank角如果相同,那么你会发现物体最终的方位是一致的,这怎么可能,这就比较尴尬了,其实类似于这种旋转pitch角度为±90°中,物体是缺失一个旋转轴的.也就是说,当pitch角度为±90°,那么bank是0.只有heading一个旋转轴起作用,是不是懵圈了?没问题,下面我要分享一个视频,我觉得这个视频会比文字更加生动形象,请对照上面的文字自行研究.欧拉旋转—万向节锁视频传送门四元数与复数看完使用矩阵和欧拉角表示方位.接下来,我们就看一下四元数,四元数一个新的概念出现在我的眼前的时候我在想,他否是因为有四个数才叫四元数,确实,四元数实际是一个标量分量和一个3D向量分量组成用来表示方位.四元数的两种记法如下所示:[ω,ν],[ω,(x,y,z)].复数,真心好久没用了.高中的时候我们就开始接触简单的复数了,现在简单说一下复数,其实我也顺道复习一下了.首先,复数的形式为a+bi,其中i²=-1,a称作实部(实数部分),b称作虚部(虚数部分).对于复数的运算,我们主要说说复数的模,复数的模可以很好的表示2D中的旋转变换,我们先看看前面说到过的2D环境中的旋转矩阵.然后,我们再看一下,一个示例,假设一个复数v = (x,y)旋转θ度得到v',如下图所示.为了完成此次的旋转,我们需要引入第二个复数q = (cosθ,sinθ),现在旋转之后的复数v'就可以使用复数的乘法计算出来了.计算过程如下所示.v = x +yiq = cosθ +isinθv' = vq = (x +yi)(cosθ +isinθ) = (xcosθ-ysinθ)+(xsinθ+ycosθ)i跟上面的2D环境中旋转矩阵效果是一样的.只是形式不相同而已.上面说了这么一大堆,那么到底四元数和复数有着怎样的关系呢?其实一个四元数[w,(x,y,z)]定义了复数w +xi +yj +zk,也就是说一个四元数是包含着一个实部和三个虚部.其实四元数的出现也是有故事的,我直接把书上搬过来,当做在枯燥的学习中的一个轻松时刻吧(实际上,然并卵?),爱尔兰的数学家哈密尔顿其实一直想把复数复数从2D扩展到3D,一开始他认为,3D中的复数应该有一个实部和两个虚部,然后他没有创造出这种一个实部两个虚部有意义的复数.1843年,在他去演讲的路上他突然意识到应该有三个虚部而不是两个虚部.他把这种新复数类型行者的等式刻在了Broome桥上.这样四元数就诞生了.等式如下所示.i²= j²= k² = -1ij = k,ji = -kjk = i,kj = -iki = j,ik = -j四元数和轴-角对我们已经知道了矩阵和欧拉角的情况,现在我们就看一下四元数是如何表示角位移的.在3D环境中任意的一个角位移都可以理解为绕某个轴旋转一定的角度,在3D图形:矩阵与线性变换这个里面曾经说过一个3D中绕任意轴旋转的公式(还记得当初那个验证过程吗,愣是搞了一天,具体验证过程就不说了,请查看原来的文章).公式如下所示.其中,θ代表着旋转角度,n代表着旋转轴.因此轴-角对(n,θ)定义了一个角位移:绕n指定的轴旋转θ角.四元数的解释其实就是角位移的轴-角对方式,但是呢,n和θ并不是直接放入到四元数中的.它们的形式如下所示.q= [ cos (θ/2) sin(θ/2)n ]=[ cos(θ/2) ( sin(θ/2)nx sin(θ/2)ny sin(θ/2)nz ) ]那么问题来了,为什么不直接放入四元数中呢?这是有原因的,这个原因,我将会在下一篇四元数的相关运算中来说明一下.现在只要知道四元数的解释其实就是角位移的轴-角对方式即可.结束自己写完这篇文章总算是对矩阵、欧拉角、四元数、角位移、方位有了一个大体的了解了.整体下来发现真心枯燥的,但是还是坚持了下来了,希望小伙伴也能坚持看完,不懂的或者有疑问可以与骚栋一起探讨.3D图像下一篇我将接着研究本篇的四元数,不过是与四元数的运算相关的知识.希望大家持续关注.最后还是要附上<<3d数学基础>>的pdf版的传送门.<<3d数学基础>>传送门。
欧拉角速度与姿态四元数角速度的关系姿态控制是机器人领域中的重要问题之一,它涉及到机器人在空间中的姿态变化。
在姿态控制中,欧拉角和姿态四元数是常用的描述姿态的方法。
欧拉角由三个连续旋转角度组成,而姿态四元数是一种四维复数,它可以表示三维空间中的旋转。
欧拉角速度是指机器人在姿态变化过程中的角度变化速度。
它可以通过欧拉角的导数来计算。
而姿态四元数角速度是指机器人在姿态变化过程中的四元数变化速度。
它可以通过姿态四元数的导数来计算。
那么欧拉角速度与姿态四元数角速度之间有什么关系呢?下面我将详细介绍一下它们之间的关系。
我们来看欧拉角速度。
欧拉角速度的计算方法是将欧拉角分别对时间求导。
假设欧拉角分别为α、β、γ,对应的欧拉角速度分别为ωx、ωy、ωz。
那么欧拉角速度可以表示为:ωx = α'ωy = β'ωz = γ'其中,α'、β'、γ'分别表示α、β、γ的导数。
接下来,我们来看姿态四元数角速度。
姿态四元数的计算方法是将旋转轴和旋转角度转化为一个四元数。
假设姿态四元数为q = [qw, qx, qy, qz],对应的姿态四元数角速度为ω = [ωw, ωx, ωy, ωz]。
那么姿态四元数角速度可以表示为:ωw = 0.5 * (ωx * qw + ωy * qz - ωz * qy)ωx = 0.5 * (ωy * qw - ωz * qx + ωw * qy)ωy = 0.5 * (ωz * qw + ωx * qy - ωw * qx)ωz = 0.5 * (-ωx * qz + ωy * qx + ωw * qz)其中,qw、qx、qy、qz分别表示姿态四元数的四个分量。
从上面的公式可以看出,姿态四元数角速度的计算涉及到姿态四元数和欧拉角速度的乘法和加法运算。
因此,欧拉角速度与姿态四元数角速度之间存在一定的关系。
总结起来,欧拉角速度与姿态四元数角速度之间的关系可以通过一系列的数学公式来表示。
ue欧拉角和四元数
欧拉角和四元数都是用于描述物体在三维空间中的旋转姿态的数学工具。
欧拉角是通过连续的旋转操作将一个物体从一个固定的坐标系转到另一个坐标系的方法。
它由三个角度组成,分别是绕X轴的旋转角度(俯仰角)、绕Y轴的旋转角度(偏航角)和绕Z轴的旋转角度(翻滚角)。
欧拉角的优点是简单直观,容易理解和计算。
然而,当连续旋转的操作次序发生变化时,会引入万向锁问题,导致计算结果出现不确定性。
四元数是一种复数扩展的数学工具,用于表示三维空间中的旋转。
它由一实部和三个虚部组成,实部表示旋转的角度,虚部表示旋转的轴向。
四元数的优点是在进行连续旋转计算时没有万向锁问题,且计算效率高。
然而,四元数的运算复杂度较高,对于直观理解和可视化展示不如欧拉角直观。
欧拉角和四元数在计算机图形学、机器人工程和飞行模拟等领域广泛应用。
根据具体的需求和应用场景,选择适合的旋转表示方法是很重要的。
四元数介绍旋转,应该是三种坐标变换——缩放、旋转和平移,中最复杂的一种了。
大家应该都听过,有一种旋转的表示方法叫四元数。
按照我们的习惯,我们更加熟悉的是另外两种旋转的表示方法——矩阵旋转和欧拉旋转。
矩阵旋转使用了一个4*4大小的矩阵来表示绕任意轴旋转的变换矩阵,而欧拉选择则是按照一定的坐标轴顺序(例如先x、再y、最后z)、每个轴旋转一定角度来变换坐标或向量,它实际上是一系列坐标轴旋转的组合。
那么,四元数又是什么呢?简单来说,四元数本质上是一种高阶复数(听不懂了吧。
),是一个四维空间,相对于复数的二维空间。
我们高中的时候应该都学过复数,一个复数由实部和虚部组成,即x = a + bi,i是虚数单位,如果你还记得的话应该知道i^2 = -1。
而四元数其实和我们学到的这种是类似的,不同的是,它的虚部包含了三个虚数单位,i、j、k,即一个四元数可以表示为x = a + bi + cj + dk。
那么,它和旋转为什么会有关系呢?在Unity里,tranform组件有一个变量名为rotation,它的类型就是四元数。
很多初学者会直接取rotation的x、y、z,认为它们分别对应了Transform面板里R的各个分量。
当然很快我们就会发现这是完全不对的。
实际上,四元数的x、y、z和R的那三个值从直观上来讲没什么关系,当然会存在一个表达式可以转换,在后面会讲。
大家应该和我一样都有很多疑问,既然已经存在了这两种旋转表示方式,为什么还要使用四元数这种听起来很难懂的东西呢?我们先要了解这三种旋转方式的优缺点:矩阵旋转优点:旋转轴可以是任意向量;缺点:旋转其实只需要知道一个向量+一个角度,一共4个值的信息,但矩阵法却使用了16个元素;而且在做乘法操作时也会增加计算量,造成了空间和时间上的一些浪费;欧拉旋转优点:很容易理解,形象直观;表示更方便,只需要3个值(分别对应x、y、z轴的旋转角度);但按我的理解,它还是转换到了3个3*3的矩阵做变换,效率不如四元数;缺点:之前提到过这种方法是要按照一个固定的坐标轴的顺序旋转的,因此不同的顺序会造成不同的结果;会造成万向节锁(Gimbal Lock)的现象。
四元数与欧拉角之间的转换在3D图形学中,最常用的旋转表示方法便是四元数和欧拉角,比起矩阵来具有节省存储空间和方便插值的优点。
计算公式常采用3D笛卡尔坐标系:图1 3D笛卡尔坐标系定义∅,φ,θ分别为绕Z轴、Y轴、X轴旋转角度,用Tait-Bryan angle表示,分别为yaw(偏航角),pitch(俯仰角),roll(横滚角)。
图2 Tait-Bryan angles1 3D笛卡尔坐标系三维空间过定点O,作三条互相垂直的数轴,它们都以O为原点且一般具有相同的长度单位。
这三条轴分别叫做x轴(横轴)、y轴(纵轴)、z轴(竖轴);统称坐标轴。
通常把x轴和y轴配置在水平面上,而z轴则是铅垂线;它们的正方向要符合右手规则,即以右手握住z轴,当右手的四指从正向x轴以π/2角度转向正向y轴时,大拇指的指向就是z轴的正向,这样的三条坐标轴就组成了一个空间直角坐标系,点O叫做坐标原点。
这样就构成了一个笛卡尔坐标。
2 四元数(Quaternions)的定义四元数由四部分(一个实部,三个虚部)组成,三个虚部与旋转轴密切相关,而旋转角度影响四部分。
q=[ωx y z]T|q|2=ω2+x+y2+z2=1ω=cos(α2⁄)x=sin(α2⁄)cos(βx)y=sin(α2⁄)cos(βy)x=sin(α2⁄)cos(βz)其中α是绕旋转轴旋转的角度,cos(βx),cos(βy),cos(βz)为旋转轴在x,y,z方向的分量(由此确定的旋转轴)。
3 欧拉角到四元数的转换q =[ωx y z ]=[ cos(φ2⁄)cos(θ2⁄)cos (∅2⁄)+sin(φ2⁄)sin(θ2⁄)sin(∅2⁄)sin(φ2⁄)cos(θ2⁄)cos(∅2⁄)−cos(φ2⁄)sin(θ2⁄)sin(∅2⁄)cos(φ2⁄)sin(θ2⁄)cos(∅2⁄)+sin(φ2⁄)cos(θ2⁄)sin(∅2⁄)cos(φ2⁄)cos(θ2⁄)sin(∅2⁄)−sin(φ2⁄)sin(θ2⁄)cos(∅2⁄)]4 四元数到欧拉角的转换[φθ∅]=[tan −12(ωx +yz)1−2(x 2+y 2)sin −1(2(ωy −zx))tan −1(2(ωz +xy)1−2(y 2+z 2))] 5 转换坐标系后,从四元数到欧拉角的求法在其他坐标系下,需根据坐标轴的定义,调整以上公式。
四元数和欧拉角的关系(一)
四元数和欧拉角的关系
什么是四元数和欧拉角
•四元数(Quaternions)是一种数学对象,常被用来表示三维空间中的旋转。
•欧拉角(Euler Angles)是一种旋转描述方法,通过三个角度来表示三维空间中的旋转。
四元数和欧拉角的对应关系
•四元数可以通过欧拉角进行转换,而欧拉角也可以通过四元数进行转换。
•欧拉角可以分为三个轴的旋转,分别是绕X轴、Y轴和Z轴旋转。
•四元数可以用一个实数部分和三个虚数部分表示,分别代表旋转角度和旋转轴的坐标。
四元数转换为欧拉角
•将四元数转换为欧拉角需要使用三角函数进行计算。
•首先,通过四元数的实数部分计算旋转角度。
•然后,通过四元数的虚数部分计算旋转轴的坐标。
•最后,将旋转角度和旋转轴的坐标表示为欧拉角形式。
欧拉角转换为四元数
•将欧拉角转换为四元数也需要使用三角函数进行计算。
•首先,将欧拉角的三个角度转换为弧度。
•然后,使用三个旋转角度计算旋转轴的坐标。
•最后,将旋转角度和旋转轴的坐标表示为四元数形式。
四元数和欧拉角的应用
•四元数和欧拉角在计算机图形学中广泛应用,可以描述物体的旋转。
•四元数在三维游戏开发中被广泛使用,可以实现平滑的旋转效果。
•欧拉角在飞机、机器人等领域中被使用,可以方便地表示飞行姿态。
总结
•四元数和欧拉角是描述三维空间中旋转的方法。
•四元数可以通过欧拉角转换,欧拉角也可以通过四元数转换。
•四元数和欧拉角在计算机图形学和其他领域中具有广泛的应用。