4.3 四元数
尽管四元数早在1843年就由William Rowan Hamilton爵士发明,作为复数的扩展,但直到1985年Shoemake[1633]才将它们引入计算机图形领域 1 ^1 1。四元数用于表示旋转和方位。它们在几个方面都优于欧拉角和矩阵。任何三维方向都可以表示为围绕特定轴的单次旋转。给定轴和角度表示,与四元数转换相互转换很简单,然后任一方向的欧拉角转换则具有挑战性。四元数可用于稳定和恒定的方向插值,这是欧拉角无法很好完成的。
复数有实部和虚部。每个复数由两个实数表示,第二个实数乘以 − 1 \sqrt{-1} −1。同样,四元数有四个部分。前三个值与旋转轴密切相关,旋转角度影响所有四个部分(更多可参考第4.3.2节)。每个四元数由四个实数表示,每个实数与不同的部分相关联。由于四元数有四个分量,我们选择将它们表示为向量,但为了区分它们,我们给它们戴上帽子: q ^ \hat{\rm\pmb{q}} qqq^。我们从四元数的一些数学背景开始,然后用它来构造各种有用的转换。
4.3.1 数学背景
我们从四元数的定义开始。
定义:四元数
q
^
\hat{\rm\pmb{q}}
qqq^可以通过以下方式定义,都是等价的。
q
^
=
(
q
v
,
q
w
)
=
i
q
x
+
j
q
y
+
k
q
z
+
q
w
=
q
v
+
q
w
,
q
v
=
i
q
x
+
j
q
y
+
k
q
z
=
(
q
x
,
q
y
,
q
z
)
,
i
2
=
j
2
=
k
2
=
−
1
,
j
k
=
−
k
j
=
i
,
k
i
=
−
i
k
=
j
,
i
j
=
−
j
i
=
k
.
(4.31)
\begin{aligned} \hat{\rm\pmb{q}} = ({\rm\pmb{q}}_v, q_w) = iq_x + jq_y + kq_z + q_w = {\rm\pmb{q}}_v + q_w ,\\ {\rm\pmb{q}}_v = iq_x + jq_y + kq_z = (q_x, q_y, q_z),\\ i^2 = j^2 = k^2 = −1, jk = −kj = i, ki = −ik = j, ij = −ji = k. \end{aligned} \tag{4.31}
qqq^=(qqqv,qw)=iqx+jqy+kqz+qw=qqqv+qw,qqqv=iqx+jqy+kqz=(qx,qy,qz),i2=j2=k2=−1,jk=−kj=i,ki=−ik=j,ij=−ji=k.(4.31)
变量 q w q_w qw称为四元数 q ^ \hat{\rm\pmb{q}} qqq^的实部。虚部是 q v {\rm\pmb{q}}_v qqqv,而 i i i、 j j j和 k k k称为虚数单位。
对于虚部 q v {\rm\pmb{q}}_v qqqv,我们可以使用所有法向量运算,例如加法、缩放、点积、叉积等。使用四元数的定义,推导出两个四元数 q ^ \hat{\rm\pmb{q}} qqq^和 r ^ \hat{\rm\pmb{r}} rrr^之间的乘法运算,如下所示。请注意,虚数单位的乘法是不可交换的。
乘 法 : q ^ r ^ = ( i q x + j q y + k q z + q w ) ( i r x + j r y + k r z + r w ) = i ( q y r z − q z r y + r w q x + q w r x ) + j ( q z r x − q x r z + r w q y + q w r y ) + k ( q x r y − q y r x + r w q z + q w r z ) + q w r w − q x r x − q y r y − q z r z = ( q v × r v + r w q v + q w r v , q w r w − q v ⋅ r v ) (4.32) \begin{aligned} \pmb{乘法:} \hat{\rm\pmb{q}}\hat{\rm\pmb{r}} &= (iq_x + jq_y + kq_z + q_w )(ir_x + jr_y + kr_z + r_w)\\ &= i(q_yr_z−q_zr_y + r_wq_x + q_wr_x)\\ &\quad + j(q_zr_x − q_xr_z + r_wq_y + q_wr_y )\\ &\quad + k(q_xr_y − q_yr_x + r_wq_z + q_wr_z )\\ &\quad + q_wr_w − q_xr_x − q_yr_y − q_zr_z\\ &= ({\rm\pmb{q}}_v \times {\rm\pmb{r}}_v + r_w{\rm\pmb{q}}_v + q_w{\rm\pmb{r}}_v, q_wr_w − {\rm\pmb{q}}_v \cdot {\rm\pmb{r}}_v ) \end{aligned} \tag{4.32} 乘法:乘法:乘法:qqq^rrr^=(iqx+jqy+kqz+qw)(irx+jry+krz+rw)=i(qyrz−qzry+rwqx+qwrx)+j(qzrx−qxrz+rwqy+qwry)+k(qxry−qyrx+rwqz+qwrz)+qwrw−qxrx−qyry−qzrz=(qqqv×rrrv+rwqqqv+qwrrrv,qwrw−qqqv⋅rrrv)(4.32)
从这个方程可以看出,我们同时使用叉积和点积来计算两个四元数的乘法。
除了四元数的定义,还需要加法、共轭、范数和单位元素的定义:
加 法 : q ^ + r ^ = ( q v , q w ) + ( r v , r w ) = ( q v + r v , q w + r w ) 共 轭 : q ^ ∗ = ( q v , q w ) ∗ = ( − q v , q w ) 范 数 : n ( q ^ ) = q ^ q ^ ∗ = q ^ ∗ q ^ = q v ⋅ q v + q w 2 = q x 2 + q y 2 + q z 2 + q w 2 单 位 元 素 : i ^ = ( 0 , 1 ) (4.33) \begin{aligned} \pmb{加法:} \hat{\rm\pmb{q}} + \hat{\rm\pmb{r}} = ({\rm\pmb{q}}_v, q_w) + ({\rm\pmb{r}}_v ,r_w ) = ({\rm\pmb{q}}_v + {\rm\pmb{r}}_v, q_w + r_w ) \\ \pmb{共轭:} \hat{\rm\pmb{q}}^∗ = ({\rm\pmb{q}}_v, q_w)^∗ = (−{\rm\pmb{q}}_v, q_w) \\ \pmb{范数:} n(\hat{\rm\pmb{q}}) = \sqrt{\hat{\rm\pmb{q}}\hat{\rm\pmb{q}}^*} = \sqrt{\hat{\rm\pmb{q}}^*\hat{\rm\pmb{q}}} = \sqrt{{\rm\pmb{q}}_v \cdot {\rm\pmb{q}}_v + q_w^2}\\ = \sqrt{q^2_x + q^2_y + q^2_z + q^2_w} \\ \pmb{单位元素:} \hat{\rm\pmb{i}} = (\rm\pmb{0},1) \\ \end{aligned} \tag{4.33} 加法:加法:加法:qqq^+rrr^=(qqqv,qw)+(rrrv,rw)=(qqqv+rrrv,qw+rw)共轭:共轭:共轭:qqq^∗=(qqqv,qw)∗=(−qqqv,qw)范数:范数:范数:n(qqq^)=qqq^qqq^∗=qqq^∗qqq^=qqqv⋅qqqv+qw2=qx2+qy2+qz2+qw2单位元素:单位元素:单位元素:iii^=(000,1)(4.33)
当
n
(
q
^
)
=
q
^
q
^
∗
n(\hat{\rm\pmb{q}}) = \sqrt{\hat{\rm\pmb{q}}\hat{\rm\pmb{q}}^*}
n(qqq^)=qqq^qqq^∗被简化时(结果如上所示),虚部抵消,只剩下实部。范数有时表示为
∣
∣
q
^
∣
=
n
(
q
^
)
||\hat{\rm\pmb{q}}| = n(\hat{\rm\pmb{q}})
∣∣qqq^∣=n(qqq^)[1105]。上面的结果是可以导出一个乘法逆,用
q
^
−
1
{\hat{\rm\pmb{q}}}^{-1}
qqq^−1表示。方程
q
^
−
1
q
^
=
q
^
−
1
q
^
=
1
{\hat{\rm\pmb{q}}}^{-1}{\hat{\rm\pmb{q}}}={\hat{\rm\pmb{q}}}^{-1}{\hat{\rm\pmb{q}}}=1
qqq^−1qqq^=qqq^−1qqq^=1对逆必须成立(这对于乘法逆是常见的)。我们从范数的定义推导出一个公式:
n
(
q
^
)
2
=
q
^
q
^
∗
⟺
q
^
q
^
∗
n
(
q
^
)
2
=
1
(4.34)
{n(\hat{\rm\pmb{q}})}^2 = \hat{\rm\pmb{q}}\hat{\rm\pmb{q}}^* \Longleftrightarrow \frac{\hat{\rm\pmb{q}}\hat{\rm\pmb{q}}^*}{{n(\hat{\rm\pmb{q}})}^2} = 1 \tag{4.34}
n(qqq^)2=qqq^qqq^∗⟺n(qqq^)2qqq^qqq^∗=1(4.34)
这给出了乘法逆,如下所示:
逆
:
q
^
−
1
=
1
n
(
q
^
)
2
q
^
∗
\pmb{逆:} {\hat{\rm\pmb{q}}}^{-1} = \frac{1}{{n(\hat{\rm\pmb{q}})}^2}\hat{\rm\pmb{q}}^*
逆:逆:逆:qqq^−1=n(qqq^)21qqq^∗
逆的公式使用了标量乘法,可以从方程4.3.1中看到的乘法推导出这个运算: s q ^ = ( 0 , s ) ( q v , q w ) = ( s q v , s q w ) s{\hat{\rm\pmb{q}}} = (\pmb{0}, s)({\rm\pmb{q}}_v, q_w) = (s{\rm\pmb{q}}_v, sq_w) sqqq^=(000,s)(qqqv,qw)=(sqqqv,sqw), 并且 q ^ s = ( q v , q w ) ( 0 , s ) = ( s q v , s q w ) {\hat{\rm\pmb{q}}}s = ({\rm\pmb{q}}_v, q_w)(\pmb{0}, s) = (s{\rm\pmb{q}}_v, sq_w) qqq^s=(qqqv,qw)(000,s)=(sqqqv,sqw)。这意味着标量乘法是可交换的: s q ^ = q ^ s = ( s q v , s q w ) s{\hat{\rm\pmb{q}}}={\hat{\rm\pmb{q}}}s = (s{\rm\pmb{q}}_v, sq_w) sqqq^=qqq^s=(sqqqv,sqw)。
以下规则集合很容易从定义中推导出来:
共
轭
规
则
:
(
q
^
∗
)
∗
=
q
^
(
q
^
+
r
^
)
∗
=
q
^
∗
+
r
^
∗
(
q
^
r
^
)
∗
=
r
^
∗
q
^
∗
(4.36)
\begin{aligned} \pmb{共轭规则:} (\hat{\rm\pmb{q}}^*)^* = \hat{\rm\pmb{q}} \\ (\hat{\rm\pmb{q}} + \hat{\rm\pmb{r}})^* = \hat{\rm\pmb{q}}^* + \hat{\rm\pmb{r}}^* \\ (\hat{\rm\pmb{q}}\hat{\rm\pmb{r}})^* = \hat{\rm\pmb{r}}^*\hat{\rm\pmb{q}}^* \end{aligned} \tag{4.36}
共轭规则:共轭规则:共轭规则:(qqq^∗)∗=qqq^(qqq^+rrr^)∗=qqq^∗+rrr^∗(qqq^rrr^)∗=rrr^∗qqq^∗(4.36)
范 数 规 则 : n ( q ^ ∗ ) = n ( q ^ ) n ( q ^ r ^ ) = n ( q ^ ) n ( r ^ ) (4.37) \begin{aligned} \pmb{范数规则:} n(\hat{\rm\pmb{q}}^*) = n(\hat{\rm\pmb{q}}) \\ n(\hat{\rm\pmb{q}}\hat{\rm\pmb{r}}) = n(\hat{\rm\pmb{q}})n(\hat{\rm\pmb{r}}) \\ \end{aligned} \tag{4.37} 范数规则:范数规则:范数规则:n(qqq^∗)=n(qqq^)n(qqq^rrr^)=n(qqq^)n(rrr^)(4.37)
乘 法 法 则 : 线 性 度 : p ^ ( s q ^ + t r ^ ) = s p ^ q ^ + t p ^ r ^ ( s p ^ + t q ^ ) r ^ = s p ^ r ^ + t q ^ r ^ 结 合 性 : p ^ ( q ^ r ^ ) = ( p ^ q ^ ) r ^ (4.38) \begin{aligned} \pmb{乘法法则:}\\ \pmb{线性度:} \hat{\rm\pmb{p}}(s\hat{\rm\pmb{q}} + t\hat{\rm\pmb{r}}) &= s\hat{\rm\pmb{p}}\hat{\rm\pmb{q}} + t\hat{\rm\pmb{p}}\hat{\rm\pmb{r}} \\ (s\hat{\rm\pmb{p}} + t\hat{\rm\pmb{q}})\hat{\rm\pmb{r}} &= s\hat{\rm\pmb{p}}\hat{\rm\pmb{r}} + t\hat{\rm\pmb{q}}\hat{\rm\pmb{r}} \\ \pmb{结合性:} \hat{\rm\pmb{p}}(\hat{\rm\pmb{q}}\hat{\rm\pmb{r}}) &= (\hat{\rm\pmb{p}}\hat{\rm\pmb{q}})\hat{\rm\pmb{r}} \end{aligned} \tag{4.38} 乘法法则:乘法法则:乘法法则:线性度:线性度:线性度:ppp^(sqqq^+trrr^)(sppp^+tqqq^)rrr^结合性:结合性:结合性:ppp^(qqq^rrr^)=sppp^qqq^+tppp^rrr^=sppp^rrr^+tqqq^rrr^=(ppp^qqq^)rrr^(4.38)
单位四元数
q
^
=
(
q
v
,
q
w
)
\hat{\rm\pmb{q}} = ({\rm\pmb{q}}_v, q_w)
qqq^=(qqqv,qw)使得
n
(
q
^
)
=
1
n(\hat{\rm\pmb{q}}) = 1
n(qqq^)=1。由此可知
q
^
\hat{\rm\pmb{q}}
qqq^可写作:
q
^
=
(
s
i
n
ϕ
u
q
,
c
o
s
ϕ
)
=
s
i
n
ϕ
u
q
+
c
o
s
ϕ
(4.39)
\hat{\rm\pmb{q}} = ({\rm{sin}}{\phi}{\rm\pmb{u}}_q, {\rm{cos}}{\phi}) = {\rm{sin}}{\phi}{\rm\pmb{u}}_q + {\rm{cos}}{\phi} \tag{4.39}
qqq^=(sinϕuuuq,cosϕ)=sinϕuuuq+cosϕ(4.39)
对于某个三维向量
u
q
{\rm\pmb{u}}_q
uuuq,使得
∣
∣
u
q
∣
∣
=
1
||{\rm\pmb{u}}_q|| = 1
∣∣uuuq∣∣=1,因为
n
(
q
^
)
=
n
(
s
i
n
ϕ
u
q
,
c
o
s
ϕ
)
=
s
i
n
2
ϕ
(
u
q
⋅
u
q
)
+
c
o
s
2
ϕ
=
s
i
n
2
ϕ
+
c
o
s
2
ϕ
=
1
(4.40)
n(\hat{\rm\pmb{q}}) = n({\rm{sin}}{\phi}{\rm\pmb{u}}_q, {\rm{cos}}{\phi}) = \sqrt{{\rm{sin}}^2{\phi}({\rm\pmb{u}}_q \cdot {\rm\pmb{u}}_q) + {\rm{cos}}^2{\phi}} \\ = \sqrt{{\rm{sin}}^2{\phi} + {\rm{cos}}^2{\phi}} \tag{4.40} = 1
n(qqq^)=n(sinϕuuuq,cosϕ)=sin2ϕ(uuuq⋅uuuq)+cos2ϕ=sin2ϕ+cos2ϕ=1(4.40)
当且仅当 u q ⋅ u q = 1 = ∣ ∣ u q ∣ ∣ 2 {\rm\pmb{u}}_q \cdot {\rm\pmb{u}}_q = 1 = ||{\rm\pmb{u}}_q||^2 uuuq⋅uuuq=1=∣∣uuuq∣∣2. 正如将在下一节中看到的,单位四元数非常适合以最有效的方式创建旋转和方向。但在此之前,会为单位四元数引入一些额外的操作。
对于复数,二维单位向量可以写成
c
o
s
ϕ
+
i
s
i
n
ϕ
=
e
i
ϕ
{\rm{cos}}{\phi} + i{\rm{sin}}{\phi} = e^{i\phi}
cosϕ+isinϕ=eiϕ。 四元数的等价物是
q
^
=
s
i
n
ϕ
u
q
+
c
o
s
ϕ
=
e
ϕ
u
q
(4.41)
\hat{\rm\pmb{q}} = {\rm{sin}}{\phi}{\rm\pmb{u}}_q + {\rm{cos}}{\phi} = e^{\phi{\rm\pmb{u}}_q} \tag{4.41}
qqq^=sinϕuuuq+cosϕ=eϕuuuq(4.41)
根据公式4.41,单位四元数的对数函数和幂函数为:
对
数
:
l
o
g
(
q
^
)
=
l
o
g
(
e
ϕ
u
q
)
=
ϕ
u
q
指
数
:
q
^
t
=
(
s
i
n
ϕ
u
q
+
c
o
s
ϕ
)
t
=
e
ϕ
t
u
q
=
s
i
n
(
ϕ
t
)
u
q
+
c
o
s
(
ϕ
t
)
(4.42)
\begin{aligned} \pmb{对数:} {\rm{log}}(\hat{\rm\pmb{q}}) = {\rm{log}}(e^{\phi{\rm\pmb{u}}_q}) = \phi{\rm\pmb{u}}_q \\ \pmb{指数:} \hat{\rm\pmb{q}}^t = ({\rm{sin}}{\phi}{\rm\pmb{u}}_q + {\rm{cos}}{\phi}) ^ t = e^{{\phi}t{\rm\pmb{u}}_q} = {\rm{sin}}({\phi}t){\rm\pmb{u}}_q + {\rm{cos}}({\phi}t)\\ \end{aligned} \tag{4.42}
对数:对数:对数:log(qqq^)=log(eϕuuuq)=ϕuuuq指数:指数:指数:qqq^t=(sinϕuuuq+cosϕ)t=eϕtuuuq=sin(ϕt)uuuq+cos(ϕt)(4.42)
4.3.2 四元数变换
我们现在将研究四元数集的一个子类,即单位长度的子类,称为单位四元数。关于单位四元数的最重要的事实是它们可以表示任何三维旋转,而且这种表示非常紧凑和简单。
现在我们将描述是什么使单位四元数对旋转和方向如此有用。首先,将点或向量的四个坐标
p
=
(
p
x
p
y
p
z
p
w
)
T
\rm\pmb{p} = (p_x\ p_y\ p_z\ p_w)^T
ppp=(px py pz pw)T代入四元数
p
^
\hat{\rm\pmb{p}}
ppp^的分量,并假设我们有一个单位四元数
q
^
=
(
s
i
n
ϕ
u
q
,
c
o
s
ϕ
)
\hat{\rm\pmb{q}} = ({\rm{sin}}{\phi}{\rm\pmb{u}}_q, {\rm{cos}}{\phi})
qqq^=(sinϕuuuq,cosϕ)。可以证明
q
^
p
^
q
^
−
1
(4.43)
\hat{\rm\pmb{q}}\hat{\rm\pmb{p}}\hat{\rm\pmb{q}}^{-1} \tag{4.43}
qqq^ppp^qqq^−1(4.43)
将
p
^
\hat{\rm\pmb{p}}
ppp^(以及点
p
\rm\pmb{p}
ppp)绕轴
u
q
{\rm\pmb{u}}_q
uuuq旋转角度
2
ϕ
2\phi
2ϕ。注意,由于
q
^
\hat{\rm\pmb{q}}
qqq^是一个单位四元数,
q
^
−
1
=
q
^
∗
\hat{\rm\pmb{q}}^{-1} = \hat{\rm\pmb{q}}^{*}
qqq^−1=qqq^∗。参见图4.9。
图4.9. 由单位四元数表示的旋转变换的图示, q ^ = ( s i n ϕ u q , c o s ϕ ) \hat{\rm\pmb{q}} = ({\rm{sin}}{\phi}{\rm\pmb{u}}_q, {\rm{cos}}{\phi}) qqq^=(sinϕuuuq,cosϕ)。变换围绕轴 u q {\rm\pmb{u}}_q uuuq旋转 2 ϕ 2\phi 2ϕ弧度。
q ^ \hat{\rm\pmb{q}} qqq^的任何非零实数倍数也表示相同的变换,这意味着 q ^ \hat{\rm\pmb{q}} qqq^和 − q ^ -\hat{\rm\pmb{q}} −qqq^表示相同的旋转。也就是说,取反轴 u q \rm\pmb{u}_q uuuq和实部 q w q_w qw会创建一个与原始四元数完全一样旋转的四元数。这也意味着从矩阵中提取四元数可以返回 q ^ \hat{\rm\pmb{q}} qqq^或 − q ^ -\hat{\rm\pmb{q}} −qqq^。
给定两个单位四元数 q ^ \hat{\rm\pmb{q}} qqq^和 r ^ \hat{\rm\pmb{r}} rrr^,首先应用 q ^ \hat{\rm\pmb{q}} qqq^再应用 r ^ \hat{\rm\pmb{r}} rrr^到四元数 p ^ \hat{\rm\pmb{p}} ppp^(可以解释为点 p {\rm\pmb{p}} ppp)的级联由公式 4.44 给出:
r ^ ( q ^ p ^ q ^ ∗ ) r ^ ∗ = ( r ^ q ^ ) p ^ ( r ^ q ^ ) ∗ = c ^ p ^ c ^ ∗ (4.44) \hat{\rm\pmb{r}}(\hat{\rm\pmb{q}}\hat{\rm\pmb{p}}\hat{\rm\pmb{q}}^{∗})\hat{\rm\pmb{r}}^{∗} = (\hat{\rm\pmb{r}}\hat{\rm\pmb{q}})\hat{\rm\pmb{p}}(\hat{\rm\pmb{r}}\hat{\rm\pmb{q}})^{∗} = \hat{\rm\pmb{c}}\hat{\rm\pmb{p}}\hat{\rm\pmb{c}}^{∗} \tag{4.44} rrr^(qqq^ppp^qqq^∗)rrr^∗=(rrr^qqq^)ppp^(rrr^qqq^)∗=ccc^ppp^ccc^∗(4.44)
这里, c ^ = r ^ q ^ \hat{\rm\pmb{c}} = \hat{\rm\pmb{r}}\hat{\rm\pmb{q}} ccc^=rrr^qqq^是单位四元数,表示单位四元数 q ^ \hat{\rm\pmb{q}} qqq^和 r ^ \hat{\rm\pmb{r}} rrr^的级联。
矩阵转换
由于经常需要将几种不同的变换组合起来,而且大部分都是矩阵形式,因此需要一种方法将式4.43转化为矩阵。四元数 q ^ \hat{\rm\pmb{q}} qqq^可以转换为矩阵 M q \rm\pmb{M}^q MMMq,如公式4.45[1633,1634]所示:
M q = ( 1 − s ( q y 2 + q z 2 ) s ( q x q y − q w q z ) s ( q x q z + q w q y ) 0 s ( q x q y + q w q z ) 1 − s ( q x 2 + q z 2 ) s ( q y q z − q w q x ) 0 s ( q x q z − q w q y ) s ( q y q z + q w q x ) 1 − s ( q x 2 + q y 2 ) 0 0 0 0 1 ) (4.45) {\rm\pmb{M}}^q = \left( \begin{matrix} 1 − s(q^2_y + q^2_z) & s(q_xq_y − q_wq_z) & s(q_xq_z + q_wq_y) & 0\\ s(q_xq_y + q_wq_z ) & 1 − s(q^2_x + q^2_z ) & s(q_yq_z − q_wq_x ) & 0\\ s(q_xq_z − q_wq_y) & s(q_yq_z + q_wq_x ) & 1 − s(q^2_x + q^2_y) & 0\\ 0 & 0 & 0 & 1 \end{matrix} \right) \tag{4.45} MMMq=⎝⎜⎜⎛1−s(qy2+qz2)s(qxqy+qwqz)s(qxqz−qwqy)0s(qxqy−qwqz)1−s(qx2+qz2)s(qyqz+qwqx)0s(qxqz+qwqy)s(qyqz−qwqx)1−s(qx2+qy2)00001⎠⎟⎟⎞(4.45)
在这里,标量是
s
=
2
/
(
n
(
q
^
)
)
2
s = 2/(n(\hat{\rm\pmb{q}}))^2
s=2/(n(qqq^))2。 对于单位四元数,上式可简化为:
M
q
=
(
1
−
2
(
q
y
2
+
q
z
2
)
2
(
q
x
q
y
−
q
w
q
z
)
2
(
q
x
q
z
+
q
w
q
y
)
0
2
(
q
x
q
y
+
q
w
q
z
)
1
−
2
(
q
x
2
+
q
z
2
)
2
(
q
y
q
z
−
q
w
q
x
)
0
2
(
q
x
q
z
−
q
w
q
y
)
2
(
q
y
q
z
+
q
w
q
x
)
1
−
2
(
q
x
2
+
q
y
2
)
0
0
0
0
1
)
(4.46)
{\rm\pmb{M}}^q = \left( \begin{matrix} 1 − 2(q^2_y + q^2_z) & 2(q_xq_y − q_wq_z) & 2(q_xq_z + q_wq_y) & 0\\ 2(q_xq_y + q_wq_z ) & 1 − 2(q^2_x + q^2_z ) & 2(q_yq_z − q_wq_x ) & 0\\ 2(q_xq_z − q_wq_y) & 2(q_yq_z + q_wq_x ) & 1 − 2(q^2_x + q^2_y) & 0\\ 0 & 0 & 0 & 1 \end{matrix} \right) \tag{4.46}
MMMq=⎝⎜⎜⎛1−2(qy2+qz2)2(qxqy+qwqz)2(qxqz−qwqy)02(qxqy−qwqz)1−2(qx2+qz2)2(qyqz+qwqx)02(qxqz+qwqy)2(qyqz−qwqx)1−2(qx2+qy2)00001⎠⎟⎟⎞(4.46)
一旦构造了四元数,就不需要计算三角函数,因此转换过程在实践中很有效率。
从正交矩阵
M
q
\rm\pmb{M}^q
MMMq到单位四元数
q
^
\hat{\rm\pmb{q}}
qqq^的逆转换要复杂一些。此过程的关键是与公式4.46中的矩阵的以下差异:
m
21
q
−
m
12
q
=
4
q
w
q
x
m
02
q
−
m
20
q
=
4
q
w
q
y
m
10
q
−
m
01
q
=
4
q
w
q
z
(4.47)
\begin{aligned} m^q_{21} − m^q_{12} = 4q_wq_x \\ m^q_{02} − m^q_{20} = 4q_wq_y \\ m^q_{10} − m^q_{01} = 4q_wq_z \\ \end{aligned} \tag{4.47}
m21q−m12q=4qwqxm02q−m20q=4qwqym10q−m01q=4qwqz(4.47)
这些方程的含义是,如果
q
w
q_w
qw已知,则可以计算向量
v
q
{\rm\pmb{v}}_q
vvvq的值,从而推导出
q
^
\hat{\rm\pmb{q}}
qqq^。
M
q
\rm\pmb{M}^q
MMMq的迹由下式计算:
t
r
(
M
q
)
=
4
−
2
s
(
q
x
2
+
q
y
2
+
q
z
2
)
=
4
(
1
−
q
x
2
+
q
y
2
+
q
z
2
q
x
2
+
q
y
2
+
q
z
2
+
q
w
2
)
=
4
q
w
2
q
x
2
+
q
y
2
+
q
z
2
+
q
w
2
=
4
q
w
2
(
n
(
q
^
)
)
2
(4.48)
\begin{aligned} tr(\rm\pmb{M}^q) &= 4 - 2s(q^2_x + q^2_y + q^2_z) = 4(1-\frac{q^2_x + q^2_y + q^2_z}{q^2_x + q^2_y + q^2_z+q^2_w}) \\ &= \frac{4q^2_w}{q^2_x + q^2_y + q^2_z+q^2_w} = \frac{4q^2_w}{(n(\hat{\rm\pmb{q}}))^2} \end{aligned} \tag{4.48}
tr(MMMq)=4−2s(qx2+qy2+qz2)=4(1−qx2+qy2+qz2+qw2qx2+qy2+qz2)=qx2+qy2+qz2+qw24qw2=(n(qqq^))24qw2(4.48)
对于单位四元数来说,可得出以下转换:
q
w
=
1
2
t
r
(
M
q
)
q
x
=
(
m
21
q
−
m
12
q
)
4
q
w
q
y
=
(
m
02
q
−
m
20
q
)
4
q
w
q
z
=
(
m
10
q
−
m
01
q
)
4
q
w
(4.49)
\begin{aligned} q_w &= \frac{1}{2}\sqrt{tr({\rm\pmb{M}}^q)} \\ q_x &= \frac{(m^q_{21} − m^q_{12})}{4q_w} \\ q_y &= \frac{(m^q_{02} − m^q_{20})}{4q_w} \\ q_z &= \frac{(m^q_{10} − m^q_{01})}{4q_w} \\ \end{aligned} \tag{4.49}
qwqxqyqz=21tr(MMMq)=4qw(m21q−m12q)=4qw(m02q−m20q)=4qw(m10q−m01q)(4.49)
为了有一个数值稳定的程序[1634],小数除法应该被避免。因此,首先设置
t
=
q
w
2
−
q
x
2
−
q
y
2
−
q
z
2
t = q^2_w − q^2_x − q^2_y − q^2_z
t=qw2−qx2−qy2−qz2,由此得出:
m
00
=
t
+
2
q
x
2
m
11
=
t
+
2
q
y
2
m
22
=
t
+
2
q
z
2
u
=
m
00
+
m
11
+
m
22
=
t
+
2
q
w
2
(4.50)
\begin{aligned} m_{00} &= t + 2q^2_x \\ m_{11} &= t + 2q^2_y \\ m_{22} &= t + 2q^2_z \\ u &= m_{00} + m_{11} + m_{22} = t + 2q^2_w\\ \end{aligned} \tag{4.50}
m00m11m22u=t+2qx2=t+2qy2=t+2qz2=m00+m11+m22=t+2qw2(4.50)
这反过来意味着
m
00
m_{00}
m00、
m
11
m_{11}
m11、
m
22
m_{22}
m22和
u
u
u中的最大值,确定了
q
x
q_x
qx、
q
y
q_y
qy、
q
z
q_z
qz和
q
w
q_w
qw中最大的。如果
q
w
q_w
qw最大,则使用公式4.49导出四元数。否则,我们注意到以下内容成立:
4
q
x
2
=
+
m
00
−
m
11
−
m
22
+
m
33
4
q
y
2
=
−
m
00
+
m
11
−
m
22
+
m
33
4
q
z
2
=
−
m
00
−
m
11
+
m
22
+
m
33
4
q
w
2
=
t
r
(
M
q
)
(4.51)
\begin{aligned} 4q^2_x &= +m_{00} − m_{11} − m_{22} + m_{33} \\ 4q^2_y &= −m_{00} + m_{11} − m_{22} + m_{33} \\ 4q^2_z &= −m_{00} − m_{11} + m_{22} + m_{33} \\ 4q^2_w &= tr({\rm\pmb{M}}^q)\\ \end{aligned} \tag{4.51}
4qx24qy24qz24qw2=+m00−m11−m22+m33=−m00+m11−m22+m33=−m00−m11+m22+m33=tr(MMMq)(4.51)
然后使用上述适当方程计算 q x q_x qx、 q y q_y qy和 q z q_z qz中的最大值,然后使用方程4.47计算 q ^ \hat{\rm\pmb{q}} qqq^的其余分量。Schüler[1588]提出了一种无分支但使用四个平方根的变体。
球面线性插值
球面线性插值是一种运算,在给定两个单位四元数 q ^ \hat{\rm\pmb{q}} qqq^和 r ^ \hat{\rm\pmb{r}} rrr^以及参数 t ∈ [ 0 , 1 ] t∈[0,1] t∈[0,1]的情况下,计算插值四元数。例如,这对于动画对象很有用。它对于插值相机方向没有用,因为相机的“向上”矢量在插值过程中可能会倾斜,通常是一种干扰效果。
此运算的代数形式由复合四元数
s
^
\hat{\rm\pmb{s}}
sss^表示,如下所示:
s
^
(
q
^
,
r
^
,
t
)
=
(
r
^
q
^
−
1
)
t
q
^
(4.52)
\hat{\rm\pmb{s}}(\hat{\rm\pmb{q}},\hat{\rm\pmb{r}},t) = (\hat{\rm\pmb{r}}\hat{\rm\pmb{q}}^{−1})^t\hat{\rm\pmb{q}} \tag{4.52}
sss^(qqq^,rrr^,t)=(rrr^qqq^−1)tqqq^(4.52)
但是,对于软件实现,以下形式更合适,其中slerp代表球面线性插值:
s
^
(
q
^
,
r
^
,
t
)
=
s
l
e
r
p
(
q
^
,
r
^
,
t
)
=
s
i
n
(
ϕ
(
1
−
t
)
)
s
i
n
ϕ
q
^
+
s
i
n
(
ϕ
t
)
s
i
n
ϕ
r
^
(4.53)
\hat{\rm\pmb{s}}(\hat{\rm\pmb{q}},\hat{\rm\pmb{r}},t) = slerp(\hat{\rm\pmb{q}},\hat{\rm\pmb{r}},t) = \frac{sin(\phi(1-t))}{sin\phi}\hat{\rm\pmb{q}} + \frac{sin(\phi t)}{sin\phi}\hat{\rm\pmb{r}} \tag{4.53}
sss^(qqq^,rrr^,t)=slerp(qqq^,rrr^,t)=sinϕsin(ϕ(1−t))qqq^+sinϕsin(ϕt)rrr^(4.53)
为了计算这个方程所需的φ,可以使用以下式子: c o s ϕ = q x r x + q y r y + q z r z + q w r w cos\phi = q_xr_x + q_yr_y + q_zr_z + q_wr_w cosϕ=qxrx+qyry+qzrz+qwrw[325]。对于 t ∈ [ 0 , 1 ] t∈[0,1] t∈[0,1],slerp函数计算(唯一的 2 ^2 2)插值四元数,它们共同构成四维单位球面上从 q ^ ( t = 0 ) \hat{\rm\pmb{q}}(t = 0) qqq^(t=0)到 r ^ ( t = 1 ) \hat{\rm\pmb{r}}(t = 1) rrr^(t=1)的最短弧。圆弧位于由 q ^ \hat{\rm\pmb{q}} qqq^, r ^ \hat{\rm\pmb{r}} rrr^和原点给出的平面与四维单位球面的交点形成的圆上。如图 4.10 所示。计算出的旋转四元数以恒定速度绕固定轴旋转。像这样的曲线具有恒定的速度,因此加速度为零,称为测地曲线[229]。过原点的平面与球面的交点在球面上形成一个大圆,这个圆的一部分称为大圆弧。
图4.10. 单位四元数表示为单位球面上的点。函数slerp用于四元数之间的插值,插值的路径是球体上的一个大圆弧。请注意,从 q ^ 1 \hat{\rm\pmb{q}}_1 qqq^1到 q ^ 2 \hat{\rm\pmb{q}}_2 qqq^2和从 q ^ 1 \hat{\rm\pmb{q}}_1 qqq^1到 q ^ 3 \hat{\rm\pmb{q}}_3 qqq^3到 q ^ 2 \hat{\rm\pmb{q}}_2 qqq^2的插值不是一回事,即使它们到达相同的方向。
slerp函数非常适合在两个方位之间进行插值,并且有良好的效果(固定轴,恒速)。使用多个欧拉角进行插值时,情况并非如此。实际上,直接计算slerp是一项涉及调用三角函数的昂贵操作。Malysau[1114]讨论了将四元数集成到渲染管线中。他指出,当不使用slerp而只是在像素着色器中对四元数进行归一化时,对于90度角,三角形方向的误差最大为 4度。光栅化三角形时,此误差率是可以接受的。Li[1039, 1040]提供了更快的增量方法来计算slerps,并且不会牺牲任何准确性。Eberly[406]提出了一种仅使用加法和乘法计算slerps的快速技术。
当有两个以上的方向时,比如 q ^ 0 , q ^ 1 , . . . , q ^ n \hat{\rm\pmb{q}}_0,\hat{\rm\pmb{q}}_1,...,\hat{\rm\pmb{q}}_n qqq^0,qqq^1,...,qqq^n,并且我们想要从 q ^ 0 \hat{\rm\pmb{q}}_0 qqq^0到 q ^ 1 \hat{\rm\pmb{q}}_1 qqq^1到 q ^ 2 \hat{\rm\pmb{q}}_2 qqq^2,依此类推直到 q ^ n − 1 \hat{\rm\pmb{q}}_{n-1} qqq^n−1,可以直接使用slerp。现在,当我们接近 q ^ i \hat{\rm\pmb{q}}_i qqq^i时,我们将使用 q ^ i − 1 \hat{\rm\pmb{q}}_{i-1} qqq^i−1和 q ^ i \hat{\rm\pmb{q}}_i qqq^i作为 slerp 的参数。通过 q ^ i \hat{\rm\pmb{q}}_i qqq^i后,我们将使用 q ^ i \hat{\rm\pmb{q}}_i qqq^i和 q ^ i + 1 \hat{\rm\pmb{q}}_{i+1} qqq^i+1作为 slerp 的参数。这将导致方向插值中出现突然的抖动,如图4.10所示。这类似于当点被线性插值时发生的情况;参见第720页图17.3的右上部分。有些读者可能希望在阅读第17章中的样条曲线后重新阅读以下段落。
更好的插值方法是使用某种样条。我们在
q
^
i
\hat{\rm\pmb{q}}_i
qqq^i和
q
^
i
+
1
\hat{\rm\pmb{q}}_{i+1}
qqq^i+1之间引入了四元数
a
^
i
\hat{\rm\pmb{a}}_i
aaa^i和
a
^
i
+
1
\hat{\rm\pmb{a}}_{i+1}
aaa^i+1。球面三次插值可以在四元数
q
^
i
\hat{\rm\pmb{q}}_i
qqq^i,
a
^
i
\hat{\rm\pmb{a}}_i
aaa^i,
a
^
i
+
1
\hat{\rm\pmb{a}}_{i+1}
aaa^i+1和
q
^
i
+
1
\hat{\rm\pmb{q}}_{i+1}
qqq^i+1的集合内定义。令人惊讶的是,这些额外的四元数计算如下[404]
3
^3
3:
a
^
i
=
q
^
i
e
x
p
[
−
l
o
g
(
q
^
i
−
1
q
^
i
−
1
)
+
l
o
g
(
q
^
i
−
1
q
^
i
+
1
)
4
]
(4.54)
\hat{\rm\pmb{a}}_i = \hat{\rm\pmb{q}}_i \, {\rm{exp}} \, [-\frac{{\rm{log}}(\hat{\rm\pmb{q}}^{-1}_{i}\hat{\rm\pmb{q}}_{i-1})+{\rm{log}}(\hat{\rm\pmb{q}}^{-1}_{i}\hat{\rm\pmb{q}}_{i+1})}{4}]\tag{4.54}
aaa^i=qqq^iexp[−4log(qqq^i−1qqq^i−1)+log(qqq^i−1qqq^i+1)](4.54)
通过三次样条平滑算法,
q
^
i
\hat{\rm\pmb{q}}_i
qqq^i和
a
^
i
\hat{\rm\pmb{a}}_i
aaa^i用来对四元数进行球面插值,如公式4.55所示:
s
q
u
a
d
(
q
^
i
,
q
^
i
+
1
,
a
^
i
,
a
^
i
+
1
,
t
)
=
s
l
e
r
p
(
s
l
e
r
p
(
q
^
i
,
q
^
i
+
1
,
t
)
,
s
l
e
r
p
(
a
^
i
,
a
^
i
+
1
,
t
)
,
2
t
(
1
−
t
)
)
(4.55)
{\rm{squad}}(\hat{\rm\pmb{q}}_i,\hat{\rm\pmb{q}}_{i+1},\hat{\rm\pmb{a}}_i,\hat{\rm\pmb{a}}_{i+1},t) = \\ {\rm{slerp}}({\rm{slerp}}(\hat{\rm\pmb{q}}_i,\hat{\rm\pmb{q}}_{i+1},t),{\rm{slerp}}(\hat{\rm\pmb{a}}_i,\hat{\rm\pmb{a}}_{i+1},t),2t(1 − t)) \tag{4.55}
squad(qqq^i,qqq^i+1,aaa^i,aaa^i+1,t)=slerp(slerp(qqq^i,qqq^i+1,t),slerp(aaa^i,aaa^i+1,t),2t(1−t))(4.55)
从上面可以看出,squad函数是使用slerp从同样的球面插值构建的(第17.1.1节有关点的重复线性插值的信息)。插值将通过初始方向 q ^ i , i ∈ [ 0 , . . . , n − 1 ] \hat{\rm\pmb{q}}_i,i ∈ [0,...,n − 1] qqq^i,i∈[0,...,n−1],但不通过 a ^ i \hat{\rm\pmb{a}}_i aaa^i——这些用于指示初始方向的切线方向。
从一个向量到另一个向量的旋转
一个常见的操作是通过尽可能最短的路径从一个方向
s
\rm\pmb{s}
sss转换到另一个方向
t
\rm\pmb{t}
ttt。四元数的数学运算极大地简化了这个过程,并显示了四元数与这种表示的密切关系。首先,将
s
\rm\pmb{s}
sss和
t
\rm\pmb{t}
ttt归一化。然后计算单位旋转轴,称为
u
\rm\pmb{u}
uuu,计算为
u
=
(
s
×
t
)
/
∣
∣
s
×
t
∣
∣
\rm\pmb{u} = (\pmb{s} × \pmb{t})/||\pmb{s} × \pmb{t}||
uuu=(sss×ttt)/∣∣sss×ttt∣∣。 接下来,
e
=
s
⋅
t
=
c
o
s
(
2
ϕ
)
e = {\rm\pmb{s}} · {\rm\pmb{t}} = cos(2\phi)
e=sss⋅ttt=cos(2ϕ)和
∣
∣
s
×
t
∣
∣
=
s
i
n
(
2
ϕ
)
||{\rm\pmb{s}} × {\rm\pmb{t}}|| = sin(2\phi)
∣∣sss×ttt∣∣=sin(2ϕ),其中
2
ϕ
2\phi
2ϕ是
s
{\rm\pmb{s}}
sss和
t
{\rm\pmb{t}}
ttt之间的角度。表示从
s
\rm\pmb{s}
sss到
t
\rm\pmb{t}
ttt的旋转的四元数是
q
^
=
(
s
i
n
ϕ
u
,
c
o
s
ϕ
)
\hat{\rm\pmb{q}} = (sin{\phi}{\rm\pmb{u}}, cos{\phi})
qqq^=(sinϕuuu,cosϕ)。事实上,使用半角关系和三角恒等式简化
q
^
=
(
s
i
n
ϕ
s
i
n
2
ϕ
(
s
×
t
)
,
c
o
s
ϕ
)
\hat{\rm\pmb{q}} = (\frac{sin{\phi}}{sin2{\phi}}({\rm\pmb{s}}×{\rm\pmb{t}}), cos{\phi})
qqq^=(sin2ϕsinϕ(sss×ttt),cosϕ),可得出[1197]:
q
^
=
(
q
v
,
q
w
)
=
(
1
2
(
1
+
e
)
(
s
×
t
)
,
2
(
1
+
e
)
2
)
(4.56)
\hat{\rm\pmb{q}} = ({\rm\pmb{q}}_v,q_w) = (\frac{1}{\sqrt{2(1+e)}}({\rm\pmb{s}}×{\rm\pmb{t}}), \frac{\sqrt{2(1+e)}}{2}) \tag{4.56}
qqq^=(qqqv,qw)=(2(1+e)1(sss×ttt),22(1+e))(4.56)
以这种方式直接生成四元数(相对于标准化叉积 s × t {\rm\pmb{s}}×{\rm\pmb{t}} sss×ttt)避免了当 s {\rm\pmb{s}} sss和 t {\rm\pmb{t}} ttt指向几乎相同的方向时的数值不稳定[1197]。当 s {\rm\pmb{s}} sss和 t {\rm\pmb{t}} ttt指向相反的方向时,两种方法都会出现稳定性问题,因为发生了除以零的情况。当检测到这种特殊情况时,任何垂直于 s {\rm\pmb{s}} sss的旋转轴都可以用来旋转到 t {\rm\pmb{t}} ttt。
有时我们需要从
s
{\rm\pmb{s}}
sss到
t
{\rm\pmb{t}}
ttt旋转的矩阵表示。在对等式4.46进行一些代数和三角简化后,旋转矩阵变为[1233]:
R
(
s
,
t
)
=
(
e
+
h
v
x
2
h
v
x
v
y
−
v
z
h
v
x
v
z
+
v
y
0
h
v
x
v
y
+
v
z
e
+
h
v
y
2
h
v
y
v
z
−
v
x
0
h
v
x
v
z
−
v
y
h
v
y
v
z
+
v
x
e
+
h
v
z
2
0
0
0
0
1
)
(4.57)
{\rm\pmb{R}}({\rm\pmb{s}}, {\rm\pmb{t}}) = \left( \begin{matrix} e + hv_x^2 & hv_xv_y − v_z & hv_xv_z + v_y & 0 \\ hv_xv_y + v_z & e + hv_y^2 & hv_yv_z − v_x & 0 \\ hv_xv_z − v_y & hv_yv_z + v_x & e + hv_z^2 & 0 \\ 0 & 0 & 0 & 1 \\ \end{matrix} \right) \tag{4.57}
RRR(sss,ttt)=⎝⎜⎜⎛e+hvx2hvxvy+vzhvxvz−vy0hvxvy−vze+hvy2hvyvz+vx0hvxvz+vyhvyvz−vxe+hvz200001⎠⎟⎟⎞(4.57)
在这个等式中,我们使用了以下中间计算:
v
=
s
×
t
e
=
c
o
s
(
2
ϕ
)
=
s
⋅
t
h
=
1
−
c
o
s
(
2
ϕ
)
s
i
n
2
(
2
ϕ
)
=
1
−
e
v
⋅
v
=
1
1
+
e
(4.58)
\begin{aligned} {\rm\pmb{v}} &= {\rm\pmb{s}} × {\rm\pmb{t}} \\ e &= cos(2{\phi}) = {\rm\pmb{s}} \cdot {\rm\pmb{t}} \\ h &= \frac{1-cos(2\phi)}{sin^2(2\phi)} = \frac{1-e}{{\rm\pmb{v}} \cdot {\rm\pmb{v}}} = \frac{1}{1+e}\\ \end{aligned} \tag{4.58}
vvveh=sss×ttt=cos(2ϕ)=sss⋅ttt=sin2(2ϕ)1−cos(2ϕ)=vvv⋅vvv1−e=1+e1(4.58)
可以看出,由于简化,所有平方根和三角函数都消失了,因此这是创建矩阵的有效方法。请注意,公式4.57的结构类似于公式4.30的结构,并注意后一种形式如何不需要三角函数。
请注意,当 s {\rm\pmb{s}} sss和 t {\rm\pmb{t}} ttt平行或接近平行时必须小心,因为这时 ∣ ∣ s × t ∣ ∣ ≈ 0 ||{\rm\pmb{s}} × {\rm\pmb{t}}|| ≈ 0 ∣∣sss×ttt∣∣≈0。如果 ϕ ≈ 0 \phi ≈ 0 ϕ≈0,那么我们可以返回单位矩阵。然而,如果 2 ϕ ≈ π 2\phi ≈ \pi 2ϕ≈π,那么我们可以绕任意轴旋转 π \pi π弧度。该轴可以是 s {\rm\pmb{s}} sss和任何其他不平行于 s {\rm\pmb{s}} sss的向量的叉积(第4.2.4节)。Möller和Hughes使用Householder矩阵以不同的方式处理这种特殊情况[1233]。
1
^1
1公平地说,Robinson[1502]在1958年使用四元数进行刚体模拟。
2
^2
2当且仅当
q
^
\hat{\rm\pmb{q}}
qqq^和
r
^
\hat{\rm\pmb{r}}
rrr^不相反。
3
^3
3Shoemake[1633]给出了另一个推导。