🦉

クォータニオン勉強録

に公開

クォータニオン(四元数)について自分なりに勉強したことをまとめる

クォータニオンとは

そもそもクォータニオンとは.一つの数の種類である.
自然数,整数,有理数などと同じように,四元数という数が存在する.

クォータニオンを学ぶ前に,複素数の復習をするとよい.

復習 -複素数-

複素数平面では,\frac{\pi}{2}ラジアン回転させることを,iを掛け算することで表すことができた.

同様に,複素平面の単位円上にある任意の点を二乗すると,回転角は倍角になった.

例)(\cos\frac{\pi}{4}+i\sin\frac{\pi}{4})^2 = i

三乗すると三倍角に,四乗すると四倍角になる.

考えてみてほしい.デカルト座標系で回転を表そうと思ったら,例えば線形代数を覚えているのなら,回転行列を掛け合わせる必要があった.
それが,i倍するだけで回転を表せてしまうのだから,複素数というのは2次元の回転を表すのに非常に適しているといえるだろう.

また,複素平面では,単位円上の任意の点を,

\cos\theta+i\sin\theta

と表すことができた.

ここまでの内容を覚えておくと,クォータニオンに入るのが少し楽になる.

導入

復習の部分で,複素数は2次元の回転表現に非常に適していると述べた.
ウィリアム・ローワン・ハミルトン(ハミルトン閉路問題とかで出てくる人)もそのように考え,これを3次元の回転表現に拡張できないかと考えた.
そして,虚数を3つに増やすことで,3次元の回転表現を単純な掛け算で表せることに気が付いた.

以下にその概要を示す.クォータニオンをqとし,実部を\omega, 虚部の係数をa, b, cとすると,

