up:: Programming
up:: Summareading
source:: クォータニオン (Quaternion) を総整理! ~ 三次元物体の回転と姿勢を鮮やかに扱う ~ - Qiita

1. クォータニオンでやりたいこと

クォータニオンでやりたいのは、3D空間における回転と、3D物体の姿勢を表すこと。姿勢は「どう回転してその向きになったか」で回転と同じく表せる。(姿勢は回転の結果)

姿勢は方向よりも多くの情報を持つ。方向に大きさは要らないため、自由度(次元と大体同じ)は2。しかし姿勢は航空機でいうロール成分が必要になるので、方向に+1して3になる。

つまり、姿勢は最小3個のパラメータで表せる。 回転は姿勢と本質的に同じなので、同様に3個でいい。実際に3個で姿勢や回転を表しているのがオイラー角。

対して、クォータニオンは4個のパラメータを使っている。このままでは自由度が1つ余るので、それを解決する方法として「ノルムが1」という制約がある。

ちなみに、3x3個のパラメータを使う回転行列という表現法もある。これを縛る制約は「正規直行行列である」こと。

1-1. クォータニオンとは

三次元空間において、

  • 方向ベクトル を回転軸として
  • 角度だけ回転する

という「回転」クォータニオンは、四次元ベクトル で表す。

UnityではそれぞれQuaternion.x,y,z,wとして実装している。生成したいならQuaternion.AngleAxis(角度, 軸)で作れる。

1-2. クォータニオンによる回転操作

回転は表せたが、これを実際に回転操作として実装するにはどうすればよいだろう。
仮に回転操作をと置くと、このようなシンプルな式ができる。

回転させるもの回転結果備考
ベクトル の逆回転
姿勢クォータニオン

クォータニオン同士の掛け算、クォータニオンとベクトルの掛け算の定義は1-4で。掛け算は不可換、つまり左右の入れ替えは不可能。
なお、はテンソル積という代物。あるベクトル空間における新しいベクトル空間を示す。が、ここではめんどいので専用掛け算記号として見ていればいい。
unityでは*で表現する。普段の掛け算と同じ。

テンソルとは何か Part.1 | 高校数学の美しい物語

1-3. クォータニオンを選ぶ理由

パラメータ数メモリ消費計算上の扱いやすさ備考
クォータニオン4⚪︎バランス型で、その他様々なメリットがあります
オイラー角3×具体的な姿勢をイメージしやすく、メモリ的にも優しいですが、計算上の難点を抱えています
回転行列 or DCM9×⚪︎

クォータニオンはメモリ消費、扱いやすさの両面でバランスが取れている。数値誤差も生じにくい。

オイラー角はメモリ消費が少ないが、三角関数を多用する関係上計算時間が大きい。 また、二番目の角度が+-90度によって起きる問題、ジンバルロックが厄介。(ヨーとロールの回転軸がそろい、区別がつかなくなる)
しかしイメージしやすいので今でもよく見る表現方法。

回転行列は、実はクォータニオンと本質的には同じ。回転行列の持つ性質を維持しつつ、4個のパラメータに圧縮したのがクォータニオンといえる。

2. クォータニオンの使い方

2-1. クォータニオンの生成

指定するものUnity 関数備考
1回転軸と回転角度Quaternion.AngleAxisクォータニオン本来の定義
2オイラー角Quaternion.Euler角度を 3 つ指定します
3向けたい方向Transform.LookAt今の向いてる方向 (デフォルトで上方向) と、向けたい方向を指定します