文章目录

  • 简介
  • Quaternion类属性
  • 静态属性
  • 属性
  • 构造函数
  • 方法
  • 静态方法
  • 运算符
  • 欧拉角


简介

Quaternion又称四元数,由x,y,z和w这四个分量组成,是由爱尔兰数学家威廉·卢云·哈密顿在1843年发现的数学概念。四元数的乘法不符合交换律。从明确地角度而言,四元数是复数的不可交换延伸。如把四元数的集合考虑成多维实数空间的话,四元数就代表着一个四维空间,相对于复数为二维空间。

四元数不存在欧拉角的万向锁问题,旋转大小角问题,以及旋转不唯一(同一个旋转结果,可以有多个旋转顺序及角度定义)问题,用起来简单。

在Unity中,用Quaternion来存储和表示对象的旋转角度。Quaternion的变换比较复杂,对于GameObject一般的旋转及移动,可以用Transform中的相关方法实现。

最常用的功能为:Quaternion.LookRotation, Quaternion.Angle, Quaternion.Euler, Quaternion.Slerp, Quaternion.FromToRotation, Quaternion.identity

Quaternion类属性

静态属性

属性

  • eulerAngles
  • normalized
  • x,y,z 旋转轴,不建议直接修改该值。
  • w 转转角度,不可以直接修改该值。

构造函数

  • Quaternion
    public Quaternion(float x, float y, float z, float w);
    构造一个四元数。

方法

  • Set
    public void Set(float newX, float newY, float newZ, float newW);
    修改四元数。
  • SetFromToRotation
    public void SetFromToRotation(Vector3 fromDirection, Vector3 toDirection);
    构建一个从fromDirectoion到toDirection的旋转。
  • SetLookRotation
    public void SetLookRotation(Vector3 view, Vector3 up = Vector3.up);
    view:观察方向
    up:定义向上的方向
    用向上和向前的方向构建旋转。
    如果用来确定Transform的朝向,则Z轴是forward,Y轴是upwards。如果forward的方向(view)是0,会报错。
  • ToAngleAxis
    public void ToAngleAxis(out float angle, out Vector3 axis);
    将旋转,转换成轴角对。这里角是角度。

静态方法

  • Angle
    public static float Angle(Quaternion a, Quaternion b);
    计算两个旋转之间的角度。
  • AngleAxis
    public static Quaternion AngleAxis(float angle, Vector3 axis);
    创建一个围绕 axis 轴旋转 angle 度的旋转。
  • Dot
    public static float Dot(Quaternion a, Quaternion b);
    计算两个旋转的点积。目前使用场景不详。
    点积也叫做欧几里得内积,四元数的点积等同于一个四维矢量的点积点积的值是p中每个元素的数值与q中相应元素的数值的乘积的和。
  • Euler
    public static Quaternion Euler(float x, float y, float z);
    根据欧拉角生成四元数。旋转顺序按照z->y->z。
  • FromToRotation
    public static Quaternion FromToRotation(Vector3 fromDirection, Vector3 toDirection);
    构建从fromDirection到toDirection的旋转。
    通常用来旋转 transform 来保证其一个轴朝向世界空间中的toDirection。例如:
    设置对象的Y轴朝向z轴(绕x轴旋转90度)
    transform.rotation = Quaternion.FromToRotation(Vector3.up, transform.forward);
  • Inverse
    public static Quaternion Inverse(Quaternion rotation);
    反向旋转。数学实现时,可以是旋转轴取反,也可以是w值取反。
    测试Unity是对旋转轴取反来实现的。
  • Lerp
    public static Quaternion Lerp(Quaternion a, Quaternion b, float t);
    在2个旋转之间进行线性插值。
    该旋转要比Slerp快,但是当两个旋转差别比较大时,效果不好。
    如果是渐进式的更新旋转,确定两个旋转差别比较小时,可以用这个来提升效率。
  • LerpUnclamped
    public static Quaternion LerpUnclamped(Quaternion a, Quaternion b, float t);
    功能同上,只是,允许t<0或t>1
  • Slerp
    public static Quaternion Slerp(Quaternion a, Quaternion b, float t);
    在两个旋转之间进行球面插值。0<=t<=1
  • SlerpUnclamped
    public static Quaternion SlerpUnclamped(Quaternion a, Quaternion b, float t);
    功能同上,允许t<0或t>1
  • LookRotation
    public static Quaternion LookRotation(Vector3 forward, Vector3 upwards = Vector3.up);
    根据forward和upwards的方向,创建旋转。
    该旋转的Z轴对齐forward,X轴对齐forward和upwards的叉积向量,Y轴对齐Z和X轴的叉积。
  • Normalize
    public static Quaternion Normalize(Quaternion q);
    将四元数转成方向不变,但是四元数长度为1的四元数(模)。
    该方法会改变参数四元数。
  • RotateTowards
    public static Quaternion RotateTowards(Quaternion from, Quaternion to, float maxDegreesDelta);
    旋转四元数(比如旋转朝向)。当旋转角度大于maxDegreesDelta,仅旋转maxDegreesDelta。比如,保持跟另一个对象朝向一致:
    transform.rotation = Quaternion.RotationTowards(transform.rotation,target.rotation,rotSpeed*Time.deltaTime);

运算符

  • operator *
    public static Quaternion operator *(Quaternion lhs, Quaternion rhs);
    组合2个旋转。可以认为旋转效果相加:
    transform.rotation = Quaternion.AngleAxis(rotSpeedTime.deltaTime, Vector3.up);

欧拉角

欧拉角,用分别三个轴上的旋转,来表示一个完整的3D空间的旋转,Unity以Z->X->Y轴的顺序依次执行旋转,该顺序非常重要,因为同样的旋转,不同的顺序,结果是不同的。