クォータニオンの回転公式 ~ハミルトンが見つけた４次元の回転ルート~

# 書いたこと

1. 3次元空間の頂点をある軸を中心に回転させる時に使われる回転公式について
    1. ロドリゲスの回転公式
    2. クォータニオンの回転公式
2. 球面線形補間が必要になる理由について

# はじめに

## ロドリゲスの回転公式とクォータニオンの回転公式の違い

名古屋から東京に行くにあたって、
自家用車で行く場合は、曲がりくねった道を通る必要があります。

![名古屋から東京へ with 自家用車.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70065/ba9d4308-8f3c-4a0b-6e39-fd3a8d783f40.png)

ですが自家用ロケットがあればどうでしょうか？

![名古屋から東京へ with 自家用ロケット_リサイズ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70065/9e575f91-c1a3-0edf-797c-0c2819daa043.png)

半分、宇宙空間を飛び、半分、宇宙空間から降りていければ、東京に行くことができるはずです。

３次元空間上の任意の頂点Pをある軸を中心に回転させるとき、ベクトル空間を使った回転を自家用車だとすれば、
クォータニオンを使った回転は、まさに自家用ロケットによる回転になります。

## 数式の表示について

* ベクトル - 矢印
* 純粋クォータニオン - 太字

例  頂点a$(x, y, z)$ 

||数式|
|:--|:--|
|ベクトル|$\vec{a} = x\vec{e_x} + y\vec{e_y} + z\vec{e_z}$|
|純粋クォータニオン|$\mathbf{a} = x\mathbf{i} + y\mathbf{j} + z\mathbf{k}$|


![空間の関係.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70065/fa9e3954-e9b5-5b89-089b-aa05b3c3dac7.jpeg)

このように３次元空間の頂点を純粋クォータニオンで対応させることで、
ロドリゲスの回転公式からクォータニオンの回転公式が得られることを明らかにします。

# 3次元空間の回転

飛行機の旋回のように、ある物体(頂点P)をある任意の軸 $\vec{a}$ 周りに $\theta$ 回転させることについて考えます。

![任意の軸による回転_リサイズ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70065/a724f8bf-6dff-63d1-31b1-f81ae5e1f316.png)

* 頂点P - 回転前の初期位置
* 頂点P' - 回転後の位置

## 回転公式

このときその公式として、以下の２つがあります。

1. ロドリゲスの回転公式
2. クォータニオンの回転公式

||ロドリゲスの回転公式|クォータニオンの回転公式|
|:--|:---|:---|
|図|![ロドリゲスの回転公式_リサイズ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70065/1926a6e9-27fd-661f-a052-f85a01b05ced.png)|![頂点の回転 with クォータニオン_リサイズ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70065/97e73519-535f-c0f7-5d3b-52ba0934b08d.png)|
|舞台|ベクトル空間|クォータニオン|
|次元|3次元|4次元|
|特徴|* 頂点を表せる<br> * 方向を表せる|* 頂点を表せる<br> * 回転を表せる|

### ロドリゲスの回転公式

一般的にコンピュータービジョンで表される空間は、数ベクトル空間が使用されます。[^1]

[^1]: 正確に言うと、それを便宜的に拡張したアフィン空間ですが、拡張部分は回転とは無関係です

この空間をそのまま使って、任意の軸を中心に頂点を回転させる公式として、ロドリゲスの回転公式が使われます。

---

ロドリゲスの回転公式

```math:
\begin{multline}
\vec{P}' = \vec{a}\;(\vec{a}\cdot\vec{P}) + (\vec{P} - \vec{a}\;(\vec{a}\cdot\vec{P}))\cos\theta + (\vec{a} \times \vec{P})\sin\theta
\end{multline}
```

---

３つのベクトルの和で構成されており、この経路を図に表せば、どのように頂点P'を求めているか見ることができます。

![ロドリゲスの回転公式_リサイズ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70065/1926a6e9-27fd-661f-a052-f85a01b05ced.png)


### クォータニオンの回転公式

クォータニオンは、複素数を使った複素平面と同じように、３次元空間上の頂点を回転させることができる代数が作れないかとという過程で考え出されたものです。

