四元数计算旋转方法的复杂度比较

0. 四元数相关知识概要

四元数是一种扩展的复数。像复数 n = a + b i n=a+bi n=a+bi的形式,四元数形如

q = q 0 + q 1 i + q 2 j + q 3 k \mathbf{q}=q_0+q_1i+q_2j+q_3k q=q0+q1i+q2j+q3k

q = [ s , v ⃗ ] , s = q 0 ∈ R , v = [ q 1 , q 2 , q 3 ] T ∈ R 3 \mathbf{q}=[s,\vec{v}], s=q_0\in \mathbf{R}, v=[q_1,q_2,q_3]^T\in \mathbf{R^3} q=[s,v ],s=q0R,v=[q1,q2,q3]TR3
其中 s s s称为实部, v ⃗ \vec{v} v 称为虚部。如果虚部为0,则称为实四元数,实部为0则称为虚四元数。

在计算机图形学、计算机视觉等学科中,常使用单位四元数表示旋转。相比欧拉角和旋转矩阵,四元数有其独到优势。

1 四元数乘法计算 q p q − 1 qpq^{-1} qpq1

1.1 四元数乘法和求逆

q a = s a + x a i ⃗ + y a j ⃗ + z a k ⃗ q_a=s_a+x_a\vec{i}+y_a\vec{j}+z_a\vec{k} qa=sa+xai +yaj +zak q b = s b + x b i ⃗ + y b j ⃗ + z b k ⃗ q_b=s_b+x_b\vec{i}+y_b\vec{j}+z_b\vec{k} qb=sb+xbi +ybj +zbk

四元数的共轭和模定义为:

共 轭 : q a ∗ = [ s a , − v a ⃗ ] 模 : ∣ ∣ q a ∣ ∣ = s a 2 + x a 2 + y a 2 + z a 2 \begin{aligned} &共轭:\mathbf{q^*_a}=[s_a,-\vec{v_a}]\\ &模:\mathbf{||q_a||}=\sqrt{s_a^2+x_a^2+y_a^2+z_a^2} \end{aligned} qa=[sa,va ]qa=sa2+xa2+ya2+za2

则乘法和求逆如下:
乘 法 : q a q b = [ s a s b − v a ⃗ T v b ⃗ , s a v b ⃗ + s b v a ⃗ + v a ⃗ × v b ⃗ ] 求 逆 : q − 1 = [ q ∗ ∣ ∣ q ∣ ∣ 2 ] \begin{aligned} &乘法:\mathbf{q_aq_b}=[s_as_b-\vec{v_a}^T\vec{v_b},\quad s_a\vec{v_b}+s_b\vec{v_a}+\vec{v_a}\times \vec{v_b}]\\ &求逆:\mathbf{q^{-1}}=[\frac{q^*}{||q||^2}] \end{aligned} qaqb=[sasbva Tvb ,savb +sbva +va ×vb ]q1=[q2q]

1.2 p ′ = q p q − 1 p'=qpq^{-1} p=qpq1的计算量

P = [ x y z ] P=\begin{bmatrix}x\\y\\z\\\end{bmatrix} P=xyz为一三维矢量,表示某空间点。为了计算其变换后的坐标,需要将其转换为一纯虚四元数: p = 0 + x i ⃗ + y j ⃗ + z k ⃗ p=0+x\vec{i}+y\vec{j}+z\vec{k} p=0+xi +yj +zk 。因此,忽略掉加减法的计算量,仅考虑乘除运算,计算一次 q p q − 1 qpq^{-1} qpq1需要一次求逆和两次四元数乘法,总共要24次实数乘法(忽略掉与p的实部0相乘的次数)和1次实数除法。

2 先转换为旋转矩阵R,再计算RP

设单位四元数 q = q 0 + q 1 i + q 2 j + q 3 k \mathbf{q}=q_0+q_1i+q_2j+q_3k q=q0+q1i+q2j+q3k

则有,

R = [ 1 − 2 q 2 2 − 2 q 3 2 2 q 1 q 2 + 2 q 0 q 3 2 q 1 q 3 − 2 q 0 q 2 2 q 1 q 2 − 2 q 0 q 3 1 − 2 q 1 2 − 2 q 3 2 2 q 2 q 3 + 2 q 0 q 1 2 q 1 q 3 + 2 q 0 q 2 2 q 2 q 3 − 2 q 0 q 1 1 − 2 q 1 2 − 2 q 2 2 ] R=\begin{bmatrix}1-2q_2^2-2q_3^2 & 2q_1q_2+2q_0q_3 & 2q_1q_3-2q_0q_2 &\\ 2q_1q_2-2q_0q_3&1-2q_1^2-2q_3^2 & 2q_2q_3+2q_0q_1&\\ 2q_1q_3+2q_0q_2&2q_2q_3-2q_0q_1&1-2q_1^2-2q_2^2&\\ \end{bmatrix} R=12q222q322q1q22q0q32q1q3+2q0q22q1q2+2q0q312q122q322q2q32q0q12q1q32q0q22q2q3+2q0q112q122q22

感兴趣可以参考这篇博客证明

忽略掉加减法的计算量,仅考虑乘除运算,计算旋转矩阵最少需要3*9=27次乘法(因为 2 q 1 q 2 2q_1q_2 2q1q2等项只需计算一次记录下来,实际被使用两次)。
完成对P的旋转变换最少需要 27 ⏟ 计算旋转矩阵 + 9 ⏟ 旋转矩阵乘三维点 = 36 \underbrace{27}_{\text{计算旋转矩阵}}+\underbrace9_{\text{旋转矩阵乘三维点}}=36 计算旋转矩阵 27+旋转矩阵乘三维点 9=36次乘法。

3. 结论

在仅有一个三维点需要旋转的情况下,计算旋转矩阵进行旋转变换的方法需要的乘法次数更多(27>24);但是当应用同一个姿态参数(旋转变换)的点数量大于1时,旋转矩阵只要计算一次后,可以保存下来重复使用,因此同一个点的平均乘法次数将更少。

所以应用中还是计算旋转矩阵进行旋转变换更好!

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