1

私は OpenGL エンジンの回転にクォータニオンを使用します。現在、x、y、z 回転の回転行列を作成するために、軸回転ごとにクォータニオンを作成します。次に、これらを乗算して最終的なクォータニオンを取得します。

  void RotateTo3(const float xr ,const float yr ,const float zr){

    quat qRotX=angleAxis(xr, X_AXIS); 
    quat qRotY=angleAxis(yr, Y_AXIS);
    quat qRotZ=angleAxis(zr, Z_AXIS);

    quat resQuat=normalize(qRotX * qRotY * qRotZ);
    resQuat=normalize(resQuat);
    _rotMatrix= mat4_cast(resQuat);

 }

これですべて問題ありませんが、3 つの軸角度すべてから 1 つのクォータニオンのみを作成し、最後の乗算をスキップしたいと考えています。クォート コンストラクターの 1 つには、次のようなオイラー角度ベクトルのパラメーターがあります。

quat resQuat(vec3(yr,xr,zr))

したがって、これを試してみると、最終的な回転が間違っています.( quat(vec3(xr,yr,zr)) も試しました).GLMに、3つの軸すべてから最終的な四元数を1つのインスタンスで埋める方法はありませんか?

さて、もう1つ: Nicol Bolasが示唆したように、 glm::eulerAngleYXZ() を使用して回転行列をすぐに埋めることができます.彼の意見では、中間の四元数ステップを実行するのは無意味です..しかし、私が見つけたのは少なくとも私にとっては、正しく動作しません。例えば:

これ :

          mat4 ex=  eulerAngleX(radians(xr));
      mat4 ey=  eulerAngleY(radians(yr));
      mat4 ez=  eulerAngleZ(radians(zr));

       rotMatrix= ex * ey * ez; 

これと同じものを返しません:

   rotMatrix= eulerAngleYXZ(radians(yr),radians(xr),radians(zr));

そして、正しい回転状態との比較から、最初の方法は正しい回転を与え、2番目の方法は間違っています。

4

3 に答える 3

3

一般に信じられていることとは反対に、クォータニオンは魔法のような「ジンバル ロックを解決する」デバイスではなく、クォータニオンを使用するとオイラー角がオイラー角ではなくなります。

関数RotateTo3は 3 つのオイラー角を取り、それらを回転行列に変換します。このプロセスをどのように実行するかは問題ではありません。3 つの行列、3 つの四元数、またはglm::eulerAngleYXZ. 結果は、3 つの軸回転から構成される行列になります。オイラー角のすべての特性と欠点を備えています。オイラー角だからです。

ここで四元数を仲介として使用しても意味がありません。それはあなたに何の利益ももたらしません。連続したglm::rotate呼び出しから構築された行列を使用することもできます。

ジンバル ロックやその他のオイラー角の問題なしで向きを設定したい場合は、向きをオイラー角で表現するのをやめる必要があります。

実際に尋ねた質問への答えとして、glm::eulerAngleYXZ計算に使用できます

于 2013-04-24T08:37:48.580 に答える
2

次のような意味ですか。

quat formQuaternion(double x, double y, double z, double angle){
     quat out;
     //x, y, and z form a normalized vector which is now the axis of rotation.
     out.w  = cosf( fAngle/2)
     out.x = x * sinf( fAngle/2 )
     out.y = y * sinf( fAngle/2 )
     out.z = z * sinf( fAngle/2 )
     return out;
}

申し訳ありませんが、実際に使用している quat クラスはわかりませんが、4 つの次元を設定する方法がまだあるはずです。出典:クォータニオンのチュートリアル

于 2013-04-27T16:48:41.470 に答える
1

eulerAngleYXZ は、API 名で示される順序で再結合された場合に、指定された四元数と同じ向きになるオイラー角の 1 つの可能なセットを提供します。これは間違った結果ではなく、いくつかの正しい結果の 1 つです。

クォータニオンを使用して向きを内部に保存します。それを回転させるには、向きの quat に、回転する量を表す別の quat を掛けます。これは、角度/軸から構築して、必要なものを実現できます。

于 2015-07-15T12:14:11.027 に答える