万向节死锁
可以理解为有两个轴重合在了一起,导致只能对物体两个方向进行旋转
实数:有理数和无理数
虚数:I^2 = -1
复数:实数+虚数
四元数<x,y,z>theta
超复数:(x,y,z,w)
X = n x * sin(theta/2)
Y = n y * sin(theta/2)
Z = n z * sin(theta/2)
W = cos(theta/2)
//通过四元数,让cube游戏物体绕z轴0旋转60度
//<x,y,z>theta 要旋转多少度,就是让theta角为多少度
//X = n x* sin(theta/ 2)
//Y = n y* sin(theta/ 2)
//Z = n z* sin(theta/ 2)
//W = cos(theta / 2)
cube.transform.rotation =
new Quaternion(0, 0, Mathf.Sin(30 * Mathf.Deg2Rad), Mathf.Cos(30 * Mathf.Deg2Rad));
Quaternion.Euler(Vector3 euler);
这相当于给一个欧拉角转换成四元数
//通过unity提供的方法,输入欧拉角,输出四元数
Quaternion q1 = Quaternion.Euler(0, 60, 0);
cube.transform.rotation = q1;
Quaternion.AngleAxis(float angle, Vector3 axis)
先输入一个角度angle,再输入要绕着哪一条轴进行旋转,Vector3.up是y轴,Vector3.forward是z轴,Vector3.left是x轴,返回的是四元数Quaterniom。
//通过Quaternion.AngleAxis()这个API来达到旋转的效果
Quaternion q2 = Quaternion.AngleAxis(60, Vector3.up);
cube.transform.rotation = q2;
Quternion.LookRotation(Vector3 forward, Vector3 upwards = Vector3.up)
效果等同于Lookat但是比较平缓
//利用Quaternion.LookRotation()这个API达到看向目标,并且进行旋转的效果
//先获取向量的差
Vector3 q1 = enemy.position - player.transform.position;
//进行旋转
player.transform.rotation =
Quaternion.Lerp(player.transform.rotation, Quaternion.LookRotation(q1, Vector3.up), 0.1f);
xxx.transform.rotation.eulerAngless;
返回的unity的欧拉角,Unity把四元数用欧拉角的形式展示在Inspector面板上
Quaternion operator * (Quaternion lhs,Quaternion rhs)
相当于对*重载,使得两个四位数的角度能够相加
//这里的*是被重载了的,这里的意思是两个四位数的角度相加
player.transform.rotation *= q ;
Vector3 operator *(Quaterion rotation, Vector3 point)
就相当于将point这个向量按照rotation进行一个旋转
Vector3 dir = enemy.transform.position - player.transform.position;
Quaternion revolue = Quaternion.AngleAxis(angix, Vector3.up);
//让向量旋转一些角度,变为另外一个向量
Vector3 pos = revolue * dir;
Debug.DrawLine(player.transform.position, enemy.transform.position, Color.red);
Debug.DrawRay(player.transform.position, pos, Color.blue);
四元数喝欧拉角旋转优缺点对比
欧拉角:
优点:很容易理解,方便
缺点:会造成万向节死锁,而且不能避免
四元数旋转:
优点:不会万向节死锁
缺点:难理解,计算复杂,比欧拉角多记录一项角度的数据