LoginSignup
13
15

More than 3 years have passed since last update.

なんでQuaternion使うか?(&ジンバルロック)

Last updated at Posted at 2018-02-12

はじめに

Unityなどでクオータニオンを目にする機会は多いと思いますが、なんで使うのかはわからないけど便利だから使うみたいなことはよくあると思います.そこで少しでもクオータニオンを使うメリットをかければいいなと思っています!
さっそくクオータニオンを使う大切な事実として任意の回転は1つの軸で表現できるということがあります.いまいち、ぴんとは来ないかも知れませんが、これがクオータニオンを使う最大のメリットであり理由なのではないかなと思っています.

クオータニオンを使うことでのメリット

例えば、空にいる飛行機を見るとします、そのときオイラー角を用いた回転ではx、y、z、の基本軸に対して何度回転させるかということが必要になってくると思いますが、それは意外とめんど臭いことなんです.このめんど臭く感じる感覚はクオータニオンについてなんとなくわかってきたら理解できるはずです.ではクオータニオンを用いたらどのようになるかというと、目的へのベクトルがわかれば回転できてしまうということです.

Unityで試してみる

クオータニオンと積ベクトルの積を用いた回転

pos = gameObject.transform.position;
//回転の中心を(1,2,3)とする
Vector3 RotCenter = new Vector3(1, 2, 3);
pos -= RotCenter;
pos = Quaternion.AngleAxis (Mathf.PI * Mathf.Rad2Deg, Vector3.up) * pos;
pos += RotCenter;
gameObject.transform.position = pos;

クオータニオンによる回転は原点中心なので回転させたいオブジェクトの座標から引いてから回転させ、最後にもう一回足してあげてます.
もう1つ大切なこととしてクオータニオンの回転度数は度数法を用いています.

またベクトルとクオータニオンの積で回転を示していますが、実際の計算ではこのようになっています.

q(xi,yi,zi,w) \times \vec{v}(x,y,z) \times  \bar{q}

Slperを使った場合の回転

Quaternion targetRot;
    public GameObject target;
    void Start () {
        target = GameObject.Find ("target");
    }

    void Update () {
        targetRot = Quaternion.LookRotation (target.transform.position - gameObject.transform.position);
        transform.rotation = Quaternion.Slerp(transform.rotation, targetRot, Time.deltaTime);
    }

LookRotation関数は目的のベクトルへ回転させるためのクオータニオンを取得します.その回転を表すクオータニオンを随時更新して、Slerp関数(球面補完してくれる関数)を用いて回転させています.
またLookRotation関数の第1引数は正面方向のZ軸、第2引数はY軸に相当します。それらの外積を求めてX軸を求め、Z軸ともとまったX軸の外積を求めることで正確にY軸を求めることでその座標系への回転を表すクオータニオンを算出しているみたいです.

補足

ジンバルロック

よくクオータニオンについて書いてあるサイトを眺めているとこんなことが書いてあります.『クオータニオンを使うことでジンバルロックの影響を受けない』 ....急にこんなことを言われても困りますよね.そのためこれから自分が理解している範囲でジンバルロックがどんなものかということを書いて行こうと思います.

ジンバルロック問題とは

ジンバル(ジンバル自体がよくわからない場合は下の参考の動画を!)の軸には親子関係があり、Z軸周りに回転するとY軸が、Y軸周りに回転するとX軸が回転します、X軸周りに回転しても、他の軸は回転しません。またそれぞれの回転角度はオイラー角における回転の順番(ヨー・ピッチ・ロール)と対応しています。(Z軸周りをヨー、Y軸周りをピッチ、X軸周りをロール)そして本題のジンバルロックの時の状態ですが、それはY軸に関して90度回転させ、X軸に関する回転軸がZ軸と被ってしまった時、回転順序の最後のX軸回転による制御ができなくなってしまことをジンバルロックというらしいです.

参考:https://www.youtube.com/watch?v=zc8b2Jo7mno

ジンバルロックに関してクオータニオンを使うと嬉しいこと

オイラー回転は3軸を使って回転するのでこのジンバルロックがおこってしまいますが、クオータニオンは4元数なのでこの問題を解決してくれます.(4元数とは、4つの実数を組み合わせたもので、4つの要素のうち、ひとつは実部、残り3つは虚部)
冒頭で書いた任意の回転は1つの軸で表現できるということを思い出すとクオータニオンでは回転軸と回転角度がわかれば回転を表現することができる.つまりこれは二次元平面での回転に帰着するためジンバルロックがおきないのであると考えています.

おわりに

自分も数学的な部分で理解していない部分はありますが、この記事が何かの役に立てたらなと思います.また間違いなどがありましたらコメントください.

13
15
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
15