ZERO_BEYOND

博客园 首页 联系 订阅 管理

四元数

欧拉角

由三个角度(x,y,z)组成,在特定坐标系下用于描述物体的旋转量

空间中的任意旋转都可以分解成绕三个互相垂直轴的三个旋转角组成的序列

heading-pitch-bank

heading:物体绕自身对象坐标系的Y轴旋转的角度

pitch:物体绕自身对象坐标系的X轴旋转的角度

bank:物体绕自身对象坐标系的Z轴旋转的角度

Unity中的欧拉角

Inspector窗口中调节的Rotation就是欧拉角

transform.eulerAngles得到的就是欧拉角角度

优点

直观,易理解

存储空间小(三个数表示)

可以进行从一个方向到另一个方向旋转大于180°的角度

缺点

同一旋转的表示不唯一

万向节死锁

当某个特定轴达到某个特殊值时,绕一个轴旋转可能会覆盖住另一个轴的旋转,从而失去一维自由度

Unity中X轴达到90度时会产生万向节死锁

总结

因为欧拉角存在一些缺点

而四元数旋转不存在万向节死锁问题,因此在计算机中我们往往使用四元数来表示三维空间中的旋转信息

四元数
四元数构成

一个四元数包含一个标量和一个3D向量

【w,v】w为标量,v为3D向量

【w,(x,y,z)】

对于给定的任意一个四元数:表示3D空间中的一个旋转量

轴-角对

在3D空间中,任意旋转都可以表示绕着某个轴旋转一个旋转角得到

注意:该轴并不是空间中的x,y,z轴,而是任意一个轴

对于给定旋转,假设为绕着n轴,旋转β度,n轴为(x,y,z),那么可以构成四元数为:

四元数Q=【cos(β/2),sin(β/2)n】

四元数Q=【cos(β/2),sin(β/2)x,sin(β/2)y,sin(β/2)z】

四元数Q则表示绕着轴n,旋转β度的旋转量

Unity中的四元数

是Unity中表示四元数的结构体

初始化方法:

轴角对公式初始化(原理)

四元数Q = 【cos(β/2),sin(β/2)x,sin(β/2)y,sin(β/2)z】

Quaternino q = new Quaternino(sin(β/2)x,sin(β/2)y,sin(β/2)z,cos(β/2))

轴角对方法初始化

四元数Q = Quaternion.AngleAxis(角度,轴);

Quaternino q = Quaternino.AngleAxis(60,Vector3.right) = new Quaternino(Mathf.sin(30 * Mathf.Deg2Rad),0,0,Mathf.cos(30 * Mathf.Deg2Rad));

四元数和欧拉角转换

欧拉角转四元数

Quaternion.Euler(x,y,z)

四元数转欧拉角

Quaternion q;

q.eulerAngles

弥补欧拉角缺

同一旋转的表示不唯一 四元数旋转区间(-180,180)

万向节死锁

必备知识点:四元数相乘代表旋转四元数

transform.rotation *= Quaternion.AngleAxis(1,Vector3.forward)

表示物体绕自身坐标系z轴每帧旋转1度

注意:一般不会直接通过四元数的w,x,y,z进行修改

四元数常用方法

单位四元数

Quaternion.identity

单位四元数表示没有旋转量(角位移),当角度为0或者360°时,对于给定轴都会得到单位四元数

【1,(0,0,0)】和【-1,(0,0,0)】都是单位四元数,表示没有旋转量

四元数插值运算

四元数中同样提供如同Vector3的插值运算

Lerp和Slerp

由于算法不同,Slerp效果会好一些,Lerp效果相比Slerp更快但是如果旋转范围较大效果较差,所以建议使用Slerp进行插值运算

向量指向转四元数

Quaternion.LookRotation(面朝向量);

LookRotation方法可将传入的面朝向量转换成对应的四元数角度信息

举例:当人物面朝向想要改变时,只需把目标面朝向传入该函数,便可得到目标四元数角度信息,之后将人物四元数信息改为得到的信息即可达到转向

A.rotation = Quaternion.LookRotation(B.position - A.position);

总结

单位四元数:用于对象角度初始化

插值运行:用于平滑旋转

向量指向转四元数:用于让对象朝向某方向

posted on 2023-11-08 03:32  ZERO_BEYOND  阅读(40)  评论(0编辑  收藏  举报