1

Irrlicht をグラフィック エンジンとして、ODE を物理学用に使用して、C++ で 3D シミュレーションを作成しようとしています。次に、ODE クォータニオンを Irrlicht Euler 角に変換する関数を使用しています。これを行うために、私はこのコードを使用しています。

void QuaternionToEuler(const dQuaternion quaternion, vector3df &euler)
{
    dReal w,x,y,z;

    w = quaternion[0];
    x = quaternion[1];
    y = quaternion[2];
    z = quaternion[3];

    double sqw = w*w;    
    double sqx = x*x;    
    double sqy = y*y;    
    double sqz = z*z; 

    euler.Z = (irr::f32) (atan2(2.0 * (x*y + z*w),(sqx - sqy - sqz + sqw)) * (180.0f/irr::core::PI));
    euler.X = (irr::f32) (atan2(2.0 * (y*z + x*w),(-sqx - sqy + sqz + sqw)) * (180.0f/irr::core::PI));          
    euler.Y = (irr::f32) (asin(-2.0 * (x*z - y*w)) * (180.0f/irr::core::PI));

}

正しい位置と回転での描画には問題なく機能しますが、問題はasin命令に付属しています。0..90-の範囲の値のみを返し、度0..-90から範囲を取得する必要があります。0..360少なくとも0..360、 を呼び出したときにの範囲で回転する必要がありますnode->getRotation().Y

4

2 に答える 2

6

オイラー角 (任意のタイプ) には特異点があります。使用している特定のオイラー角 (Tait-Bryan 角またはそのバリエーションのように見える) の場合、特異点はピッチ (Y) のプラスマイナス 90 度です。これは、オイラー角に固有の制限であり、深刻な状況でオイラー角がめったに使用されない主な理由の 1 つです (すべての航空機は速度ベクトル (水平ではない可能性があります) に対してピッチングする能力が非常に限られているため、航空機力学を除く)。そのため、その特異点に近づくことはめったにありません)。

これは、計算が実際には 2 つの同等のソリューションの 1 つにすぎないことも意味します。与えられた四元数に対して、同じ回転を表すオイラー角の解が 2 つあります。どちらのソリューションも同等であるため、ピッチが -90 度から 90 度の間の最も簡単な側を選択するだけです。

また、NaN を回避するために、コードは特異点へのアプローチに対処する必要があります。つまり、特異点 (ピッチの -90 度と 90 度) に近づいているかどうか (小さな許容誤差で) を確認する必要があります。回転)。

オイラー角の使用を完全に回避する方法がある場合は、それを行うことを強くお勧めします。回転のほとんどすべての表現は、オイラー角よりも適しています。Irrlicht はマトリックスをネイティブに使用し、軸角度表現を介した回転の設定/取得もサポートしています。これは、操作がはるかに優れています (また、クォータニオンから取得するのがはるかに簡単で、特異点がありません)。

于 2013-01-21T21:41:58.203 に答える
1

地球の地球について考えてみてください。[-90, 90]その上の各点は、緯度 (範囲) と経度 (範囲 ) を使用してのみ定義できます[-180, 180]。したがって、球上の各点は、これらの角度を使用して指定できます。球上の点はベクトルを指定し、球上のすべての点は可能なすべてのベクトルを指定します。したがって、この記事で指摘したように、使用する式はすべての可能な方向を生成します。

お役に立てれば。

于 2013-01-21T21:38:49.000 に答える