クォータニオン
#回転 #数学
クォータニオン (Quaternion, 四元数) とは、複素数を拡張したもの
$ i・$ j・$ kという3つの虚数単位を用いる
https://ja.wikipedia.org/wiki/四元数
定義
クォータニオンは、虚数単位$ i・$ j・$ kを用いて、
$ (x, y, z; w) = xi + yj + zk + w
で表される
$ i・$ j・$ kは、以下の関係を満たす
$ i^2 = j^2 = k^2 = ijk = -1
積は不可換
乗積表にすると、以下の通り
table:table
* 1 i j k
1 1 i j k
i i -1 k -j
j j -k -1 i
k k j -i -1
$ \begin{bmatrix} w_1 \\ x_1 \\ y_1 \\ z_1 \end{bmatrix} * \begin{bmatrix} w_2 \\ x_2 \\ y_2 \\ z_2 \end{bmatrix} = \begin{bmatrix} w_1 w_2 - x_1 x_2 - y_1 y_2 - z_1 z_2 \\ w_1 x_2 + x_1 w_2 + y_1 z_2 - z_1 y_2 \\ w_1 y_2 - x_1 z_2 + y_1 w_2 + z_1 x_2 \\ w_1 z_2 + x_1 y_2 - y_1 x_2 + z_1 w_2 \end{bmatrix}
ノルム・複素共役・逆数
ノルム
クォータニオン$ qのノルム$ \|q\|
クォータニオンの各コンポーネントを使って4次元ベクトルを作り、そのL2ノルムを出す
$ \|q\| = \sqrt{w^2 + x^2 + y^2 + z^2}
単位クォータニオン・正規化
絶対値が1のクォータニオンを単位クォータニオンと呼ぶ
クォータニオンの正規化は$ {\rm normalize}(q) = \frac{q}{\|q\|}とできる
複素共役
クォータニオン$ qの複素共役$ \bar q
$ \bar q = w - xi - yj - zk
逆数
クォータニオン$ qの逆数$ q^{-1}
$ q^{-1} = \frac{\bar q}{\|q\|^2}
単位クォータニオンのとき、$ \bar q = q^{-1}
表記
$ xi + yj + zk + wと書けば一番確実
実数部を$ s・虚数部を$ \bf vとして、$ s + \bf vや$ (s, \bf v)と表記することもしばしば
プログラミング
(x, y, z, w) の派閥と (w, x, y, z) の派閥がある
プログラミング言語やライブラリごとに異なる
xyzw は、Unity・Three.js・glam・glTFなど
wxyz は、Mathematica・numpy-quaternion・Eigenなど
筆者は、基本的には xyzw の派閥
GLSLの vec4 も xyzw の順だしね
わかりやすいように、セミコロンを用いて (x, y, z; w) という表記を用いることがあるが、正確性や伝わりやすさには自信がない
回転での利用
クォータニオンは、CG文脈において、回転によく用いられる
基本的には単位クォータニオンとして正規化して使いたい
だいたいDCCでわけわからん挙動だ~~~って絶叫しているやつは、内部的に正規化されてたり・正規化されていなくてスケールが変わっていたりしてわけわからんくなっている
クォータニオンのベクトルへの適用をする際は、
$ p = (v_x, v_y, v_z; 0)
と置いた上で
$ q^{-1} \ p \ qして、結果から$ x・$ y・$ zを取り出す
単位クォータニオンのとき、$ \bar qは逆回転を表す
Axis-Angle
回転軸を$ u・回転角を$ \thetaとしたとき、
$ u = {\rm normalize} \left( q_x, q_y, q_z \right)
$ w = \cos(\theta / 2)
$ \theta = 2\ {\rm acos}(q_w)
https://github.com/mrdoob/three.js/blob/r175/src/math/Quaternion.js#L390-L405