Skip to content

四元数基础理论

四元数(Quaternion)是3D旋转的最佳表示方式,解决了欧拉角的万向节死锁问题。

什么是四元数?

四元数是一种扩展的复数,由一个实部和三个虚部组成:

$$ \mathbf{q} = w + xi + yj + zk $$

其中:

  • $w$ 是实部(scalar)
  • $(x, y, z)$ 是虚部(vector)

通常写成:

$$ \mathbf{q} = [w, (x, y, z)] = [w, \mathbf{v}] $$

虚数单位规则

四元数的虚数单位满足:

$$ i^2 = j^2 = k^2 = ijk = -1 $$

乘法规则(非交换):

$$ ij = k, \quad ji = -k $$ $$ jk = i, \quad kj = -i $$ $$ ki = j, \quad ik = -j $$

记忆技巧:按照循环顺序 $i \rightarrow j \rightarrow k$ 是正,逆序是负。

单位四元数与旋转

关键事实:单位四元数(长度为1)可以表示3D旋转。

绕轴 $\mathbf{axis}$ 旋转角度 $\theta$ 的四元数:

$$ \mathbf{q} = \left[ \cos\left(\frac{\theta}{2}\right), \sin\left(\frac{\theta}{2}\right) \cdot \mathbf{axis} \right] $$

注意:角度要除以2

代码实现

javascript
class Quaternion {
  constructor(w = 1, x = 0, y = 0, z = 0) {
    this.w = w;
    this.x = x;
    this.y = y;
    this.z = z;
  }
  
  // 从轴角创建
  static fromAxisAngle(axis, angle) {
    const halfAngle = angle / 2;
    const s = Math.sin(halfAngle);
    return new Quaternion(
      Math.cos(halfAngle),
      axis.x * s,
      axis.y * s,
      axis.z * s
    );
  }
  
  // 长度(模)
  length() {
    return Math.sqrt(this.w * this.w + this.x * this.x + this.y * this.y + this.z * this.z);
  }
  
  // 归一化
  normalize() {
    const len = this.length();
    if (len === 0) return new Quaternion();
    return new Quaternion(
      this.w / len,
      this.x / len,
      this.y / len,
      this.z / len
    );
  }
  
  toString() {
    return `Quat(${this.w.toFixed(3)}, ${this.x.toFixed(3)}, ${this.y.toFixed(3)}, ${this.z.toFixed(3)})`;
  }
}

// 示例:绕Y轴旋转90度
const axis = new Vector3(0, 1, 0);
const angle = Math.PI / 2;
const q = Quaternion.fromAxisAngle(axis, angle);
console.log(q.toString());  // Quat(0.707, 0, 0.707, 0)

为什么角度除以2?

这是四元数的数学性质。旋转 $\theta$ 角度,四元数参数是 $\frac{\theta}{2}$。

后果

  • 旋转360度:$\mathbf{q} = [\cos(180°), 0] = [-1, 0]$
  • 旋转720度:$\mathbf{q} = [\cos(360°), 0] = [1, 0]$

这意味着四元数有双重覆盖(double cover):$\mathbf{q}$ 和 $-\mathbf{q}$ 表示相同旋转。

特殊四元数

单位四元数(无旋转)

$$ \mathbf{q}_{identity} = [1, (0, 0, 0)] $$

javascript
const identity = new Quaternion(1, 0, 0, 0);

绕轴旋转90度

  • 绕X轴:$\mathbf{q}_x = [\cos(45°), \sin(45°), 0, 0] = [0.707, 0.707, 0, 0]$
  • 绕Y轴:$\mathbf{q}_y = [0.707, 0, 0.707, 0]$
  • 绕Z轴:$\mathbf{q}_z = [0.707, 0, 0, 0.707]$

四元数 vs 其他旋转表示

表示方式存储空间万向节死锁插值平滑组合效率
欧拉角3个数字
旋转矩阵9个数字
轴角4个数字
四元数4个数字优秀(Slerp)优秀

小结

  • 四元数:$\mathbf{q} = [w, (x, y, z)]$,4个数字表示旋转
  • 单位四元数:长度为1,表示3D旋转
  • 从轴角创建:$\mathbf{q} = [\cos(\frac{\theta}{2}), \sin(\frac{\theta}{2}) \cdot \mathbf{axis}]$
  • 双重覆盖:$\mathbf{q}$ 和 $-\mathbf{q}$ 是同一旋转
  • 优势:无万向节死锁,插值平滑,组合高效
四元数基础理论 has loaded