3D空間で回転・向きを表す方法

3Dわからない人によるメモ

行列

4x4正方行列で回転と向きを表す。
 
利点
  • 回転を行列の掛け算で表せるので、計算が速い
  • 行列なので平行移動・拡大縮小・傾きも表現できる
  • OpenGLの回転表現法がこれなので、わざわざ変換する必要がない
欠点
  • 向きを表すのに16個の実数値が必要なので、メモリ効率が悪い
    • 3D物体1つだとなんてことはない差だが、何万個も物体があると大差に。
  • 乗算が多いので、誤差がたまりやすい

オイラー角

軸に対する回転3つで向きを表す。
直観的なので3DCGソフトなどでのクライアントに対する回転表示によく使われるが、内部的に使うとなると特定の状況以外では効率がよくない。
 
利点
  • 向きを直観的な形式で表現することができる
  • 各軸に対する回転処理が単純かつ高速
  • 3つの実数値があればいいので、メモリ効率がいい
欠点
  • 単純でない回転を適用する場合、計算が複雑で時間がかかる
  • 特異点が存在する。つまり、2つの等価でないオイラー角が同じ向きを表すことがある
    • このためオイラー角が一意に定まらないことを考慮しないといけないので、他の向き表現からの変換が多少複雑。
  • ジンバルロックが発生する。つまり、特定の向きのときに回転が急激になったり、ほとんど回転しないことがある。
  • 軸の回転順序に自由度があるうえ、状況によって有効な順番が異なるので、統一感がなく紛らわしい
    • いくつか流儀がある(参考:RfLab.Wiki - 数学)。
    • zxy:航空機の姿勢制御(ロールピッチヨー)。
    • yxz:カメラの向き制御
    • zxz:ロボットの姿勢制御。狭義のオイラー角。
    • xyz:あまり使わないが、順序がわかりやすいので他の向き表現形式からの変換過程で使ったり

クォータニオン

クォータニオン四元数)を使って向きを表す。
四元数複素数を拡張した概念で、1つの実数と3つの虚数からなる数のこと。
回転を表す内部表現にはクォータニオンが使われることが多い。
 
利点
  • 回転を四元数の積で表すことができるので、計算が速い
  • 拡大縮小も表現できる
    • 正規化すると拡大情報が消え、正規化しないと回転の誤差がたまるので、あまり使い勝手がよくないが。
  • 2つの向き間の角度を求めるのが高速
  • 高速な球面線形補間(Slerp)が使える
欠点
  • 表現が直観的でない
  • 複数回の回転を表現できない。つまり、60度の右回転・420度の右回転・300度の左回転…が、全て等価に扱われる
    • 1フレームごとならストロボ効果で気にならぬ
    • Slerpとかするときは処理を細かくわけましょう