Pitch() と Yaw() を呼び出すだけで、最終的にカメラが Roll() になるのはなぜでしょうか?

StackOverflow https://stackoverflow.com/questions/784445

  •  16-09-2019
  •  | 
  •  

質問

私は基本的な OpenGL ゲームをコーディングしていて、カメラの移動に関してマウスを処理するコードをいくつか持っています。

私は次の方法を使用しています。

int windowWidth = 640;
int windowHeight = 480;

int oldMouseX = -1;
int oldMouseY = -1;

void mousePassiveHandler(int x, int y)
{
    int snapThreshold = 50;

    if (oldMouseX != -1 && oldMouseY != -1)
    {
        cam.yaw((x - oldMouseX)/10.0);
        cam.pitch((y - oldMouseY)/10.0);


        oldMouseX = x;
        oldMouseY = y;

        if ((fabs(x - (windowWidth / 2)) > snapThreshold) || (fabs(y - (windowHeight / 2)) > snapThreshold))
        {
            oldMouseX = windowWidth / 2;
            oldMouseY = windowHeight / 2;
            glutWarpPointer(windowWidth / 2, windowHeight / 2);
        }
    }
    else
    {
        oldMouseX = windowWidth / 2;
        oldMouseY = windowHeight / 2;
        glutWarpPointer(windowWidth / 2, windowHeight / 2);
    }


    glutPostRedisplay();

}

ただし、ぐるっと見回した後、カメラが「回転」し始めることがわかります。私は Pitch と Yaw を呼び出しているだけなので、これがどのようにして可能なのかわかりません。

Camera クラスに使用しているコードは次のとおりです。 http://pastebin.com/m20d2b01e

私の知る限り、カメラが「回転」することは起こらないはずです。単純に上下にピッチしたり、左右にヨーを動かしたりする必要があります。転がらないでください。

これの原因は何でしょうか?

役に立ちましたか?

解決

おめでとうございます - あなたはリー群理論を発見しました!

はい、それは可能です。一連の変換の結果 彼らが実行している順序に依存します。ピッチを行います ヨー続い続く、やってヨーと同じではありません ピッチによります。実際には、無限小イチゴ腫の制限で そして、ピッチは、違いは、純粋なロールになります。一般的な 場合は、もう少し複雑です。

(物理学者は、「転流関係の本を呼び出します 回転基」。)

あなたは回転行列に精通している場合、

、あなたはそれをうまくすることができます 非常に簡単に。

他のヒント

あなたはまだ行っていない場合は、

あなたはおそらく、回転を構成するために四元して使用する必要があります。これは、3つの軸を中心に回転させることにより、カメラを向けるときに取得することができますジンバルロックするの問題を回避しますます。

ここでは、それらの間で変換する方法である。

そうですね、地平線に対して水平に前方を見て始めて、90 度上にピッチを上げ、次に 90 度左にヨーを動かし、次に 90 度下にピッチすると、最初と同じ方向を見ていることになりますが、地平線は垂直になります (左に90度回転したかのように)。

編集:問題は、カメラを飛行機のように扱う場合、ヨー/ピッチ/ロールが適切であることだと思います。おそらくあなたがやりたいことは、それを球の中の点のように扱い、球上のどこにカメラを向けているかを追跡することです。ヨー/ピッチの代わりに、シータ (緯度) とファイ (経度) を追跡する球面座標を使用します。似ているように聞こえるかもしれませんが、カメラが真上を向いているという極端なケースを考えてみましょう。ヨー/ピッチを使用すると、真上方向からヨーとピッチを自由に調整できます。シータ/ファイでは、シータは下方向にしか調整できず、ファイをどれだけ調整しても、シータを減少させても、カメラは地平線に平行になります。これが FPS カメラの仕組みです (後ろを見るほど遠くを見ることはできません)。

編集2:リンク先のカメラ コードを見ると、使用したいのは rotLati(float angle) そして rotLongi(float angle) 機能。

数学的にこの理由は、3D空間で回転が通学していないということです。何それが意味する)、ヨー()ピッチ()が続くと同じヨー(続くそのピッチ()されていないが、その事実の結果は、回転の3種類が密接にリンクされていることであり、あなたがいずれかを実行することはできません第三のいくつかを得ることなく、それらのうちの2つです。シーケンスの後半は前半の正確な逆である場合を除き、他の言葉で、ピッチ()ES及びヨーのいずれかの配列は、()Sは、時間の経過とともに顕著ロール()効果をもたらすであろう。 (そこに関与し、このかなり複雑な数学の多くは、ですが、詳細は特に関係ありません)。

ピッチ/ヨー/ロールのすべてのあなたの車の向きを基準にしています。あなたがアップ/ダウンピッチときは、ヨーのあなたの軸を変更します。あなたはヨーとき同様に、あなたはあなたのピッチ軸を変更します。だから、ただ組み合わせとピッチ&ヨー操縦によってロール操縦と同様に、あなたの向きを変更することが可能です。

私はこのような状況は、ジンバルロックすると呼ばれていると信じて - 上のイラストと、それの例がありますウィキペディアのページでます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top