オイラー(Euler)回転の弱点:ジンバルロック
ここまで学んできた回転方法は「オイラー」(Euler)回転といい、x, y, zの各軸ごとに別々に回転することにより、オブジェクトに連続に適用すると、自由に回転できる…

設定しても、回転順番を決めないといけない。X→Y→Z / Y→Z→X / X→Z→Y などの様々な組み合わせがあり、それぞれの最終結果がことなるので、混乱する可能性がある。
また、「ジンバルロック」という問題もある。次の装置を見てください。この装置は「X(赤)→ Y(緑)→ Z(青)」の順番で回転する装置。この状態で、物体が各軸の周りの回転を自由にできる。
| X 軸の周り |
|
||
|
|
Y 軸の周り | ||
| Z 軸の周り |
|
||
ここで、Y軸の周りを90度回転してみると2つの回転軸が重なってしまうこの状態は「ジンバルロック」といい、1つの回転自由度が失ってしまった:
- 重なったXとZを回転しても、同じ回転になってしまう。
- 矢印の方向に回転したくても、できない
この場合はうまく回転できなくなるので、何かの解決を実装しないといけない。
一時的な解決:Angle-Axis(度-軸)回転
ジンバルロックになってしまった場合、一時的に新しい回転軸を作成し、その「仮想軸」の周りに回転ができる。この方法を使うと、定番のXYZだけではなく、お好みのベクトルの周りに回転ができる。

式は、今までの回転と同じアイデアである。sinとcosを使うが、回転する面はあるベクトル「v」を直交する
この場合は、回転行列は以下のようになる:
|
|
ここで、
|
|
|
θ は回転角度で、
v は回転軸になる任意の3D単位ベクトルである |
|
|
||
|
|
これは今までの回転行列の一般な形である。例えば、回転軸は Z にすると:
|
|
とすると、行列を更新すると:
|
|
|
|
でも、
、なので…
|
|
これで、Z 軸周りの回転行列に戻った!
Unityのサポート
Unityでは「Quaternion.AngleAxis」を使用し、任意の軸周りの回転ができる:
// 以下、X 軸周りに45度を回転する相当:
Vector3 axis = new Vector3(1, 0, 0); // 軸
float angle = 45; // 角度
transform.localRotation = Quaternion.AngleAxis(angle, axis); // 度・軸の回転
練習
惑星と月を真似しましょう。月が惑星の軸周りを従って回転させましょう:
- Moonスクリプトを作成し、
- 回転速度
- 追跡する惑星
- 惑星から離れる距離
- Inspectorで設定できるようにする
Quaternion.AngleAxisを使用し、惑星の「上向きベクトル」(transform.up) の周りに回転する- 実行し、Sceneビューで惑星を傾いて、回転を確認する。
汎用的な解決
Quaternion(クォータニオン - 四元数)
「クォータニオン」は、回転を表す4次元の数値である。一般な形は
|
|
ここでは、「+」は加算ではなく、次元を表してる。ベクトルの表現にすると:
|
|
と等しいのである。4次元の数値であるため演算は多少ややこしいので、ゲームで使う目的だけに注目しましょう。
単位クォータニオンの特徴は:
- ジンバルロックせず、どの回転でも表現ができる
- 2つのクォータニオンを乗算は、2つの回転を連続に適用すると同じものである
- 逆クォータニオン(共役)は、逆回転と同じである
- クォータニオン⇔回転行列の変換ができる
クォータニオンがゲームの中で回転でよく使われるので、Unityがすでに実装されている。Unityは「Quaternion」というクラスがあり、すべての回転は「Quaternion」で行う。そもそも「transform.rotation」のデータ型は「Quaternion」だ!
// Unityの中で、すべての回転は「Quaternion型」である
Quaternion rot = transform.rotation;
オイラー角度と Quaternion の変換
Unityではオイラー角度(XYZ回転)と Quaternion の変換メソッドが実装されている:
// 回転を Quaternion として表現されている
Quaternion rotA = transform.rotation;
// オイラー角度を知りたいなら:
Vector3 angles = rot.eulerAngles;
// 逆に、オイラー角度から Quaternion にしたいなら:
Quaternion rotB = Quaternion.Euler(x, y, z); // x, y, z は各軸の回転である
// このまま回転として利用できる
transform.rotation = rotB;
掛け算(乗算)
クォータニオンが重要なので簡単にクォータニオンの掛け算を理解していきましょう。なお、式を覚えるよりも、掛け算はどのような影響があるのかを覚えてください。
2つのクォータニオン「q」と「p」があり、それぞれは別の回転であるとしたら「p × q」は、連続に2つの回転を適用したことと同じである。
クォータニオン「p」による回転
|
クォータニオン「p」による回転 |
クォータニオン「q」による回転 |
|
|
|
式は教科書にある(泣きたくなるぐらい大変)が、Unity の Quaternion なら「*」で計算できる:
// 「p」と「q」それぞれは「Quaternion」である
Quaternion qp = q * p;
注意:クォータニオンの積は可換でない。回転の順番により、最後の結果が変わるので、行列と同様に:
|
|
|
|
q × p |
p × q |
回転行列との関係
任意の単位クォータニオンを今まで勉強してきた回転行列として表現ができるので、他の変換と組み合わせることができる。
|
|
「a, b, c, d」はクォータニオンの成分である。これで、クォータニオンを回転行列に変換でき、他の変換(移動、拡大縮小)との連結できるようになる。


















q × p の結果


No comments to display
No comments to display