【Unity】Unity 欧拉角、四元数、万向节死锁、四元数转轴角


欧拉角(Euler)

什么是欧拉角?百科上是这样解释的:用来确定定点转动刚体位置的3个一组独立角参量,由章动角θ、旋进角(即进动角)ψ和自转角φ组成,为欧拉首先提出而得名。
在这里插入图片描述
很难理解吧?其实我们没有必要把欧拉角想得太复杂。

对于开发者来说,欧拉角就是用一个Vector3变量来记录物体沿着x、y、z轴的旋转。注意,虽然这是一个Vector3变量,但它并不是向量,这个变量的x、y、z三个分量是用来描述旋转的。

欧拉角特点:

  • 使用3个角度来保存方位。
  • x 与 z沿自身坐标旋转,y 沿世界坐标旋转。
  • API:Vector3 eulerAngle = this.transform.eulerAngles;

万向节

万向节,也叫平衡环架(Gimbal),具有枢纽的装置,使得一物体能以单一轴旋转。由彼此垂直的枢纽轴所组成的一组三只平衡环架,则可使架在最内的环架的物体维持旋转轴不变。常常应用于船上的陀螺仪、罗盘、饮料杯架等。
在这里插入图片描述

在飞行器的航行中,进行XYZ三个方向旋转的旋转有专业的术语,见下图:
在这里插入图片描述
沿着机身右方轴(Unity中的+X)进行旋转,称为pitch,中文叫俯仰。
沿着机头上方轴(Unity中的+Y)进行旋转,称为Yaw,中文叫偏航。
沿着机头前方轴(Unity中的+Z)进行旋转,称为Roll,中文叫桶滚。

欧拉角旋转特性

欧拉角的旋转就是沿着万向节的轴旋转的。目前人类最常用也最容易理解的方式是先沿着X轴旋转,再沿着Y轴旋转,最后沿着Z轴旋转,最后达到目标旋转角度。如下图所示:
请添加图片描述

这时候可能就有人会有疑问了,为什么不能三个轴同时旋转呢?
实际上,如果三个轴同时旋转,将会无法达到你预期的旋转效果。为什么呢?因为物体是一个整体,当某一个轴进行旋转时,其他的轴是跟着物体一起动的,如果还是按照原来的旋转角度旋转则会随着其他轴的转动形成偏移,如下图所示:
在这里插入图片描述
我们想要的其实只是让箭头指向我们,但三个轴同时旋转却使这个旋转轨迹划出了一个不应该有的弧线。

所以我们要了解的是,欧拉旋转是一定要有顺序的。这样的问题其实是无法避免的,但是我们可以根据物体的旋转情况对此进行优化,这个优化的方法就是给三个轴指定一个新的层级顺序。
在这里插入图片描述
当然这并不是真正的解决了问题,只是尽量避免了问题而已。欧拉角的问题是无法彻底解决的,

欧拉角优点

  • 仅使用三个数字表达方位,占用空间小。
  • 沿坐标轴旋转的单位为角度,符合人类思考方式。
  • 任意三个数字都是合法的,不存在不合法的欧拉角。

欧拉角缺点

方位的表达方式不唯一

对于一个方位,存在多个欧拉角描述,因此无法判断多个欧拉角代表的唯一是否相同。

例如:

  • 角度 0, 5, 0 与角度 0, 365, 0
  • 角度 0, -5, 0 与角度 0, 355, 0
  • 角度 250, 0, 0 与角度 290, 180, 180

为了保证任意方位都只有独一无二的表示,Unity引擎限制了角度范围,即沿x轴旋转限制在 -90 ~ 90 之间,沿 y 与 z 轴旋转限制在 0 ~ 360 之间。

万向节锁(Gimbal Lock)

当物体沿 x 轴旋转   ± 90 ° \ \plusmn 90°  ±90° ,自身坐标系z轴与世界坐标系y轴将重合,此时再沿y轴或z轴旋转时,将会失去一个自由度。
请添加图片描述
Unity的优化方案:在万向节死锁的情况下,规定沿z轴完成绕竖直轴的全部旋转,即此时y轴旋转为0。

关于万向节锁的讲解视频:https://v.youku.com/v_show/id_XNjk1MTkzMTM2.html#paction

在使用欧拉旋转的情况下,万向节锁的情况是无法避免的,为了更好的表示旋转,Unity引入了四元数的概念。

四元数(Quaternion)

四元数在3D图形学中代表旋转,由一个三维向量 / [ x , y , z ] / [x, y, z] /[x,y,z] 和一个标量 / w / w /w 组成。

旋转轴为 V V V ,旋转弧度为 θ \theta θ ,若使用四元数表示,则四个分量为:
x = S i n ( θ / 2 ) ∗ V . x y = S i n ( θ / 2 ) ∗ V . y z = S i n ( θ / 2 ) ∗ V . z w = C o s ( θ / 2 ) x = Sin(\theta / 2) * V.x \\ y = Sin(\theta / 2) * V.y \\ z = Sin(\theta / 2) * V.z \\ w = Cos(\theta / 2) x=Sin(θ/2)V.xy=Sin(θ/2)V.yz=Sin(θ/2)V.zw=Cos(θ/2)
四个分量的值都在 -1 到 1 之间。

几何应用:四元数与向量相乘,可以实现向量的旋转。

代码:

// 获取四元数
Quaternion qt = this.transform.rotation;

// 使用四元数做旋转
this.transform.rotation = Quaternion.Euler(0, 50, 0);

// 或者调用Rotation方法实现旋转
this.transform.Rotation(0, 50, 0);

