Contents

欧拉角和四元数

欧拉角

  • 由三个角度XYZ组成
  • 在特定坐标系下用于描述物体的旋转量
  • 空间中任意旋转都可以分解成绕三个互相垂直轴的三个旋转角组成的序列

欧拉角旋转约定

  • Heading-Pitch-bank是一种最常用的旋转序列约定
  • heading 物体围绕自身坐标系的Y轴 旋转的角度
  • pitch 物体围绕自身坐标系的X轴 旋转的角度
  • bank 物体绕自身的对象坐标系的Z轴 旋转的角度

Unity中的欧拉角

  • Inspector窗口中调节的Rotaion就是欧拉角
  • this.transform.enlerAngles得到的就是欧拉角角度

欧拉角的优缺点

优点:

  • 直观,易理解
  • 存储空间小(三个数表示)
  • 可以从一个方向到另一个方向旋转大于180的角度

缺点:

  • 同一旋转的表示不唯一
  • 万向节死锁
    • 绕一个轴 旋转可能会覆盖住另一个轴的旋转 从而失去一个维度的自由度

四元数

  • 一个四元数包含一个标量和一个3D向量
    • [w,v],w为标量 V为3D向量
    • [w,(x,y,z)]对于给定的任意一个四元数 表示3D空间中的一个旋转量
  • 四元数弥补了欧拉角的缺点
  • 四元数相乘相当于旋转四元数

轴角对

在3D空间中,任意旋转都可以表示 绕着某个轴旋转一个角得到(该轴不是空间中的xyz轴 而是任意一个轴)

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

Q=[cos(β/2),sin(β/2)n]

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


Unity中的四元数

//轴角对公式初始化 一般不会使用这种方式
//β为角度 需要转换成弧度传入
Quaternino q = new Quaternino(sin(β/2)x,sin(β/2)y,sin(β/2)z,cos(β/2));
//Quaternino(角度,轴);
Quaternino q2 =  Quaternino.AngleAxis(60,Vector3.right);//Vector3.right也会围绕自己的本地坐标系旋转

四元数的常用方法

单位四元数

Quaternion.identity;//没有旋转量的四元数 相当于是欧拉角的0,0,0

插值运算

四元数中同样提供了Lerp和Slero用于插值运算

四元数中的Lerp和Slerp只有一些细微差别

由于算法不同Slerp的效果会好一些

Lerp的效果相比Slerp更快 但是如果旋转范围较大效果较差

所以建议使用Slerp进行插值运算

Quaternion.Lerp(start,end,t);
Quaternion.Slerp(start,end,t);

看向方法

Quaternion.LookRotation(看向目标的面朝向量);

四元数的计算

四元数相乘

Q3 = Q1*Q2

  • 两个四元数相乘得到一个新的四元数
  • 代表两个旋转量的叠加
  • 旋转相对的坐标系是物体自身的坐标系

四元数乘向量

V2 = Q1 * V1

  • 四元数乘向量 会返回一个新的向量
  • 可以将向量V1旋转Q1角度 返回旋转后的向量V2
  • 要将四元数写在前面 因为只有四元数重写了乘法运算符
  • 向量的旋转 四元数中的坐标系是世界坐标系