[ウィリアム・ローワン・ハミルトン](https://ja.wikipedia.org/wiki/%E3%82%A6%E3%82%A3%E3%83%AA%E3%82%A2%E3%83%A0%E3%83%BB%E3%83%AD%E3%83%BC%E3%83%AF%E3%83%B3%E3%83%BB%E3%83%8F%E3%83%9F%E3%83%AB%E3%83%88%E3%83%B3)は、その代数を４次元に拡張することで、回転させる公式があることを発見したのです。

実はクォータニオンの回転公式は、ベクトル空間上のロドリゲスの回転公式をクォータニオンに変換し、こねくり回すことで、求めることが出来ます。
(従って必ず３次元の目的地P'にもどってくることが保証されます。)

では、それを早速見ていきましょう。

１. ロドリゲスの回転公式をクォータニオンに変換する

```math:
\mathbf{p}' = -\mathbf{a}\frac{\mathbf{ap} + \mathbf{pa}}{2} + (\mathbf{p} + \mathbf{a}\frac{\mathbf{ap} + \mathbf{pa}}{2})\cos\theta + \frac{\mathbf{ap} -\mathbf{pa}}{2}\sin\theta \tag{1}
```

上式の対応表

||ベクトル|クォータニオン|
|:--|:-------|:-----------------|
|①|$\vec{a} (\vec{a}\cdot\vec{P})$|$-\mathbf{a}\frac{\mathbf{ap} + \mathbf{pa}}{2}$|
|②|$(\vec{P} - \vec{a}(\vec{a}\cdot\vec{P}))\cos\theta$|$(\mathbf{p} + \mathbf{a}\frac{\mathbf{ap} + \mathbf{pa}}{2})\cos\theta$|
|③|$(\vec{A} \times \vec{P})\sin\theta$|$\frac{\mathbf{ap} -\mathbf{pa}}{2}\sin\theta$|

ベクトル空間からクォータニオンへの変換は[こちら](https://qiita.com/ysn/items/639895c61299abe72b8e)で詳解しています。

２. (1)式をこねくり回す

![rubiks_cube_woman.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70065/67d9b4c4-593a-1ad0-037e-ea42a0a61f9d.png)

<details><summary>こねくり回すと
</summary><div>

```math:
\begin{align}
\mathbf{p}' &= \mathbf{p}\cos\theta + \frac{\mathbf{ap} -\mathbf{pa}}{2}\sin\theta - \mathbf{a}\frac{\mathbf{ap} + \mathbf{pa}}{2}(1 - \cos\theta) \\
  &= p\cos\theta + \frac{ap -pa}{2}\sin\theta - \frac{a(ap + pa)}{2}(1 - \cos\theta) \\
  &= p\cos\theta + \frac{ap -pa}{2}\sin\theta - \frac{(aa)p + apa}{2}(1 - \cos\theta)  \\
  &= p\cos\theta + \frac{ap -pa}{2}\sin\theta + \frac{|a|^2p - apa}{2}(1 - \cos\theta)  \\
  &= p\cos\theta + \frac{ap -pa}{2}\sin\theta + \frac{p - apa}{2}(1 - \cos\theta)  \\
  &= p\frac{1 + \cos\theta}{2} + \frac{ap -pa}{2}\sin\theta - \frac{apa}{2}(1 - \cos\theta) \\
  &= p\cos^2\frac{\theta}{2} + (ap - pa)\sin\frac{\theta}{2}\cos \frac{\theta}{2} -apa\sin^2\frac{\theta}{2} \\
  &= \biggl( p\cos^2\frac{\theta}{2} + ap\sin\frac{\theta}{2}\cos\frac{\theta}{2} \biggr) - \biggl(pa\sin\frac{\theta}{2}\cos\frac{\theta}{2} + apa\sin^2\frac{\theta}{2}\biggr) \\
  &= \Bigl(\cos\frac{\theta}{2} + a\sin\frac{\theta}{2}\Bigr) \Bigl(p\cos\frac{\theta}{2}\Bigr) - \Bigl(\cos\frac{\theta}{2} + a\sin\frac{\theta}{2}\Bigr) \Bigl(pa\sin\frac{\theta}{2}\Bigr) \\
  &= \Bigl(\cos\frac{\theta}{2} + a\sin\frac{\theta}{2}\Bigr) \Bigl(p\cos\frac{\theta}{2} - pa\sin\frac{\theta}{2}\Bigr) \\
  &= \Bigl(\cos\frac{\theta}{2} + a\sin\frac{\theta}{2} \Bigr) \; p \; \Bigl(\cos\frac{\theta}{2} - a\sin\frac{\theta}{2}\Bigr)
\end{align}
```

</div></details>

以下の式が得られる。

```math:
\mathbf{p'} = \Bigl(\cos\frac{\theta}{2} + \mathbf{a}\sin\frac{\theta}{2} \Bigr) \; \mathbf{p} \; \Bigl(\cos\frac{\theta}{2} - \mathbf{a}
\sin\frac{\theta}{2}\Bigr)  \tag{2} 
```

(2)式において、 

```math:
\mathbf{q} = \cos\frac{\theta}{2} + \mathbf{a}\sin\frac{\theta}{2} 
```

とおくことで、クォータニオンの回転公式が得られます。

```math:
\mathbf{p'} = \mathbf{q}\mathbf{p}\mathbf{q^{-1}} \tag{3}
```

(3)式において、頂点Pと頂点P'を表す$\mathbf{p}$, $\mathbf{p'}$ は、３次元空間上の頂点です。
一方、$\mathbf{qp}$, $\mathbf{pq^{-1}}$は、実数を含むため４次元空間上の頂点になります。

実際に$\mathbf{qp}$を計算すると実数wが現れる。

```math:
\begin{align}
\mathbf{qp} &= (\cos\frac{\theta}{2} + \mathbf{a}\sin\frac{\theta}{2} 
 )\mathbf{p} \\
&= \mathbf{p}\cos\frac{\theta}{2} + \mathbf{ap}\sin\frac{\theta}{2} \\
&= \mathbf{p}\cos\frac{\theta}{2} + (w + x\mathbf{i}+y\mathbf{j} + z\mathbf{k})\sin\frac{\theta}{2} \\
&= w\sin\theta + \mathbf{p}\cos\frac{\theta}{2} + \mathbf{p''}\sin\frac{\theta}{2}
\end{align}
```

つまりハミルトンは、複素数を拡張した代数を使って３次元空間上の頂点を回転させるには、
4次元空間を通らなければならないことを発見したのです。

これは半分は４次元を飛び、半分は４次元から戻ってくるルートで回転しているといえます。
まさに$\frac{\theta}{2}$の正体でもある。

![頂点の回転 with クォータニオン.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70065/a493f70b-ad78-1dad-833d-80e30d26b7db.png)


# 球面線形補間について

従ってクォータニオンは3次元上空を飛んでいく回転であるため、3Dでアニメーションを実現する際に困ってしまいます。
PからP'まで３次元空間に存在しないためです。

つまりクォータニオンの回転公式は、**どこでもドアで、P'に移動することと同じ** だと言えます。

これでは$\theta$をフレーム単位で割って、フレーム毎に４次元世界に飛んで戻ってを繰り返す必要があります。

そこで考案されたのが、球面線形補間です。
これは３次元空間上の話であるため、ロドリゲスの回転公式を使ってP'を求めた場合でも有効です。

回転後の頂点P'を求め、ベクトル空間上において、頂点P,P'を結ぶ補間を表す頂点Ptを考えます。

![球面線形補間_リサイズ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70065/e55f70d4-7736-f9e4-de16-98cb72d1e7d7.png)

このように頂点Ptは、ベクトルの和で表せます。

```math:
P_t = k_1\vec{P} + k_2\vec{P'} \tag{4}
```

さらに図から(4)式の**k1, k2を $t\theta$ で表すことができれば** 、頂点Ptは、孤PP'上の頂点であることが保証されます。

<details><summary>これは幾何学的に求めることが出来ます
</summary><div>

k1について

![球面線形補間_k1について_リサイズ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70065/bcfb6625-9d8e-eedd-6cba-3b61d587e42f.png)

```math:
k1 = \frac{\sin(1-t)\theta}{\sin\theta}
```

k2について

![球面線形補間_k2について_リサイズ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70065/ce7ef476-5780-19a3-bcca-94808729e7ee.png)

```math:
k2 = \frac{\sin t\theta}{\sin\theta}
```

</div></details>

```math:
\vec{P_t} =  \frac{\sin(1-t)\theta}{\sin\theta}\vec{P} +  \frac{\sin t\theta}{\sin\theta}\vec{P'}
```

# まとめ

* クォータニオンの回転公式は、４次元を通る回転である
* クォータニオンは、4次元を通る回転であるため、その補間が必要となる。(球面線形補間)

# 参考書籍

* [四元数の発見](https://www.amazon.co.jp/%E5%9B%9B%E5%85%83%E6%95%B0%E3%81%AE%E7%99%BA%E8%A6%8B-%E7%9F%A2%E9%87%8E-%E5%BF%A0/dp/4875253141)
* [ゲームプログラミングのための3Dグラフィックス数学](https://www.amazon.co.jp/%E3%82%B2%E3%83%BC%E3%83%A0%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE3D%E3%82%B0%E3%83%A9%E3%83%95%E3%82%A3%E3%83%83%E3%82%AF%E3%82%B9%E6%95%B0%E5%AD%A6-Eric-Lengyel/dp/4939007375/)
* [実例で学ぶゲーム3D数学](https://www.amazon.co.jp/%E5%AE%9F%E4%BE%8B%E3%81%A7%E5%AD%A6%E3%81%B6%E3%82%B2%E3%83%BC%E3%83%A03D%E6%95%B0%E5%AD%A6-Fletcher-Dunn/dp/4873113776)