Unity-万向节死锁(GimbalLock)问题总结

Unity-万向节死锁(GimbalLock)问题总结
⼀、欧拉
1.1 欧拉⾓定义
Unity API中对Transform.eulerAngles的定义是,本⾝是Vector3,即三维⽮量,含有x、y、z三个参数。中央轴空病
Unity API对Transform.eulerAngles的描述
1.以欧拉⾓为单位的旋转
2.x、y、z⾓度分别表⽰先围绕z轴旋转z度,再围绕x轴旋转x度,最后围绕y轴旋转y度;
option82
3.仅使⽤此变量读取⾓度并将其设置为固定值。不要增加它们,因为当⾓度超过360度时会失败。应使⽤Transform.Rotate来执⾏旋转操作。
◆此处“⾓度超过360度时会失败”的理解是,Unity内部使⽤四元数去执⾏旋转,不会存储欧拉⾓的累计值,欧拉⾓只代表了等值的旋转变化结果,当旋转⾓度X超过360度时,存储的⾓度为X-360,例如,361度等同于1度,722度等同于2度。
同时,Unity API提醒我们不要单独设置⼀个欧拉⾓的参数(例如,Eulerangles.x=10;),这将导致错误的旋转,应当同时对x、y、z三个参数进⾏设置。
空军政治学院
1.2 欧拉旋转的旋转轴
欧拉旋转中,总是沿着初始的固定轴向在进⾏按z、x、y顺序的旋转。例如,指定欧拉旋转(90,90,90),它会先绕Z轴旋转90度,再绕X轴旋转90度,再绕Y轴旋转90度,但是绕Z旋转后,再绕X轴旋转时,依然是绕着初始的X轴旋转,绕Y轴旋转时同理。
正是由于欧拉旋转沿Z、X、Y顺规执⾏和旋转轴轴向的定义,导致了“万向节死锁”的发⽣。
⼆、万向节死锁
2.1万向节定义和陀螺仪原理
万向节,也叫平衡环架(Gimbal),具有枢纽的装置,使得⼀物体能以单⼀轴旋转。由彼此垂直的枢
纽轴所组成的⼀组三只平衡环架,则可使架在最内的环架的物体维持旋转轴不变。常常应⽤于船上的陀螺仪、罗盘、饮料杯架等。
陀螺仪
在飞⾏器的航⾏中,进⾏XYZ三个⽅向旋转的旋转有专业的术语,见下图:
飞⾏器旋转⽰意图
俯仰。
pitch,中⽂叫俯仰
沿着机⾝右⽅轴(Unity中的+X)进⾏旋转,称为pitch
偏航。
沿着机头上⽅轴(Unity中的+Y)进⾏旋转,称为Yaw
Yaw,中⽂叫偏航
细胞吞噬Roll,中⽂叫桶滚
桶滚。
沿着机头前⽅轴(Unity中的+Z)进⾏旋转,称为Roll
当飞⾏器或者船体发⽣桶滚、俯仰和偏航时,陀螺仪中的转⼦和旋转轴具有较⼤的惯性,会保持原来的姿态,⽽其余的环则会发⽣旋转,最终保证轩⼦和旋转轴的平衡,如图所⽰:
初始状态
俯仰唐山警示录
偏航
桶滚
2.2 万向节死锁
当飞⾏器和船体仰起90度时,陀螺仪状态如下:
仰起90度时状态此时沿蓝⾊轴转动,则转⼦和旋转轴将⽆法保持平衡。
此时沿蓝⾊轴转动现在,
红⾊连接头:提供⼀个相对俯仰的⾃由度。
绿⾊连接头:提供⼀个相对偏航的⾃由度。
中医美容学
蓝⾊连接头:提供⼀个相对偏航的⾃由度。
3个连接头只提供了两个⾃由度,桶滚的⾃由度丢失了,这种现象被称为“万向节死锁”。
更加进⼀步地分析原因,欧拉⾓的X轴转动造成最后的变化结果,受到到了预先执⾏的Z轴转动的影响,它仍然会造成某个相对⾃⾝的轴向的变化,但是结果不唯⼀;同样,欧拉⾓的Y轴转动,则受到了Z轴和X轴的影响,结果更加不唯⼀。
由于沿XYZ轴的转动遵循Unity中欧拉旋转的顺规和轴向定义,有些情况下会造成某个轴向⾃由度的丢失。
再追究其本质,从欧拉⾓到旋转是⼀个多对⼀的映射(即不同的欧拉⾓可以表⽰同⼀个旋转⽅向),⽽且并不是每⼀个旋转变化都可以⽤欧拉⾓来表⽰。
三、万向节死锁的避免
3.1 四元数介绍
利⽤四元数(Quaternion)来进⾏旋转。
四元数本质上是⼀种⾼阶复数,它的虚部包含了三个虚数单位,i、j、k,即⼀个四元数可以表⽰为x = a + bi + cj + dk。Unity
中,ation存储四元数信息,我们可以使⽤⼀个四元数来执⾏⼀个旋转。
举例说,把点P(1, 0, 1)绕旋转轴u = (0, 1, 0)旋转90°,求旋转后的顶点坐标。⾸先将P扩充到四元数,即p = (P, 0)。⽽q = (u*sin45°,
cos45°)。求p′=qpq−1的值。最后的结果p'= ((1, 0, -1), 0),即旋转后的顶点位置是(1, 0, -1)。
Unity内部使⽤四元数表⽰所有旋转。Unity API中并未对四元数进⾏详细的定义,仅是提供了常见的若⼲四元数函数,⽐如
Quaternion.LookRotation, Quaternion.Angle,Quaternion.Eule,Quaternion.Slerp, Quaternion.FromToRotation和
Quaternion.identity等。
在Unity中,使⽤四元数进⾏旋转,⽐欧拉旋转更强⼤,能够进⾏增量旋转,能够避免万向锁,还能进⾏球⾯差值。
3.2 简单的例⼦
使⽤四元数来实现⼀定⾓度的平滑旋转的简单⽰例如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class rotate : MonoBehaviour
{
[SerializeField]
float rotateSpeed = 2f;
bool isClick = false;
Quaternion targetAngles;
private void Start()

本文发布于:2024-09-20 13:50:30,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/532191.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:旋转   欧拉   旋转轴   轴向   定义   变化   提供
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议