公告

Welcome

Skip to content

定义

四元数

四元数是定义在四维空间中的

q=w+xi+yj+zk=cosθ2+sinθ2(uxi+uyj+uzk)=(w,v)=(cosθ2,usinθ2)q=w+xi+yj+zk=\cos\frac{\theta}{2}+\sin\frac{\theta}{2}(u_xi+u_yj+u_zk)=(w,\mathbf{v})=(\cos\frac{\theta}{2}, \mathbf{u}\sin\frac{\theta}{2})

其中:

i2+j2+k2=ijk=1i^2+j^2+k^2=ijk=-1

ij=k,jk=i,ki=j,ji=k,kj=i,ik=jij=k,jk=i,ki=j,ji=-k,kj=-i,ik=-j

u\mathbf{u} 为旋转轴,θ\theta 为旋转角度

其中 i,j,ki,j,k 代表三维坐标轴,而 ww 代表第四个轴垂直于 i,j,ki,j,k

旋转矩阵

绕 X 轴旋转

Rx(θ)=[1000cosθsinθ0sinθcosθ]R_x(\theta) = \begin{bmatrix} 1 & 0 & 0 \\ 0 & \cos\theta & -\sin\theta \\ 0 & \sin\theta & \cos\theta \end{bmatrix}

绕 Y 轴旋转

Ry(θ)=[cosθ0sinθ010sinθ0cosθ]R_y(\theta) = \begin{bmatrix} \cos\theta & 0 & \sin\theta \\ 0 & 1 & 0 \\ -\sin\theta & 0 & \cos\theta \end{bmatrix}

绕 Z 轴旋转

Rz(θ)=[cosθsinθ0sinθcosθ0001]R_z(\theta) = \begin{bmatrix} \cos\theta & -\sin\theta & 0 \\ \sin\theta & \cos\theta & 0 \\ 0 & 0 & 1 \end{bmatrix}

欧拉角

欧拉角通过将旋转分解为绕三个互相垂直的坐标轴的连续旋转来表示方向。常见的顺序包括:

ZYX顺序​(绕Z轴→Y轴→X轴旋转,即偏航-俯仰-滚转,Yaw-Pitch-Roll)。 ​ZYZ顺序​(绕Z轴→Y轴→Z轴旋转,常用于经典力学)。

unity欧拉角顺序默认是 ZXYZ\rightarrow X\rightarrow Y, Unreal欧拉角顺序默认是 ZYXZ\rightarrow Y\rightarrow X, ​Godot欧拉角顺序默认是 YXZY\rightarrow X\rightarrow Z, ​Blender欧拉角顺序默认是 ZYXZ\rightarrow Y\rightarrow X,Three.js 欧拉角顺序默认是 XYZX\rightarrow Y\rightarrow Z

如何使用四元数表示旋转?

  1. 先将三维点 (x,y,z)(x,y,z) 转为四元数 (0,x,y,z)(0,x,y,z)
  2. 使用单位四元数(只有单位四元数才能表示旋转)对其进行旋转 q^=qXq1=qXq\hat{q}=q\mathbf{X}q^{-1}=q\mathbf{X}q^*
  3. 根据旋转后的四元数 q^=(0,X^)\hat{q}=(0,\mathbf{\hat{X}}) 提取 X^\mathbf{\hat{X}} 即为旋转后的三维点坐标

共轭四元数 q=w(xi+yj,zk)=(w,v)q^*=w-(xi+yj,zk)=(w,-\mathbf{v}) 对于非单位四元数如果要表示旋转要先将其归一化 q=qqq=\frac{q}{||q||}, q=w2+x2+y2+z2||q||=\sqrt{w^2+x^2+y^2+z^2} 对于单位四元数来说其逆等于共轭 q1=qq^{-1}=q^* 四元数的连续旋转 (q3q2q1)X(q11q21q31)(q_3q_2q_1)\mathbf{X}(q_1^{-1}q_2^{-1}q_3^{-1})

为什么使用四元数表示旋转?

欧拉角的万向锁

欧拉角是针对于物体初始姿态的变换,无论 (eulerx,eulery,eulerz)(euler_x,euler_y,euler_z) 调整的顺序如何。其执行的变换都是针对于初始姿态进行的,而且是先 XXYYZZ 轴,因此当 euleryeuler_y 为90度时,执行的是针对于初始姿态 09000\rightarrow90\rightarrow0 的变换,因此此时调整 eulerxeuler_x 时其执行的是针对于初始姿态 eulerx900euler_x\rightarrow90\rightarrow0, 变换执行的顺序与用户调整欧拉角的顺序无关。那么物体在 (0,90,0)(0,90,0) 的状态下,自身的 zz 轴和物体初始姿态的 xx 轴重合,此时调整两者是等价的 (45,90,0)(45,90,0)(0,90,45)(0,90,45) 是一样的。实质是前面的轴可以带动后面的轴转动,而后面的轴无法带动前面的轴转动。

旋转矩阵的误差

矩阵用于表示旋转的前提是该矩阵必须是正交矩阵否则就会发生缩放,而由于矩阵乘法和浮点运算导致累计误差,那么矩阵很难维持正交化,因此不直接使用矩阵进行旋转。由于矩阵的​非欧几里得性质直接对矩阵元素进行线性插值可能破坏矩阵的重要特性(如正交性、正定性、秩等)

四元数、欧拉角和旋转矩阵的相互转化

四元数 \rightarrow 旋转矩阵

单位四元数 q=(w,x,y,z)q=(w,x,y,z)

R=[12y22z22xy2wz2xz+2wy2xy+2wz12x22z22yz2wx2xz2wy2yz+2wx12x22y2]R= \begin{bmatrix} 1-2y^2-2z^2 & 2xy-2wz & 2xz+2wy \\ 2xy+2wz & 1-2x^2-2z^2 & 2yz-2wx \\ 2xz-2wy & 2yz+2wx & 1-2x^2-2y^2 \end{bmatrix}

旋转矩阵 \rightarrow 四元数

四元数 \rightarrow 欧拉角

欧拉角 \rightarrow 四元数

四元数的插值

线性插值NLerp

NLerp(q0,q1,t)=(1t)q0+tq1NLerp(q_0,q_1,t)=(1-t)q_0+tq_1

qnlerp=Lerp(q0,q1,t)Lerp(q0,q1,t)q_{nlerp}=\frac{Lerp(q_0,q_1,t)}{||Lerp(q_0,q_1,t)||}

​球面线性插值Slerp

Slerp(q0,q1,t)=sin((1t)θ)sinθq0+sin(tθ)sinθq1Slerp(q_0, q_1, t) = \frac{\sin\big((1-t)\theta\big)}{\sin\theta} q_0 + \frac{\sin(t\theta)}{\sin\theta} q_1

上次更新于: