ことれいのもり

クォータニオンから回転行列への変換を、数式と手計算で丁寧に導く【中編】

はじめに

「クォータニオンって難しそうだけど、仕組みを理解して自分で実装したい」

そんな方に向けて、回転行列⇔クォータニオンの仕組みを3部構成で丁寧に解説しています。


この記事は中編にあたり、クォータニオン→回転行列の変換式を手計算で導いていきます。


前編では、クォータニオンや回転行列、traceなどの変換の理解に必要な「土台となる基礎知識」を紹介しています。

まだ読んでいない方は、先にそちらから読んで頂くのがオススメです。


「最終的に目指すのは回転行列→クォータニオンの変換なのに、なぜ逆の変換からはじめるの?」と思うかもしれませんが、先にクォータニオンから回転行列を得る流れを理解しておくことで、後編の導出が驚くほど分かりやすくなります。


まずは「クォータニオンがどのように回転行列に変換されるのか?」を一緒に確認していきましょう。

本記事について(3部構成)

この記事は「回転行列→クォータニオン変換の式を自力で導出する」ことを最終目標とした、3部構成の中編です。



「導出なんて難しそう」と思うかも知れませんが、基礎知識さえ理解すれば、誰でもたどり着けるように工夫しています。

途中式を省略することなく丁寧に解説しているので、興味のあるところから読み進めてみてください。

この記事で解説する流れ

最終的には回転行列→クォータニオンの変換を目指していますが、その逆の「クォータニオン→回転行列」を求める方法を先に説明します。

なぜ逆のことを先に行なうの?と不思議に思うかもしれませんが、これには理由があります。


クォータニオンは、ある物体を回転させるために使います。

まず最初にクォータニオンを使ってベクトルを回転させその結果として得られる回転行列を導きます。

この回転行列を理解することで、「クォータニオン→回転行列」の仕組みがわかり、その後に逆の操作である「回転行列→クォータニオン」を求めることができます。


なにより、逆の仕組みを理解していると、後々出てくる数式の意味が理解しやすいです。

回りくどいですが、まずは、「クォータニオン→回転行列」を理解していきましょう!

クォータニオンから回転行列を求める

1. ベクトルをクォータニオンに変換する

クォータニオンは「ある物体を回転させるため」に使います。

ここでは、ベクトル $\overline{v} = \begin{pmatrix} v_x \ v_y \ v_z \end{pmatrix}$ を回転させるためにクォータニオンを使っていきましょう。


しかし、このままの形ではクォータニオンとして表現できません。

まずは、ベクトル $\overline{v} = \begin{pmatrix} v_x \ v_y \ v_z \end{pmatrix}$ をクォータニオンに変換します。

前回の記事で、クォータニオンは「スカラー部(実部)」と「ベクトル部(虚部)」から成ることを説明しました。


クォータニオンの表し方(実部と虚部)


ここでベクトル $\overline{v} = \begin{pmatrix} v_x \ v_y \ v_z \end{pmatrix}$ をクォータニオンに変換するには、スカラー部を0にして、ベクトル部をそのまま使います。

結果として、次のような純クォータニオンになります。


$$v = 0 + v_xi + v_yj + v_zk $$


これでベクトルがクォータニオンの形になっているから終わりじゃないの?と思うかもしれません。

実はこの形は一見クォータニオンになっているように見えますが、形だけなんです!

位置の情報をクォータニオンの形にしただけで、回転の情報はまだ含まれていません。


思い出してください。

クォータニオンは回転の情報などを $w, x, y, z$ と虚数単位を使って表していましたよね?

でも今の形はw成分がなくて、ただベクトルをクォータニオンの形に合わせただけです。

つまりここから、回転の情報を加えたベクトルの形(言い換えるならば、回転の情報を加えた純クォータニオン)にする必要があります。


まとめるとこんな感じです。


・今の状態はベクトルを純クォータニオンの形にしただけで、回転の情報を持っていない

・ここから回転の情報を持ったクォータニオンの形に変化させる

・最終的なゴールは回転の情報を持った純クォータニオン


では、次に回転情報を持たせるための計算を紹介します。

2. 回転後のベクトル $v'$ を求める

クォータニオンを使ってベクトルを回転させるためには、次の式を使います。


$$v' = q \cdot v \cdot \overline q $$


ここで、


$$\begin{align} &q: 単位クォータニオン \\ &v: 回転させたいベクトル \\ &\overline q: 共役クォータニオン \end{align} $$


を表しています。


なんでこの掛け算を行なうのか?という疑問は、実際の計算過程を追って説明していきます。

2-1. 単位クォータニオンをかける

まずは、単位クォータニオン $q$ を回転させたいベクトル $v$ にかけます。


$$v' = q \cdot v $$


$q$ と $v$ は以下の通りです。


$$\begin{align} &q = w + xi + yj + zk \\ &v = 0 + v_xi + v_yj + v_zk \end{align} $$


回転させたいベクトル $v$ は、クォータニオンの形にしただけで、ここに回転の情報は含まれていません。

単位クォータニオンをかけることで、「どんな回転をするのか」という情報が含まれます。


では実際に計算をしていきます。

ここから先はクォータニオンの積のルールに従って計算していきます。

具体的には、以下の規則です。


$$\begin{align} &i^2 = j^2 = k^2 = -1 \\ &ijk = -1 \\ &ij = -ji = k \qquad jk = -kj = i \qquad ki = -ik = j \end{align} $$


この規則を元に $q \cdot v$ のそれぞれの項を地道に掛け合わせていきます。

なおこれ以降の式では、それぞれの成分を次のように色分けして表示します。


・$\textcolor{skyblue}{w}$成分→$\textcolor{skyblue}{青}$

・$\textcolor{pink}{x}$成分→$\textcolor{pink}{ピンク}$

・$\textcolor{yellowgreen}{y}$成分→$\textcolor{yellowgreen}{緑}$

・$\textcolor{orange}{z}$成分→$\textcolor{orange}{オレンジ}$


$$\begin{align} q \cdot v &= (\textcolor{skyblue}{w}+\textcolor{pink}{xi}+\textcolor{yellowgreen}{yj}+\textcolor{orange}{zk})(\textcolor{skyblue}{0}+\textcolor{pink}{v_xi}+\textcolor{yellowgreen}{v_yj}+\textcolor{orange}{v_zk})\\ &=\textcolor{skyblue}{wv_xi + wv_yj + wv_zk} + \textcolor{pink}{xiv_xi + xiv_yj + xiv_zk} + \textcolor{yellowgreen}{yjv_xi + yjv_yj + yjv_zk} + \textcolor{orange}{zkv_xi + zkv_yj + zkv_zk} \\ &=\textcolor{skyblue}{w(v_xi+v_yj+v_zk)} + \textcolor{pink}{(-xv_x) + (xv_yk) + (-xv_zj)} + \textcolor{yellowgreen}{(-yv_xk) + (-yv_y) + (yv_zi)} + \textcolor{orange}{(zv_xj) + (-zv_yi) + (-zv_z)} \\ &= \textcolor{skyblue}{w(v_xi + v_yj + v_zk)} + \textcolor{pink}{x(-v_x + v_yk - v_zj)} + \textcolor{yellowgreen}{y(-v_xk - v_y - v_zi)} + \textcolor{orange}{z(v_xj - v_yi - v_z)} \\ &= \textcolor{skyblue}{(wv_xi+wv_yj+wv_zk)}+\textcolor{pink}{(-xv_x+xv_yk-xv_zj)}+\textcolor{yellowgreen}{(-yv_xk-yv_y+yv_zi)}+\textcolor{orange}{(zv_xj-zv_yi-zb_z)}\\ &= \textcolor{skyblue}{(-xv_x-yv_y-zv_z)}+(wv_x+yv_z-zv_y)i+(wv_y+zv_x-xv_z)j+(wv_z+xv_y-y_vx)k \end{align} $$


この計算で、元のベクトルに回転の情報が加わりました。

しかし、式の最後の形を見て分かるとおり、w成分が増えてしまっています。(式の青色の成分)

最終的に目指す形はw成分に値が入っていない純クォータニオンなので、このw成分が邪魔ですよね。

ここでさらにかけるのが、共役クォータニオンです。

2_2. 共役クォータニオンをさらにかける

次に、先程の計算結果に共役クォータニオンをかけます。


$$\begin{align} q v \cdot \overline{q} \end{align} $$


$$\begin{align} &\overline{q} = w - v_xi - v_yj - v_zk \end{align} $$


この計算によって、w成分が打ち消しあい、w成分がない純クォータニオンの形になります。


式だけを見ていると、なぜ単位クォータニオンをかけた後に共役クォータニオンをかけるのだろう?と思ってしまいますよね。

途中式を辿ることで、綺麗にw成分が消えるので、「不要なw成分を打ち消しあうためにかけるんだ!」と理解できます!

とても長いですが、頑張ってついてきてください!


なおこれ以降の式では、それぞれの成分を次のように色分けして表示します。


・$\textcolor{skyblue}{w}$成分→$\textcolor{skyblue}{青}$

・$\textcolor{Tomato}{i}$成分→$\textcolor{Tomato}{トマト}$

・$\textcolor{SeaGreen}{j}$成分→$\textcolor{SeaGreen}{深緑}$

・$\textcolor{gold}{k}$成分→$\textcolor{gold}{ゴールド}$


まず、


$$\begin{align} q \cdot \overline{v} &= \textcolor{skyblue}{(-xv_x-yv_y-zv_z)}+\textcolor{Tomato}{(wv_x+yv_z-zv_y)i}+(\textcolor{SeaGreen}{wv_y+zv_x-xv_z)j}+\textcolor{gold}{(wv_z+xv_y-y_vx)k} \\ &= \textcolor{skyblue}{s} + \textcolor{Tomato}{ai} + \textcolor{SeaGreen}{bj} + \textcolor{gold}{ck} \end{align} $$


と置き換えます。

ここで置き換える理由は、そのまま計算すると式がとんでもなく長くなるからです!


このとき、


$$\begin{align} s &= -xv_x-yv_y-zv_z \\ a &= wv_x+yv_z-zv_y \\ b &= wv_y+zv_x-xv_z \\ c &= wv_z+xv_y-y_vx \end{align} $$


です。

これをふまえて、置き換えた式で計算していきます。


$$\begin{align} q \cdot v \times \overline{q} &=(\textcolor{skyblue}{s}\textcolor{Tomato}{+ai}\textcolor{SeaGreen}{+bj}\textcolor{gold}{+ck})(w\textcolor{Tomato}{-xi}\textcolor{SeaGreen}{-yj}\textcolor{gold}{-zk}) \\ \end{align} $$


まずはスカラー部分について


$$s(w-xi-yj-zk) = \textcolor{skyblue}{sw}\textcolor{Tomato}{-sxi}\textcolor{SeaGreen}{-syj}\textcolor{gold}{-szk} $$


ベクトル部分の

・$ai$ 部分について、


$$\begin{align} ai(w-xi-yj-zk)\\ aiw &= \textcolor{Tomato}{awi} \\ ai(-xi) &= -axi^2 = \textcolor{skyblue}{ax} \\ ai(-yj) &= -ayij = \textcolor{gold}{-ayk} \\ ai(-zk) &= -azik = \textcolor{seagreen}{azj} \\ \end{align} $$


よって、


$$\textcolor{Tomato}{awi}\textcolor{skyblue}{+ax}\textcolor{gold}{-ayk}\textcolor{seagreen}{+azj} $$


・$bj$ 部分について、


$$\begin{align} bj(w-xi-yj-zk) \\ bjw &= \textcolor{seagreen}{bwj} \\ bj(-xi) &= -bxji = \textcolor{gold}{bxk} \\ bj(-yi) &= -byj^2 = \textcolor{skyblue}{by} \\ bj(-zk) &= -bzjk = \textcolor{Tomato}{-bzi} \\ \end{align} $$


よって、


$$\textcolor{seagreen}{bwj}\textcolor{gold}{+bxk}\textcolor{skyblue}{+by}\textcolor{Tomato}{-bzi} $$


・$ck$ 部分について


$$\begin{align} ck(w-xi-yj-zk) \\ ckw &= \textcolor{gold}{cwk} \\ ck(-xi) &= -cxki = \textcolor{seagreen}{-cxj} \\ ck(-yj) &= -cykj = \textcolor{Tomato}{cyi} \\ ck(-zk) &= -czk^2 = \textcolor{skyblue}{cz} \\ \end{align} $$


よって、


$$\textcolor{gold}{cwk}\textcolor{seagreen}{+cxj}\textcolor{Tomato}{-cyi}\textcolor{skyblue}{+cz} $$


ここまでをすべてまとめると、


$$\begin{align} &(\textcolor{skyblue}{sw}\textcolor{Tomato}{-sxi}\textcolor{SeaGreen}{-syj}\textcolor{gold}{-szk})+ (\textcolor{Tomato}{awi}\textcolor{skyblue}{+ax}\textcolor{gold}{-ayk}\textcolor{seagreen}{+azj})+\\ &(\textcolor{seagreen}{bwj}\textcolor{gold}{+bxk}\textcolor{skyblue}{+by}\textcolor{Tomato}{-bzi})+ (\textcolor{gold}{cwk}\textcolor{seagreen}{+cxj}\textcolor{Tomato}{-cyi}\textcolor{skyblue}{+cz}) \end{align} $$


成分ごとにわけると、

w成分:$\textcolor{skyblue}{sw+ax+by+cz}$

$i$: $\textcolor{Tomato}{-sx+aw-bz+cy}$

$j$: $\textcolor{seagreen}{-sy+az+bw-cx}$

$k$: $\textcolor{gold}{-sz-ay+bx+cw}$


ここからは各成分ごとに、置き換えた $s, a, b, c$ を戻していきます。

※色分けは省略します


[$w$成分]

$sw+ax+by+cz$


・$sw$

$$\begin{align} sw &= (-xv_x-yv_y-zv_z)\cdot w \\ &= -wxv_x-wyv_y-wzv_z \end{align} $$


・$ax$

$$\begin{align} ax &= (wv_x+yv_z-zv_y) \cdot x \\ &= wxv_x+xyv_z-xzv_y \end{align} $$


・$by$

$$\begin{align} by &= (wv_y+zv_x-xv_z) \cdot y \\ &= wyv_y + zyv_x - xyv_z \end{align} $$


・$cz$

$$\begin{align} cz &= (wv_z+xv_y-yv_x) \cdot z \\ &= wzv_z + xzv_y - yzv_x \end{align} $$


全て足し合わせると、


$$\begin{align} sw+ax+by+cz &= (-wxv_x-wyv_y-wzv_z)+(wxv_x+xyv_z-xzv_y)+(wyv_y + zyv_x - xyv_z)+(wzv_z + xzv_y - yzv_x) \\ &= (-wxv_x+wxv_x)+(-wyv_y+wyv_y)+(-wzv_z+wzv_z)+(xyv_z-xyv_z)+(-xzv_y+xzv_y)+(yzv_x-yzv_x) \\ &= 0 \end{align} $$


このように、全て打ち消しあって0になります!

これが、単位クォータニオンをかけた後に共役クォータニオンをかけた理由です!

スカラー部が0になるので、この時点で純クォータニオンになりそうなのが分かると思います。


[$i$成分]

$-sx+aw-bz+cy$


・$-sx$


$$\begin{align} -sx &= -(-xv_x-yv_y-zv_z)\cdot x \\ &= (xv_x+yv_y+zv_z)\cdot x \\ &= x^2v_x+zyv_y+xzv_z \end{align} $$

・$aw$


$$\begin{align} aw &= (wv_x+yv_z-zv_y)\cdot w \\ &= w^2v_x+wyv_z-wzv_y \end{align} $$

・$-bz$


$$\begin{align} -bz &= -(wv_y+zv_x-xv_z)\cdot z \\ &= -wzv_y-z^2v_x+xzv_z \end{align} $$

・$cy$


$$\begin{align} cy &= (wv_z+xv_y-yv_x) \cdot y \\ &= wyv_z+xyv_y-y^2v_x \end{align} $$


よって、各ベクトル($vx, vy, vz$)でまとめると、


$$\begin{align} vx:& \quad (x^2-z^2+w^2-y^2)v_x \\ &= (w^2+x^2-y^2-z^2)v_x \end{align} $$


$$\begin{align} vy:& \quad xyv_y-wzv_y-wzv_y+xyv_y\\ &= (xy-wz-wz+xy)v_y \\ &= (2xy-2wz)v_y \end{align} $$


$$\begin{align} vz:& \quad xzv_z+xzv_z+wyv_z+wyv_z \\ &= 2xzv_z+2wyv_z \\ &= (2xz+2wy)v_z \end{align} $$

[$j$成分]

$-sy+az+bw-cx$

・$-sy$

$$\begin{align} -sy &= -(-xv_x-yv_y-zv_z)\cdot y \\ &= xyv_x+y^2v_y+yzv_z \end{align} $$

・$az$

$$\begin{align} az &= (wv_x+yv_z-zv_y) \cdot z \\ &= wzv_x+yzv_z-z^2v_y \end{align} $$

・$bw$

$$\begin{align} bw &= (wv_y+zv_x-xv_z)\cdot w \\ &= w^2v_y+wzv_x-wxv_z \end{align} $$

・$-cx$

$$\begin{align} -cx &= -(wv_z+xv_y-yv_x)\cdot x\\ &= -wxv_z-x^2v_y+xyv_x \end{align} $$

よって、各ベクトル($vx, vy, vz$)でまとめると、

$$\begin{align} vx: & \quad v_yv_x+wzv_x+wzv_x+xyv_x \\ &= 2wzv_x + 2xyv_x \\ &= (2xy+2wz)v_x \end{align} $$$$\begin{align} vy: & \quad y^2v_y+w^2v_y-z^2v_y-z^2v_y \\ &= (-x^2+y^2-z^2+w^2)v_y \\ &= (w^2-x^2+y^2-z^2)v_y \end{align} $$$$\begin{align} vz: & \quad yzv_z-wxv_z+yzv_z-wxv_z \\ &= 2yzv_z-2wxv_z \\ &= (2yz-2wx)v_z \end{align} $$

[$k$成分]

$-sz-ay+bx+cw$

・$-sz$

$$\begin{align} -sz &= -(-xv_x-yv_y-zv_z)\cdot z \\ &= xv_zz+yzv_y+z^2v_z \end{align} $$

・$-ay$

$$\begin{align} -ay &= -(wv_x+yv_z-zv_y) \cdot y \\ &= -wyv_x-y^2v_z+yzv_y \end{align} $$

・$bx$

$$\begin{align} bx &= (wv_y+zv_x-xv_z) \cdot x \\ &= wxv_y+xzv_x-x^2v_z \end{align} $$

・$cw$

$$\begin{align} cw &= (wv_z+xv_y-yv_x) \cdot w \\ &= w^2v_z+wxv_y-wyv_x \end{align} $$


よって、各ベクトル($vx, vy, vz$)でまとめると、


$$\begin{align} vx: & \quad xv_xz + xzv_x - wyv_x-wyv_x \\ &= 2xzv_x - 2wyv_x \\ &= (2xz-2wy)v_x \end{align} $$


$$\begin{align} vy: & \quad yzv_y+wxv_y+yzv_y+wxv_y \\ &= 2yzv_y + 2wxv_y \\ &= (2yz+2wx)v_y \end{align} $$


$$\begin{align} vz: & \quad z^2v_z-x^2v_z-y^2v_z+w^2v_z \\ &= (-x^2-y^2+z^2+w^2)v_z \\ &= (w^2-x^2-y^2+z^2)v_z \end{align} $$


そして、ここまで計算した $v_x, v_y, v_z$ をそれぞれ行列の形で表示してみると次のようになります。


$$R= \begin{pmatrix} w^2+x^2-y^2-z^2 & 2xy-2wz & 2xz+2wy \\ 2xy+2wz & w^2-x^2+y^2-z^2 & 2yz-2wx \\ 2xz-2wy & 2yz+2wx & w^2-x^2-y^2+z^2 \end{pmatrix} \begin{pmatrix} vx\\ vy\\ vz \end{pmatrix} $$


これで、ベクトルの状態からクォータニオン→回転行列へと変換することができました。

ですが、まだ終わりではないです!

2_3. 単位クォータニオンの性質を利用する

さて、ここで思い出してほしいのは、単位クォータニオンを使って回転を表現していたということです。


前回、クォータニオンの長さは


$$|q| = \sqrt{w^2+x^2+y^2+z^2} $$


このように表せると書きました。

単位クォータニオンの場合、長さが1になるので式に当てはめると次のようになります。


$$\sqrt{w^2+x^2+y^2+z^2} = 1 $$


ここで両辺を2乗してルートを消します。

すると、次の式が導けます。


$$w^2+x^2+y^2+z^2 = 1 $$


そして、先程導いた回転行列 $R$ は、この単位クォータニオンを使って求めたものでした。

つまり、 $R$ の中に出てくる $w^2+x^2$ などの項は、この「長さ1」の性質を使ってさらに整理することができます。


・1行1列目の成分


$$w^2+x^2-y^2-z^2 $$


単位行列の長さの式から、1行1列目の成分の式にするにはどうすれば良いか考えます。

$w^2+x^2$は同じだから放置して、残った部分について

(単位行列の式) - (?) = (1行1列目の成分)

と考えると、


$$\begin{align} y^2 - 2y^2 = -y^2 \\ z^2 - 2z^2 = -z^2 \\ \end{align} $$


となるので、$-2y^2-2z^2$ 単位行列の式に足せば良さそうです。

よって、


$$\begin{align} w^2+x^2-y^2-z^2 &= (w^2+x^2+y^2+z^2) - 2y^2-2z^2 \\ &= 1- 2y^2-2z^2 \\ &= 1-2(y^2+z^2) \end{align} $$


これで、1行1列目の成分がさらに短く書き換えられました!


同様に2行2列目、3行3列目でもおこないます。


・2行2列目の成分


$$w^2-x^2+y^2-z^2 $$


これを単位行列の長さの式から、2行2列目の成分の式にするにはどうすれば良いか考えると、

$w^2+y^2$は同じだから放置して、残った部分について

(単位行列の式) - (?) = (2行2列目の成分)

と考えると、


$$\begin{align} x^2 - 2x^2 = -x^2 \\ z^2 - 2z^2 = -z^2 \end{align} $$


となるので、$-2x^2-2z^2$ 単位行列の式に足せば良さそうです。

よって、


$$\begin{align} w^2-x^2+y^2-z^2 &= (w^2+x^2+y^2+z^2) - 2x^2-2z^2 \\ &= 1-2x^2-2z^2 \\ &= 1-2(x^2+z^2) \end{align} $$

・3行3列目の成分


$$w^2-x^2-y^2+z^2 $$


これを単位行列の長さの式から、3行3列目の成分の式にするにはどうすれば良いか考えると、

$w^2+z^2$は同じだから放置して、残った部分について

(単位行列の式) - (?) = (3行3列目の成分)

と考えると、


$$\begin{align} x^2 - 2x^2 = -x^2 \\ y^2 - 2y^2 = -y^2 \end{align} $$


となるので、$-2x^2-2y^2$ 単位行列の式に足せば良さそうです。

よって、


$$\begin{align} w^2-x^2-y^2+z^2 &= (w^2+x^2+y^2+z^2) - 2x^2-2y^2 \\ &= 1-2x^2-2y^2 \\ &= 1-2(x^2+y^2) \end{align} $$


これで3つの成分を書き換えられました!

最後に全てまとめると、クォータニオン→回転行列へ変換すると次のようになります。


$$R= \begin{pmatrix} 1-2(y^2+z^2) & 2xy-2wz & 2xz+2wy \\ 2xy+2wz & 1-2(x^2+z^2) & 2yz-2wx \\ 2xz-2wy & 2yz+2wx & 1-2(x^2+y^2) \end{pmatrix} \begin{pmatrix} vx\\ vy\\ vz \end{pmatrix} $$

おわりに

クォータニオンから回転行列への変換を導出できました!

次回の後編では、今回の操作の「逆」を行って、回転行列からクォータニオンの変換について解説していきます。

次の記事はこちらから

参考リンク

この記事を作るにあたり、以下のサイトを参考にしました。

CGのための数学(Zenn)

クォータニオンと回転行列 - 理系的な戯れ