GLM: Euler Winkel zu Quaternion

12

Ich hoffe du kennst GL Mathematik ( GLM ), weil ich ein Problem habe, ich kann nicht brechen:

Ich habe eine Reihe von Euler-Winkeln und muss zwischen ihnen glatt interpolieren . Am besten konvertieren Sie sie in Quaternions und wenden SLERP alrogirthm an.

Das Problem, das ich habe, ist, wie man glm :: quaternion mit Euler Angles initialisiert , bitte.

Ich habe die GLM-Dokumentation immer wieder gelesen , kann aber nicht feststellen Quaternion constructor signature, dass ich drei Euler-Winkel benötige. Das nächste, was ich gefunden habe, ist die Funktion angleAxis () , die den Winkelwert und eine Achse für diesen Winkel verwendet. Beachten Sie bitte, wonach ich suche und wie ich analysieren kann RotX, RotY, RotZ.


Zu Ihrer Information ist dies die oben angegebene Funktionssignatur von angleAxis () :

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

Antworten:

13

Ich bin mit GLM nicht vertraut, aber da es keine Funktion gibt, mit der Euler-Winkel direkt in Quaternionen umgewandelt werden können, können Sie die Funktionen "Drehung um eine Achse" (z. B. "angleAxis") selbst verwenden.

Hier ist wie (Pseudocode):

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;

(Oder Sie müssen möglicherweise die Quaternionsmultiplikatoren umschalten, abhängig von der Reihenfolge, in der Ihre Euler-Winkelrotationen angewendet werden sollen.)

Aus der Dokumentation von GLM geht jedoch hervor, dass Sie möglicherweise Euler-Winkel -> Matrix3 -> Quaternion wie folgt konvertieren können:

toQuat( orient3( EulerAngles ) )
Trevor Powell
quelle
Gute Antwort, da die Reihenfolge der Bewerbung weniger eindeutig ist.
Richard Fabian
@ Trevor: +1, Hallo Trevor, danke für deine gute Antwort. Dies scheint hier die praktischste Lösung zu sein. Ich kann leicht zwischen der Rotationsmultiplikationsreihenfolge wechseln. Möglicherweise ist die Anzahl der Kombinationen der Grund, warum die Euler-Winkel-zu-Quaterion-Konvertierung in GLM nicht verfügbar ist.
Bunkai.Satori
Obwohl alle die Antworten gut und wertvoll sind, meiner Meinung nach , das ist die praktischste ein. Ich möchte es als akzeptierte Antwort markieren .
Bunkai.Satori
@ Trevor: In Quaternion finalOrientation = QuatAroundX * QuatAroundY * QuatAroundZ ;, welche Art von Multiplikation hast du gemeint? Ich bin überrascht, dass GLM die operator *Quaternion-Multiplikation nicht überlastet. Daher muss ich die Multiplikation möglicherweise manuell durchführen .
Bunkai.Satori
3
@Bunkai Das Konzept der Quaternion-Multiplikation ähnelt der Matrix-Multiplikation, es ist weder ein Punkt noch ein Kreuzprodukt. Wenn Sie die Verwendung von Quaternionen verstehen möchten, sich an Matrizen und Achsenwinkel gewöhnen möchten, ist ihr Grundkonzept Quaternionen ziemlich ähnlich, die Mathematik ist etwas fortgeschrittener, aber wenn Sie die Achsenwinkel verstanden haben, sind Quaternionen es nicht weit weg mehr.
Maik Semder
16
glm::quat myquaternion = glm::quat(glm::vec3(angle.x, angle.y, angle.z));

Wo angleist ein glm::vec3enthaltender Pitch, Yaw, Roll .

PS. Im Zweifelsfall einfach in die Überschriften gehen und nachsehen. Die Definition finden Sie in 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;    
}

Wo quatist ein float typedef für tquat.

gebremster Kaviar
quelle
Das ist ziemlich zweideutig, in welcher Reihenfolge würden diese zutreffen? Euler sind Rotationen angeordnet und der Quaternion-Konstruktor hier scheint sich nicht darum zu kümmern.
Richard Fabian
Die Funktionsdefinition entspricht genau Ihrer; Ich habe es in meiner Antwort gepostet, wenn es darauf ankam.
verzögerte
nicht die Reihenfolge der Argumente, die Reihenfolge der Anwendung der Rotation. Meine Antwort enthält die XYZ-Reihenfolge, die dem Wikipedia-Artikel entnommen ist. Wir verwenden jedoch die ZYX-Reihenfolge der Anwendung bei meiner alten Firma und YZX bei meiner aktuellen. Der x-Winkel ist in allen Fällen immer noch der erste Wert in der Vektor- / Argumentliste, aber die tatsächliche resultierende Transformation ist nicht dieselbe.
Richard Fabian
Ich habe meine Antwort für das RotationsQuat korrigiert, damit Sie sehen können, wie Sie die Reihenfolge leicht ändern können. Standardmäßig akzeptiert es XYZ, aber Sie können das leicht ändern.
verlangsamt
2
-1 für die Nicht-Erwähnung der Rotationsreihenfolge, die für die Frage sehr wichtig ist
Maik Semder
7

Die Lösung befindet sich in Wikipedia: http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles

damit:

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

Konstruktoren für eine Quaternion unter Angabe eines Eulers (wobei die Anwendung der Rotation XYZ oder ZYX ist). Es sind jedoch nur zwei von sechs möglichen Kombinationen von Euler-Winkeln. Sie müssen wirklich herausfinden, in welcher Reihenfolge die Euler-Winkel konstruiert sind, wenn Sie in eine Transformationsmatrix konvertieren. Erst dann kann die Lösung definiert werden.

In der alten Firma, in der ich gearbeitet habe, hatten wir Z als Vorwärts (wie die meisten Grafikkarten), daher lautete die Anwendungsreihenfolge ZYX, und in meiner aktuellen Firma ist die Y-Achse vorwärts und Z nach oben, also lautet unsere Anwendungsreihenfolge YZX. Diese Reihenfolge ist die Reihenfolge, in der Sie Ihre Quaternionen multiplizieren, um Ihre endgültige Transformation zu generieren, und die Reihenfolge ist wichtig für Rotationen, da die Multiplikationen nicht kommutativ sind.

Richard Fabian
quelle
1
+1, hi und danke für die tolle Antwort. Wenn ich OpenGL verwende, verschwindet der Z-Wert aus dem Bildschirm. In meiner Anwendung führe ich die ZYX-Multiplikationsreihenfolge durch. Ursprünglich dachte ich, dass GLM diese Funktionalität zur Verfügung hat, aber ich sehe, sie haben sie noch nicht implementiert, so dass eine Alternative darin besteht, die Konvertierung manuell zu erstellen , wie Sie empfehlen.
Bunkai.Satori
Dies ist die beste Antwort hier.
Plasmacel
1
vec3 myEuler (fAngle[0],fAngle[1],fAngle[2]);
glm::quat myQuat (myEuler);

Der Winkel muss im Bogenmaß angegeben werden!

Carlos
quelle
2
War das ein Witz? Oder hast du die anderen Antworten (besonders Daniels) einfach nicht gelesen?
Chris sagt Reinstate Monica