GLM:四元数に対するオイラー角


12

私が問題を抱えているので、GL数学GLM)を知っていることを望みます、私は破ることができません:

オイラー角のセットがあり、それらの間のスムーズな補間を実行する必要があります。最良の方法は、それらをクォータニオンに変換し、SLERPアルゴリズムを適用することです。

私が抱えている問題は、オイラー角でglm :: quaternion を初期化する方法です。

GLMドキュメンテーションを何度も読みましたが、適切なが見つからずQuaternion constructor signature、3つのオイラー角が必要です。私が見つけた最も近いものは 、角度の値とその角度の軸をとるangleAxis()関数です。注意してください、私が探しているのは、方法、解析方法RotX, RotY, RotZです。


参考までに、これは上記のangleAxis() 関数のシグネチャです。

detail::tquat< valType > angleAxis (valType const &angle, valType const &x, valType const &y, valType const &z)

回答:


13

私はGLMに精通していませんが、オイラー角から四元数に直接変換する関数がない場合は、「軸周りの回転」関数(「angleAxis」など)を自分で使用できます。

方法(擬似コード)は次のとおりです。

Quaternion QuatAroundX = Quaternion( Vector3(1.0,0.0,0.0), EulerAngle.x );
Quaternion QuatAroundY = Quaternion( Vector3(0.0,1.0,0.0), EulerAngle.y );
Quaternion QuatAroundZ = Quaternion( Vector3(0.0,0.0,1.0), EulerAngle.z );
Quaternion finalOrientation = QuatAroundX * QuatAroundY * QuatAroundZ;

(または、オイラー角の回転が適用される予定の順序に応じて、四元数の乗算を切り替える必要がある場合があります)

あるいは、GLMのドキュメントを見ると、オイラー角-> matrix3->クォータニオンを次のように変換できる可能性があります。

toQuat( orient3( EulerAngles ) )

アプリケーションの順序があいまいでないため、良い答えです。
リチャードファビアン

@Trevor:+1、こんにちはTrevor、お返事ありがとう。これは、ここで最も実用的なソリューションのように見えます。回転の乗算順序を簡単に切り替えることができます。おそらく、組み合わせの数が理由であり、オイラー角から四元数への変換がGLMで使用できない理由です。
文海。佐取

私の意見では、すべての答えは有益で価値がありますが、これが最も実用的なものです。私はそれを受け入れられた答えとしてマークしたいと思います。
文海。佐取

@Trevor:QuaternionではfinalOrientation = QuatAroundX * QuatAroundY * QuatAroundZ ;、どのような乗算を意味しますか?驚いたことに、GLM operator *はクォータニオン乗算に対してオーバーロードしないので、おそらく、手動で乗算を実行する必要があります。
文開。佐取

3
@Bunkaiクォータニオン乗算の概念は行列乗算に似ており、ドット積でもクロス積でもありません。四元数の使用方法を理解し、マトリックスに慣れて軸角度を理解したい場合、その基本概念は四元数に非常に似ており、数学はもう少し高度ですが、一度軸角度を理解すると、四元数はもう遠く。
マイクセンダー

16
glm::quat myquaternion = glm::quat(glm::vec3(angle.x, angle.y, angle.z));

ここangleglm::vec3含有ピッチ、ヨー、ロールそれぞれ。

PS。疑わしい場合は、ヘッダーに移動して見てください。定義はglm / gtc / quaternion.hppにあります。

explicit tquat(tvec3<T> const & eulerAngles) {
        tvec3<T> c = glm::cos(eulerAngle * value_type(0.5));
    tvec3<T> s = glm::sin(eulerAngle * value_type(0.5));

    this->w = c.x * c.y * c.z + s.x * s.y * s.z;
    this->x = s.x * c.y * c.z - c.x * s.y * s.z;
    this->y = c.x * s.y * c.z + s.x * c.y * s.z;
    this->z = c.x * c.y * s.z - s.x * s.y * c.z;    
}

どこquatのためのフロートのtypedefですtquat


それは非常に曖昧です、これらの順序は何に適用されますか?オイラーは順序付けられた回転であり、ここのクォータニオンコンストラクターはそれを気にしていないようです。
リチャードファビアン

関数定義はあなたのものとまったく同じです。必要に応じて回答に投稿しました。
減速

引数の順序ではなく、回転の適用の順序。私の答えには、ウィキペディアの記事から取られたXYZ順序が含まれていますが、古い会社ではアプリケーションのZYX順序を使用し、現在の会社ではYZX順序を使用しています。x角度はすべての場合においてベクトル/引数リストの最初の値のままですが、実際の結果の変換は同じではありません。
リチャードファビアン

rotationQuatの答えを修正したので、順序を簡単に変更する方法を確認できます。デフォルトではXYZを受け入れますが、簡単に変更できます。
減速

2
-1、質問にとって非常に重要なローテーションの順序に言及していないため
Maik Semder

7

ソリューションはウィキペディアにあります:http : //en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles

それを使用して:

sx = sin(x/2); sy = sin(y/2); sz = sin(z/2);
cx = cos(x/2); cy = cos(y/2); cz = cos(z/2);

q( cx*cy*cz + sx*sy*sz,
   sx*cy*cz - cx*sy*sz,
   cx*sy*cz + sx*cy*sz,
   cx*cy*sz - sx*sy*cz ) // for XYZ application order

q( cx*cy*cz - sx*sy*sz,
   sx*cy*cz + cx*sy*sz,
   cx*sy*cz - sx*cy*sz,
   cx*cy*sz + sx*sy*cz ) // for ZYX application order

オイラー(回転の適用がXYZまたはZYXの場合)を指定したクォータニオンのコンストラクター。ただし、オイラー角の6つの可能な組み合わせのうち2つだけです。変換行列に変換するときに、オイラー角がどの順序で構築されるかを本当に知る必要があります。そうして初めて、ソリューションを定義できます。

私が働いていた古い会社では、(ほとんどのグラフィックスカードと同様に)Zをフォワードとして使用していたため、アプリケーションの順序はZYXでした。この順序は、クォータニオンを乗算して最終的な変換を生成する順序であり、回転の順序の問題は乗算が可換ではないことです。


1
+1、こんにちは。すばらしい回答をありがとう。OpenGLを使用すると、Z値が画面から消えます。私のアプリケーションでは、ZYX乗算順序を実行します。もともと、GLMにはこの機能があると思っていましたが、まだ実装されていないので、推奨されるように、手動で変換作成することもできます。
文海。佐取

これが最良の答えです。
プラズマセル

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.