四元数
欧拉角
由三个角度(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;
弥补欧拉角缺
同一旋转的表示不唯一 四元数旋转区间(-180,180)
万向节死锁
必备知识点:四元数相乘代表旋转四元数
transform.rotation *= Quaternion.AngleAxis(1,Vector3.forward)
四元数常用方法
单位四元数
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);
总结
单位四元数:用于对象角度初始化
插值运行:用于平滑旋转