\begin{equation} q = \omega + a\textcolor{#E69F00}i + b\textcolor{#56B4E9}j + c\textcolor{#009E73}k \tag{1} \end{equation}

で表される.また,虚数単位i, j, kはそれぞれ

\textcolor{#E69F00}i^2 = -1, \textcolor{#56B4E9}j^2= -1, \textcolor{#009E73}k^2 = -1 \\[3pt] \textcolor{#E69F00}i\textcolor{#56B4E9}j = -\textcolor{#56B4E9}j\textcolor{#E69F00}i = \textcolor{#009E73}k \\[3pt] \textcolor{#56B4E9}j\textcolor{#009E73}k = -\textcolor{#009E73}k\textcolor{#56B4E9}j = \textcolor{#E69F00}i \\[3pt] \textcolor{#009E73}k\textcolor{#E69F00}i = -\textcolor{#E69F00}i\textcolor{#009E73}k = \textcolor{#56B4E9}j \\[3pt] \textcolor{#E69F00}i\textcolor{#56B4E9}j\textcolor{#009E73}k = -1

を満たす.

これだけ見ると項が多くてわかりづらいように感じるが,実部と虚部に分かれている点は複素数と同じである.

クォータニオンの演算

クォータニオンは掛け算において群になっている.クォータニオンの集合を\mathbb{H}とすると,(\mathbb{H}, \cdot)と表せる.

  1. 単位元がある

    実部のみが1で,虚部が全て0になっているクォータニオンが単位元である.Iと表され,単位クォータニオンと呼ばれる.

  2. 逆元がある

    演算すると単位元になるような,逆クォータニオンが存在する.
    逆クォータニオンを作るには,共役のクォータニオンを元のクォータニオンのノルムで割れば良い.
    逆クォータニオンはq^{-1},共役のクォータニオンはq^*,ノルムは\|q\|と書く.(1)の式の共役,ノルム,逆クォータニオンは次のように計算できる.

    q^* = \omega - a\textcolor{#E69F00}i -b\textcolor{#56B4E9}j - c\textcolor{#009E73}k\\[6pt] \|q\| = \sqrt{\omega^2 + a^2 + b^2 + c^2} \\[4pt] q^{-1} = \frac{q^*}{\|q\|}
  3. 結合法則が成り立つ

    \forall q_0, q_1, q_2について,

    q_0 \cdot (q_1 \cdot q_2) = (q_0 \cdot q_1) \cdot q_2

    が成り立つ.

ただし,クォータニオンは非可換群なので,\forall q_0, q_1について,

q_0 \cdot q_1 \neq q_1 \cdot q_0

となる.


回転表現の種類

次の章に行く前に,回転表現の種類について触れておく.

回転の表現方法は大まかに二種類ある.オイラー角によるものと,クォータニオンによるものだ.

オイラー角では,(\theta_x, \theta_y, \theta_z)の三種類の変数で回転を表すことができ,x軸に\theta_x回転,y軸に\theta_y回転,z軸に\theta_z回転するというような表現になる.

ただ回転を表すだけならば,こちらの方がより直感的で分かりやすいのだが,オイラー角による回転にはいくつか欠点がある.オイラー角による回転は,ジンバルロックが発生する.

ジンバルロックとは

オイラー角による回転表現は,回転させる順番が大事になる.
例として,Unityでは,z→x→yの順で回転させる.
この時,x軸にのみ\frac{\pi}{2}回転すると,z軸とy軸が重なってしまい,z軸回転とy軸回転が一致してしまう.

字面だけ見てもわからないと思うので,動画を探すことをお勧めする.

個人的には,swapを2変数でやろうとした時と同じような問題が起こっているのかなという印象を持った.片方の変数が上書きされて参照できなくなってしまう.みたいな.

また,オイラー角では,1つの物体を回転させるのに,x軸y軸z軸の計3回回さなければならず,計算量が増える.

一方,クォータニオンを用いた回転表現は,任意の方向に回転軸を取って,その回転軸に対して\theta回転するというような表現になる.こうすることで,一つの物体を回すのに1回の回転で達成することができる.

このやり方の場合,ジンバルロックは発生しない.また,複素数の時と同じように,掛け算をすることで回転を表現できるため,クォータニオンはコンピュータグラフィックスなどで重宝される.

クォータニオンによる回転表現

ここからは,実際どのような式を用いて回転を表現するのかを見ていく.

クォータニオンで回転表現をする時は,複素数の時と同じように,単位球上を動かす.
そのため,単位球上の任意の点を表すクォータニオンはこのように表現される.

\cos\frac{\theta}{2} + \begin{pmatrix} \textcolor{#E69F00}in_x \\ \textcolor{#56B4E9}jn_y \\ \textcolor{#009E73}kn_z \end{pmatrix} \sin\frac{\theta}{2}

ここで,n_x, n_y, n_z

n_x^2 + n_y^2 + n_z^2 = 1

となる任意の実数である.

これは,複素平面の単位円上の任意の点を表す式とよく似ているが,
複素数の時はiで済んでいた部分が,四元数では

\begin{pmatrix} \textcolor{#E69F00}in_x & \textcolor{#56B4E9}jn_y & \textcolor{#009E73}kn_z \end{pmatrix}^\intercal

になっていたり,複素数の時は\thetaだった部分が,四元数では\frac{\theta}{2}になっていたり.いくつか相違点がある.

前者は,虚数単位が3つに増えたためであり,それぞれの虚数の係数n_x, n_y, n_zは,回転軸を表す三次元ベクトルと見ることができる.例えば,

\begin{pmatrix} \textcolor{#E69F00}i\frac{1}{\sqrt{2}} & \textcolor{#56B4E9}j\frac{1}{\sqrt{2}} & \textcolor{#009E73}k0 \end{pmatrix}^\intercal

なら,x-y平面に対して\frac{\pi}{4}傾いているベクトルを回転軸とすることになる.

後者については,まあ一言で言えば辻褄合わせなのだが.それだけだと説明として味気がないので,補足を入れておく.

補足

クォータニオンには二価性という性質がある.二周してようやく元に戻ってくるというような性質だ[1].逆に言えば,二周しないと絶対に元には戻って来れないのだ.この性質により,私たちの考える2\piとクォータニオンで表される2\piではズレが生じる.そのズレを修正するために,\frac{\theta}{2}になっている.


ベクトルの回転

さて,任意の3次元ベクトルを回転させるにはどうすれば良いだろう.

クォータニオン同士の掛け算はできるが,クォータニオンとベクトルの掛け算は定義されていないので,どうしても無理な気もする.

だがこれを,ベクトルを無理やりクォータニオンに変換することで解決する.

例えば,(x, y, z)^\intercalという3次元ベクトルがあったなら,

q_v = x\textcolor{#E69F00}i + y\textcolor{#56B4E9}j + z\textcolor{#009E73}k

とする.ちなみに,このように実部が0のクォータニオンは純粋クォータニオンと呼ばれる.

この,ベクトルから作られたクォータニオンと,回転を表すクォータニオンをかけることで,回転させた後のベクトルを取り出すことができる.

ただし,q \cdot q_vとしただけでは,計算結果が純粋クォータニオンにならず,ベクトルを取り出すことができない.なので,

q \cdot q_v \cdot q^*

とする必要がある.こうすることで,純粋クォータニオンを得ることができ,ベクトルに直すことができる.これは,線形代数で扱った対角化と似ているように思う.

逆に,あるベクトルAから,あるベクトルBに移動させるような回転を表すクォータニオンを知りたければ,ベクトルA,Bの内積と外積を取れば良い.

内積と外積についてはまた別のところにまとめるつもりだが,ざっくりいうと,内積で回転角度.外積で回転軸を出すことができる.


姿勢の回転

実際によく用いられるのはこっちだろうと思う.(しらないけど)

一本のベクトルを回転させるだけなら,回転軸はいくらでも取れる.
しかし,三つの正規直行ベクトルを基底ベクトルとした姿勢を回転させるにはどうすれば良いだろうか.

ここでは,回転させたい基底ベクトルを相対座標系(ローカル座標系)とし,絶対に回転しない,基準となる基底ベクトルを絶対座標系(グローバル座標系)と表現する.

今度は,基底ベクトルのそれぞれの絶対座標(グローバル座標)を行列に表す.ここで,x_yは相対座標系のx軸の,絶対座標のy成分を表す.

A = \begin{bmatrix} x_x & y_x & z_x \\ x_y & y_y & z_y \\ x_z & y_z & z_z \end{bmatrix}

この時,この姿勢を表すクォータニオンはこのように表される.

\omega = \frac{1}{2}\sqrt{1 + x_x^2 + y_y^2 + z_z^2} \\[3pt] a = \frac{1}{4\omega}(y_z - z_y) \\[4pt] b = \frac{1}{4\omega}(z_x - x_z) \\[4pt] c = \frac{1}{4\omega}(x_y - y_x) \\[10pt] q_A = \omega + a\textcolor{#E69F00}i + b\textcolor{#56B4E9}j + c\textcolor{#009E73}k

このq_Aを,便宜上姿勢クォータニオンとしておこう.
上記の式の導出にはロドリゲスの回転公式を用いるのだが,これに関しては私も詳しくないので教えてください.

この姿勢クォータニオンを回転させたければ,回転を表すクォータニオンをかければ良い.

q_A' = q_A \cdot q

逆に,ある姿勢Aからある姿勢Bに移動させるような回転を表すクォーニオンが知りたければ,

q = q_B \cdot q_A^{-1}

とすれば良い.

座標系の変換ならびに回転方向の反転

上で紹介しきれなかった部分を寄せ集めた感じになってしまった.

実際にコンピュータでクォータニオンを使って何かさせようと思った時,必ず座標系の設定をする必要がある.座標系には二種類あり,右手系左手系と呼ばれている[2]

右手系で作ったクォータニオンを,左手系に持ってきてもうまくいかない.
逆もまた然りだ.

右手系から左手系にクォータニオンを変換するには,

q_{right} = \omega + a\textcolor{#E69F00}i + b\textcolor{#56B4E9}j + c\textcolor{#009E73}k \\[5pt] q_{left} = \omega - a\textcolor{#E69F00}i + b\textcolor{#56B4E9}j - c\textcolor{#009E73}k

このように,i, kの符号を反転させれば良い.

また,クォータニオンの全ての符号を反転させると,逆回転して同じ位置に移動する.

結び

今回はここまでにしておこうと思う.

クォータニオンはコンピュータグラフィックスでとてもよく用いられている数体系であり,知識として知っておいて損はないと思う.

ただ,ロボティクスなどでは,クォータニオンの二価性が問題になる場合もあるので,その場合は六元数などを検討してみるのも良いだろう.

参考文献

以下の動画・PDFを参考にした.

また,姿勢クォータニオンの部分については,chatGPTを参考にしているので,間違っている部分があるやもしれない.もし,もっと良い方法・説明があれば教えていただきたい.

脚注
  1. 例えば,メビウスの輪を考えてみてほしい.表から指を滑らせていって,一周してきたとき.その場所は初めに出発した場所の裏面になっているはずだ.さらにそこからもう一周することでようやく元出発した表面に戻ってくることができる.このように,二価性を持つものは現実世界にもたくさんある.物理の世界では,電子のスピンにニ価性があるとされているし,心理学でもニ価性という用語が出てくる. ↩︎

  2. 親指をx軸,人差し指をy軸,中指をz軸として,それぞれの手でフレミングの手の形をしてみると,右手左手の座標系を手で作ることができる.それぞれの座標系は鏡像異性体となっており,一致することはない. ↩︎

Discussion