立体の姿勢を表現するには
3DCGを扱っていると立体の姿勢を表現したいことがある。
立体の姿勢とは、立体をデフォルト状態からどう回転させたかという情報である。
拡大縮小や平行移動の情報は含まない。
では、立体の姿勢を表現するためにはどのような情報があればいいだろうか?
例えば左図の立体を右図のように回転するには何の情報があればいいだろうか?
それは、回転軸は何かという情報と、回転角度はいくらかという情報の2つである。
この2つの情報があれば、任意の回転を表現することができるのである。
回転後の座標を計算するには
立体の姿勢を表現するのに必要な情報は分かったが、これだけでは回転後の立体を描画することはできない。
回転後の立体を描画するには、デフォルト状態の立体を構成している座標$\boldsymbol{x}=\begin{pmatrix}x\\y\\z\end{pmatrix}$が回転後にどの座標$\boldsymbol{x}'=\begin{pmatrix}x'\\y'\\z'\end{pmatrix}$に位置するのかが分からなければならない。
では具体的に、回転前の座標$\boldsymbol{x}$に対応する回転後の座標$\boldsymbol{x}'$はどのようにして求めればよいのだろうか?
つまりもう少し厳密な言葉で書き直すと、3次元位置ベクトル$\boldsymbol{x}$、回転軸を表す単位ベクトル$\hat{\boldsymbol{v}}$、回転角度をラジアンで表すスカラー$\theta$があったとき、$\boldsymbol{x}$を$\hat{\boldsymbol{v}}$の周りに角$\theta$だけ回転させた座標$\boldsymbol{x}'$はどのようにして求めればいいのだろうか?
(補足: この回転は、座標系が左手系の場合、$\hat{\boldsymbol{v}}$に対して左ねじの向きに行われ、座標系が右手系の場合、$\hat{\boldsymbol{v}}$に対して右ねじの向きに行われる)
実は、四元数(英語ではquaternion)と呼ばれるものを使うと単純な数式で$\boldsymbol{x}'$を求めることができるのである。
四元数
四元数は、複素数を拡張した数学の代数である。
複素数が$a+bi$で表されるように、四元数は$a+bi+cj+dk$で表される数である。
また、複素数では$i^2=-1$であるように、四元数では$i^2=j^2=k^2=ijk=-1$という計算規則がある。
四元数は行列のような性質を持つ。
四元数では積の交換法則は成り立たない(例: $ij=-ji$)が、一方、積の結合法則や和に対する分配法則は成り立つという性質がある。
四元数は行列のような性質を持つのみならず、式を変形することで行列のように扱うことができる。
例えば、任意の四元数は$a+bi+cj+dk$で表されるが、これを変形すると$a+\begin{pmatrix}i&j&k\end{pmatrix}\begin{pmatrix}b\\c\\d\end{pmatrix}$となる。
この形で計算を行っていくことで、四元数同士の乗算など複雑な計算を比較的簡単に行っていくことができる。
四元数同士の乗算
\begin{align}
&\left(a+\begin{pmatrix}i&j&k\end{pmatrix}\begin{pmatrix}b\\c\\d\end{pmatrix}\right) \left(a'+\begin{pmatrix}i&j&k\end{pmatrix}\begin{pmatrix}b'\\c'\\d'\end{pmatrix}\right)\\
=&\left(aa'-\begin{pmatrix}b\\c\\d\end{pmatrix}\cdot\begin{pmatrix}b'\\c'\\d'\end{pmatrix}\right)+\begin{pmatrix}i&j&k\end{pmatrix}\left(a\begin{pmatrix}b'\\c'\\d'\end{pmatrix}+a'\begin{pmatrix}b\\c\\d\end{pmatrix}+\begin{pmatrix}b\\c\\d\end{pmatrix}\times\begin{pmatrix}b'\\c'\\d'\end{pmatrix}\right)
\end{align}
である。
証明
\begin{align}
&\left(a+\begin{pmatrix}i&j&k\end{pmatrix}\begin{pmatrix}b\\c\\d\end{pmatrix}\right) \left(a'+\begin{pmatrix}i&j&k\end{pmatrix}\begin{pmatrix}b'\\c'\\d'\end{pmatrix}\right)\\
=&aa'+a\begin{pmatrix}i&j&k\end{pmatrix}\begin{pmatrix}b'\\c'\\d'\end{pmatrix}+a'\begin{pmatrix}i&j&k\end{pmatrix}\begin{pmatrix}b\\c\\d\end{pmatrix}+\begin{pmatrix}i&j&k\end{pmatrix}\begin{pmatrix}b\\c\\d\end{pmatrix}\begin{pmatrix}i&j&k\end{pmatrix}\begin{pmatrix}b'\\c'\\d'\end{pmatrix}\\
=&aa'+\begin{pmatrix}i&j&k\end{pmatrix}\left(a\begin{pmatrix}b'\\c'\\d'\end{pmatrix}+a'\begin{pmatrix}b\\c\\d\end{pmatrix}\right)+\begin{pmatrix}i&j&k\end{pmatrix}\begin{pmatrix}b\\c\\d\end{pmatrix}\begin{pmatrix}i&j&k\end{pmatrix}\begin{pmatrix}b'\\c'\\d'\end{pmatrix}
\end{align}
ところで、
\begin{align*}
&\begin{pmatrix}i&j&k\end{pmatrix}\begin{pmatrix}b\\c\\d\end{pmatrix}\begin{pmatrix}i&j&k\end{pmatrix}\begin{pmatrix}b'\\c'\\d'\end{pmatrix}\\
=&-\left(\begin{pmatrix}b\\c\\d\end{pmatrix}\cdot\begin{pmatrix}b'\\c'\\d'\end{pmatrix}\right) + \begin{pmatrix}i&j&k\end{pmatrix}\left( \begin{pmatrix}b\\c\\d\end{pmatrix}\times\begin{pmatrix}b'\\c'\\d'\end{pmatrix} \right)
\end{align*}
である。(これは行列の成分を計算すれば証明できる)
なので、結局、
\begin{align}
&aa'+\begin{pmatrix}i&j&k\end{pmatrix}\left(a\begin{pmatrix}b'\\c'\\d'\end{pmatrix}+a'\begin{pmatrix}b\\c\\d\end{pmatrix}\right)+\begin{pmatrix}i&j&k\end{pmatrix}\begin{pmatrix}b\\c\\d\end{pmatrix}\begin{pmatrix}i&j&k\end{pmatrix}\begin{pmatrix}b'\\c'\\d'\end{pmatrix}\\
=&\left(aa'-\begin{pmatrix}b\\c\\d\end{pmatrix}\cdot\begin{pmatrix}b'\\c'\\d'\end{pmatrix}\right)+\begin{pmatrix}i&j&k\end{pmatrix}\left(a\begin{pmatrix}b'\\c'\\d'\end{pmatrix}+a'\begin{pmatrix}b\\c\\d\end{pmatrix}+\begin{pmatrix}b\\c\\d\end{pmatrix}\times\begin{pmatrix}b'\\c'\\d'\end{pmatrix}\right)
\end{align}
四元数で立体の姿勢を表現する
四元数を使うと以下のようにして、$\boldsymbol{x}$を$\hat{\boldsymbol{v}}$の周りに角$\theta$だけ回転させた座標$\boldsymbol{x}'$を求められることが知られている。
\begin{align}
\begin{pmatrix}i&j&k\end{pmatrix}\boldsymbol{x}'&=\left(\cos\frac{\theta}{2}+\begin{pmatrix}i&j&k\end{pmatrix}\sin\frac{\theta}{2}\hat{\boldsymbol{v}}\right)\left(\begin{pmatrix}i&j&k\end{pmatrix}\boldsymbol{x}\right)\left(\cos\frac{\theta}{2}-\begin{pmatrix}i&j&k\end{pmatrix}\sin\frac{\theta}{2}\hat{\boldsymbol{v}}\right) \tag{1}\\
&=\begin{pmatrix}i&j&k\end{pmatrix}\left((\cos\theta)\boldsymbol{x}+(1-\cos\theta)(\hat{\boldsymbol{v}}\cdot\boldsymbol{x})\hat{\boldsymbol{v}}+\sin\theta(\hat{\boldsymbol{v}}\times\boldsymbol{x})\right) \tag{2}
\end{align}
(2)式は四元数の乗算の公式を使って具体的な$\boldsymbol{x}'$を求めたものだが、注目してほしいのは(1)式の形である。
つまり回転を$\cos\frac{\theta}{2}+\begin{pmatrix}i&j&k\end{pmatrix}\sin\frac{\theta}{2}\hat{\boldsymbol{v}}$という四元数一つで表現するということにすると、回転後の座標を求める式が以下のような単純な式になるのである。(なお、共役四元数とは$\begin{pmatrix}i&j&k\end{pmatrix}$の項の符号を反転させたもの)
\text{(回転後の座標を表す四元数)}=\text{(回転を表す四元数)}\text{(回転前の座標を表す四元数)}\text{(回転を表す四元数の共役四元数)}
式がこのように単純な形であるため、回転の合成と呼ばれるものも簡単に扱うことができる。
例えば、$q_1=\cos\frac{\theta_1}{2}+\begin{pmatrix}i&j&k\end{pmatrix}\sin\frac{\theta_1}{2}\hat{\boldsymbol{v_1}}$で表現できる回転を行った後、$q_2=\cos\frac{\theta_2}{2}+\begin{pmatrix}i&j&k\end{pmatrix}\sin\frac{\theta_2}{2}\hat{\boldsymbol{v_2}}$で表現できる回転を行うという動作を一つの回転として表現したい場合がある。
これは単純に$q_2 q_1$という四元数で表現できる。
この一まとめの回転後の座標は以下のようにして単純な式で求められる。($\overline{q_2 q_1}$は$q_2 q_1$の共役四元数)
\begin{pmatrix}i&j&k\end{pmatrix}\boldsymbol{x}'=q_2 q_1\, \begin{pmatrix}i&j&k\end{pmatrix}\boldsymbol{x}\,\overline{q_2 q_1}
まとめ
四元数で立体の姿勢を表現すると、回転後の座標を計算する式が単純になり、回転の合成を簡単に行うこともできる。