四元数旋转角度相加需要用 * 乘法,而不是加法。

四元数转轴角

Transform 中的 rotation 使用的是四元数,有时我们需要获取 Transform 沿某一个轴旋转的角度,此时可以用下面的代码进行计算:


Quaternion q = transform.rotation;

// 计算X轴旋转角度
float angleX = 0;
float siny_cosp1 = 2 * (q.w * q.x + q.z * q.y);
float cosy_cosp1 = 1 - 2 * (q.y * q.y + q.x * q.x);
float radian1 = Mathf.Atan2(siny_cosp1, cosy_cosp1); // 求出弧度
angleX = radian1 * Mathf.Rad2Deg; // 转化角度
Debug.Log("=============" + angleX);

// 计算Z轴旋转角度
float angleZ = 0;
float siny_cosp2 = 2 * (q.w * q.z + q.x * q.y);
float  cosy_cosp2 = 1 -2 * (q.y * q.y + q.z * q.z);
float radian2 = Mathf.Atan2(siny_cosp2, cosy_cosp2); // 求出弧度
angleZ = radian2 * Mathf.Rad2Deg; // 转化角度
Debug.Log("=============" + angleZ);

上述方法适用于物体只在一个轴上做了旋转的情况,Y轴的计算方法以此类推。

四元数优点

避免万向节死锁,完全沿自身轴(而不是全局轴)旋转。

四元数缺点

难于使用,且存在不合法的数值。

Quaternion类

Unity中提供了Quaternion类来处理四元数相关操作,该类的使用方法可以参考我的另外一篇文章:【Unity】Unity常用类:向量Vector3、四元数Quaternion


本文万向节部分内容参考了塞北烟云大神的文章,地址如下:https://www.jianshu.com/p/9f45e91a2391

更多内容请查看总目录【Unity】Unity学习笔记目录整理

  • 4
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Unity 中的四元数欧拉角都是用来表示物体的旋转的数学概念。 四元数是一种复数形式,用来表示三维空间中的旋转。在 Unity 中,四元数使用 Quaternion 类来表示。四元数具有几何意义,并且可以避免表示旋转的浮点精度误差。 欧拉角是三个欧拉角的旋转序列,用来表示三维空间中的旋转。在 Unity 中,欧拉角使用 Euler 类来表示。欧拉角的优点在于易于理解,但缺点在于容易发生万向节锁(Gimbal lock),并且还存在浮点精度误差。 总的来说,两者都可以用来表示物体的旋转,但是四元数在精度和几何意义上更为优秀。因此,一般情况下建议使用四元数来表示物体的旋转。 ### 回答2: Unity中的四元数(Quaternion)和欧拉角(Euler Angles)是描述游戏物体旋转的两种常用方法。 四元数是一种复数扩展的概念,可以用来表示三维空间中的旋转。在Unity中,四元数由四个浮点数(x、y、z、w)表示,它们代表了旋转轴的三个分量以及旋转度。相比欧拉角四元数具有更简洁和高效的表示方式,并且可以避免万向节锁(Gimbal Lock)的问题。 欧拉角是将旋转分解为绕X、Y和Z轴的三个独立旋转度的方法。在Unity中,欧拉角可以通过三个浮点数(pitch,yaw,roll)来表示,它们代表了绕X、Y和Z轴旋转的度。但是使用欧拉角有时会遇到万向节锁问题,即当两个轴的旋转度一样时,会导致旋转轴的丧失,影响旋转的自由度。 在Unity中,四元数常用于旋转的插值计算,比如使用Lerp函数进行平滑的旋转过渡。而欧拉角则常用于编辑器中的输入和操作,因为欧拉角更容易理解和控制。 总而言之,四元数欧拉角都是描述旋转的方法,而四元数在性能和数学上更加高效和精确,而欧拉角则更易于理解和操作。在使用Unity进行旋转计算时,根据具体的需求和场景选择合适的方法,可以更好地控制物体的旋转效果。 ### 回答3: Unity中的四元数(Quaternion)和欧拉角(Euler Angles)都是用来表示物体在三维空间中的旋转的方法。 四元数是一种复数形式的表示方法,由一个实数部分(标量)和三个虚数部分(向量)组成。在Unity中,四元数可以使用Quaternion类来表示和操作。四元数可以通过简单的乘法操作和单位长度约束来计算和表示物体的旋转。它具有消除万向锁和插值旋转等优点,被广泛用于游戏和图形学领域。 欧拉角是一种以旋转顺序的三个度来描述物体旋转的方法。通常使用欧拉角顺序(Yaw、Pitch、Roll)来表示物体的旋转,也就是绕Y轴旋转的偏航、绕X轴旋转的俯仰和绕Z轴旋转的翻滚。在Unity中,欧拉角可以通过Transform组件的eulerAngles属性来获取和设置。然而,欧拉角在旋转过程中存在万向锁问题,会导致无法准确表示物体的旋转。 在使用四元数欧拉角时,我们需要根据具体的需求来选择合适的方法。如果需要精确的旋转表示并进行旋转插值操作,建议使用四元数来表示物体的旋转。而欧拉角则更适合用于方便的人类可读的表示和操作。在Unity中,可以通过Quaternion转换为欧拉角,或者通过欧拉角转换为四元数来进行两者之间的转换。 总结来说,四元数适用于精确的旋转表示和插值计算,而欧拉角则适用于直观的表示和操作。在实际开发中,我们可以根据具体需求和场景来选择使用四元数还是欧拉角来表示和操作物体的旋转。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值