• Quaternion
    • Quaternion.Slerp 球形插值
    • Quaternion.LookRotation 注视旋转
    • 四元数
      • 复数: a + bi i是虚数,满足 i^2 = -1: a称为实部 b称为虚部。
      • 共轭复数:通过使虚部变负,能够计算出复数的共轭。
      • 四元数:四元数扩展了复数系统,它使用三个虚部 i, j, k。
      • 四元数和轴-角对
      • 负四元数 : 将每个分量都变负
      • 单位四元数
      • 四元数的模
      • 四元数共轭和逆
      • 四元数乘法(叉乘)
    • API

    Quaternion

    四元数用于表示旋转。

    它们是紧凑的,不会出现万向节锁并且能够很容易被插值。Unity内使用Quaternion表示所有旋转。

    他们基于复数并且直觉上不容易理解。你几乎不必要进入或者修改个人的四元数组件(x,y,z,w);

    Quaternion.Slerp 球形插值

    球形插值,通过t值from向to之间插值。参数取值范围[0,1]。

    实例:

    1. using UnityEngine;
    2. using System.Collections;
    3. public class ExampleClass : MonoBehaviour {
    4. public Transform from;
    5. public Transform to;
    6. public float speed = 0.1F;
    7. void Update() {
    8. transform.rotation = Quaternion.Slerp(from.rotation, to.rotation, Time.time * speed);
    9. }
    10. }

    Quaternion.LookRotation 注视旋转

    创建一个旋转,沿着forward(z轴)并且头部沿着upwards(y轴)的约束注视。也就是建立一个旋转,使z轴朝向view y轴朝向up。

    返回计算四元数。如果用于定向的变换,Z轴将会被对准前方并且如果这些向量正交,Y轴向前。如果forward方向是0,记录一个错误。

    实例:

    1. using UnityEngine;
    2. using System.Collections;
    3. public class ExampleClass : MonoBehaviour {
    4. public Transform target;
    5. void Update() {
    6. Vector3 relativePos = target.position - transform.position;
    7. Quaternion rotation = Quaternion.LookRotation(relativePos);
    8. transform.rotation = rotation;
    9. }
    10. }

    四元数

      四元数是简单的超复数。 复数是由实数加上虚数单位 i 组成,其中i^2 = -1。 相似地,四元数都是由实数加上三个虚数单位 i、j、k 组成,而且它们有如下的关系: i^2 = j^2 = k^2 = -1, i^0 = j^0 = k^0 = 1 , 每个四元数都是 1、i、j 和 k 的线性组合,即是四元数一般可表示为a + bk+ cj + di,其中a、b、c 、d是实数。

    1. 使用轴角对的形式描述一个旋转
    2. 绕轴n旋转?角度 描述为[cos(?/2), sin(?/2)nx, sin(?/2)ny, sin(?/2)nz]

    矩阵旋转

    1. 优点:
    2. 旋转轴可以是任意向量
    3. 缺点:
    4. 旋转其实只需要知道一个向量+一个角度,一共4个值的信息,但矩阵法却使用了16个元素
    5. 而且在做乘法操作时也会增加计算量,造成了空间和时间上的一些浪费

    欧拉旋转

    1. 优点:
    2. 很容易理解,形象直观
    3. 表示更方便,只需要3个值(分别对应xyz轴的旋转角度);但它还是转换到了33*3的矩阵做变换,效率不如四元数;
    4. 缺点:
    5. 这种方法是要按照一个固定的坐标轴的顺序旋转的,因此不同的顺序会造成不同的结果;
    6. 会造成万向节锁(Gimbal Lock)的现象。这种现象的发生就是由于上述固定坐标轴旋转顺序造成的。理论上,欧拉旋转可以靠这种顺序让一个物体指到任何一个想要的方向,但如果在旋转中不幸让某些坐标轴重合了就会发生万向节锁,这时就会丢失一个方向上的旋转能力,也就是说在这种状态下我们无论怎么旋转(当然还是要原先的顺序)都不可能得到某些想要的旋转效果,除非我们打破原先的旋转顺序或者同时旋转3个坐标轴。
    7. 由于万向节锁的存在,欧拉旋转无法实现球面平滑插值;

    四元数旋转

    1. 优点:
    2. 可以避免万向节锁现象
    3. 只需要一个4维的四元数就可以绕任意过原点的向量的旋转,方便快捷,在某些实现下比旋转矩阵效率更高;
    4. 可以提供平滑插值
    5. 缺点:
    6. 比欧拉旋转稍微复杂了一点点,因为多了一个纬度
    7. 理解更困难,不直观

    复数: a + bi i是虚数,满足 i^2 = -1: a称为实部 b称为虚部。

    任意实数k都能表示为复数(k, 0) = k + 0i

    1. 复数 + - *
    2. (a + bi) + (c + di) = (a + c) + (b + d)i
    3. (a + bi) - (c + di) = (a - c) + (b - d)i
    4. (a + bi) * (c + di) = ac + adi + bci + bdi^2 = ac + (ad + bc)i + bd*(-1) = (ac - bd) + (ad + bc)i

    共轭复数:通过使虚部变负,能够计算出复数的共轭。

    1. p = (a + bi) p* = (a - bi)
    2. 能计算复数的模长:|p| = Sqrt(p * p*) = Sqrt(a^2 + b^2)

    复数存在于一个2D平面上,实轴、虚轴。将复数(x, y)解释为2D向量。它们能用来表达平面中的旋转。

    1. 例如:复数p绕原点旋转角度theta的情况。
    2. 进行这个旋转,引入第二个复数q = (cos<theta>, sin<theta>)。
    3. 旋转后的复数p'能用复数乘法计算出来:
    4. p = x + yi
    5. q = cos<theta> + i * sin<theta>
    6. p' = p * q
    7. = (x + yi)(cos<theta> + i * sin<theta>)
    8. = (xcos<theta> - ysin<theta>) + (xsin<theta> + ycos<theta>)i

    四元数:四元数扩展了复数系统,它使用三个虚部 i, j, k。

    它们的关系如下:

    1. i^2 = j^2 = k^2 = -1
    2. ij = k, ji = -k
    3. jk = i, kj = -i
    4. ki = j, ik = -j

    一个四元数[w, (x, y, z)]定义了复数 w + xi + yj + zk。

    和复数能用来旋转2D中的向量类似,四元数也能用来旋转3D中的向量。

    四元数和轴-角对

    在3D中任意角位移都能表示为绕单一轴(任意的)的单一旋转。轴-角对(n, theta)定义了一个角位移:绕n指定的轴旋转theta角。

    1. q = [cos<theta/2> sin<theta/2>n]
    2. = [cos<theta/2> (sin<theta/2>nx sin<theta/2>ny sin<theta/2>nz)]

    负四元数 : 将每个分量都变负

    1. -q = -[w (x y z)] = [-w (-x -y -z)]
    2. = -[w v] = [-w -v]

    q 和 -q代表的角位移是相同的。如果我们将theta加上360度的倍数,不会改变q代表的角位移,但它使q的四个分量都变负了。因此,3D中的任意角位移都有两种不同的四元数表示方法,它们互相为负。

    单位四元数

    几何上,存在两个“单位”四元数,它们代表没有角位移:[1, 0]和[-1, 0]。当theta是360的偶数倍时,cos=1;theta是360的奇数倍时,cos = -1。在两种情况下,都有sin=0,所以n的值无关紧要。它的意义在于:当旋转角theta是360的整数倍时,方位并没有改变,并且旋转轴也是无关紧要的。

    在数学上,实际只有一个单位四元数:[1, 0],[-1, 0]并不是“真正”的单位四元数。用任意四元数q乘以单位四元数[1, 0],结果仍是q。

    四元数的模

    计算:和向量类似几何意义:如果使用单位四元数,则模长为1。为了用四元数来表示方位,我们仅使用单位四元数。

    四元数共轭和逆

    四元数的共轭记作:q*,可通过让四元数的向量部分变负来获得 (把轴反向,其实就是按照相反的方向旋转)

    1. q* = [w v]* = [w -v]
    2. = [w (x y z)]* = [w (-x -y -z)]

    四元数的逆记作:q^-1,定义为四元数的共轭除以它的模

    1. q^-1 = q* / |q|

    一个四元数q乘以它的逆q^-1,即可得到单位四元数[1, 0]

    对于单位四元数,四元数的逆和共轭是相等的。

    四元数乘法(叉乘)

    满足结合律但不满足交换律四元数乘积的模等于模的乘积。两个单位四元数相乘的结果还是单位四元数。

    四元数乘积的逆等于各个四元数的逆以相反的顺序相乘。

    1. (ab)^-1 = b^-1a^-1

    将一个标准的点到四元数空间 即 p = [0, (x, y, z)] 设q为我们讨论的旋转四元数形式[cos, nsin]

    1. p' = qpq^-1 可以使点p绕n旋转

    API

    静态变量说明
    identity同一性旋转(只读)。
    变量说明
    eulerAngles返回表示旋转的欧拉角度。
    this[int]分别使用 [0]、[1]、 [2]、 [3],访问x、y、z、w组件。
    w四元数的W组件。不要直接修改这个,除非你很了解四元数。
    x四元数的X组件。不要直接修改这个,除非你很了解四元数。
    y四元数的Y组件。不要直接修改这个,除非你很了解四元数。
    z四元数的Z组件。不要直接修改这个,除非你很了解四元数。
    公有方法说明
    Set设置存在的四元素的x, y, z 和w 组件。
    SetFromToRotation创建一个从fromDirection到toDirection的旋转。
    SetLookRotation创建一个旋转,沿着forward(z轴)并且头部沿着up(y轴)的约束注视。也就是建立一个旋转,使z轴朝向view y轴朝向up。
    ToAngleAxis转换一个旋转用“角-轴”表示。
    静态方法说明
    Angle返回a和b两者之间的角度。
    AngleAxis绕axis轴旋转angle,创建一个旋转。
    Dot两个旋转之间的点乘。
    Euler返回一个旋转角度,绕z轴旋转z度,绕x轴旋转x度,绕y轴旋转y度(像这样的顺序)。
    FromToRotation从fromDirection到toDirection创建一个旋转。
    Inverse返回反向的旋转。
    Lerp通过t值from向to之间插值,并且规范化结果。
    LookRotation创建一个旋转,沿着forward(z轴)并且头部沿着upwards(y轴)的约束注视。也就是建立一个旋转,使z轴朝向view y轴朝向up。
    RotateTowards旋转一个角度从from向to。
    Slerp球形插值,通过t值from向to之间插值。参数取值范围[0,1]。
    SlerpUnclamped球形插值,通过t值from向to之间插值。该参数t是不在区间内。
    Operators 运算符说明
    operator !=判断两个四元数是否不同?
    operator* 获取lhs 的旋转状态并应用rhs的旋转。
    operator ==判断两个四元数是否相等?

    ?