GLM: Euler Angles to Quaternion


12

Spero che tu conosca GL Mathematics ( GLM ) perché ho un problema, non posso rompere:

Ho una serie di angoli di Eulero e ho bisogno di eseguire un'interpolazione regolare tra di loro. Il modo migliore è convertirli in Quaternioni e applicare l' alrogirthm SLERP.

Il problema che ho è come inizializzare glm :: quaternion con Euler Angles, per favore?

Ho letto più volte la documentazione GLM , ma non riesco a trovare appropriata Quaternion constructor signature, che richiederebbe tre angoli di Eulero. Il più vicino che ho trovato è la funzione angleAxis () , prendendo il valore dell'angolo e un asse per quell'angolo. Nota, per favore, quello che sto cercando è un modo, come analizzare RotX, RotY, RotZ.


Per vostra informazione, questa è la firma della funzione angleAxis () sopra citata :

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

Risposte:


13

Non ho familiarità con GLM, ma in assenza di una funzione per convertire direttamente dagli angoli di Eulero in quaternioni, puoi usare tu stesso le funzioni di "rotazione attorno ad un asse" (come "angoloAsse").

Ecco come (pseudocodice):

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;

(O potresti aver bisogno di cambiare quelle moltiplicazioni di quaternione, a seconda dell'ordine in cui le rotazioni dell'angolo di eulero sono destinate ad essere applicate)

In alternativa, guardando attraverso la documentazione di GLM, sembra che potresti essere in grado di convertire gli angoli di eulero -> matrix3 -> quaternion in questo modo:

toQuat( orient3( EulerAngles ) )

buona risposta perché è meno ambiguo riguardo all'ordine di applicazione.
Richard Fabian,

@Trevor: +1, ciao Trevor, grazie per la tua buona risposta. Questa sembra la soluzione più pratica qui. Posso passare facilmente dall'ordine di moltiplicazione di rotazione. Probabilmente, il numero di combinazioni è il motivo, per cui la conversione da angolo di Eulero a quaterion non è disponibile in GLM.
Bunkai.Satori,

Sebbene tutte le risposte siano buone e preziose, a mio avviso, questa è la più pratica. Vorrei contrassegnarlo come risposta accettata .
Bunkai.Satori,

@Trevor: In Quaternion finalOrientation = QuatAroundX * QuatAroundY * QuatAroundZ ;, che tipo di moltiplicazione intendevi? Sono sorpreso che GLM non sovraccarichi operator *per la moltiplicazione di Quaternion, quindi probabilmente dovrò eseguire la moltiplicazione manualmente .
Bunkai.Satori,

3
@Bunkai il concetto di moltiplicazione del quaternione è simile alla moltiplicazione della matrice, non è né punto né prodotto incrociato. Se vuoi capire l'uso dei quaternioni, quindi abituarti alle matrici e comprendere gli angoli degli assi, il loro concetto di base è abbastanza simile ai quaternioni, la matematica è un po 'più avanzata, ma una volta che hai capito gli angoli degli assi, i quaternioni non lo sono molto più lontano.
Maik Semder,

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

Dov'è rispettivamente angleun pitch, yaw, rollglm::vec3 contenente .

PS. In caso di dubbi, vai alle intestazioni e guarda. La definizione può essere trovata 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;    
}

Dov'è quatun typedef float per tquat.


È abbastanza ambiguo, in quale ordine si applicherebbero? Agli euler vengono ordinate rotazioni e il costruttore di quaternioni qui non sembra preoccuparsene.
Richard Fabian,

La definizione della funzione è identica alla tua; L'ho pubblicato nella mia risposta se contava.
deceleratedcaviar

non l'ordine degli argomenti, l'ordine di applicazione della rotazione. La mia risposta contiene l'ordinamento XYZ, tratto dall'articolo di Wikipedia, tuttavia, utilizziamo l'ordinamento ZYX dell'applicazione nella mia vecchia azienda e YZX nel mio attuale. l'angolo x è sempre il primo valore nell'elenco vettore / argomento in tutti i casi, ma la trasformazione risultante effettiva non è la stessa.
Richard Fabian,

Ho risolto la mia risposta per la rotazioneQuat, così puoi vedere come potresti facilmente cambiare l'ordine. Di default accetta XYZ, ma puoi facilmente cambiarlo.
deceleratedcaviar

2
-1 per non menzionare l'ordine di rotazione, che è molto importante per la domanda
Maik Semder,

7

La soluzione è in Wikipedia: http://it.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles

usando quello:

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

Costruttori per un quaternione, dato un Eulero (dove l'applicazione della rotazione è XYZ o ZYX). Tuttavia, sono solo due delle sei possibili combinazioni di angoli di Eulero. Devi davvero scoprire in che ordine vengono costruiti gli angoli di Eulero durante la conversione in matrice di trasformazione. Solo allora la soluzione può essere definita.

Nella vecchia società in cui lavoravo, avevamo Z come forward (come la maggior parte delle schede grafiche), quindi l'ordine dell'applicazione era ZYX, e nella mia azienda attuale l'asse Y è in avanti e Z è attivo, quindi il nostro ordine di applicazione è YZX. Questo ordine è l'ordine in cui moltiplichi i tuoi quaternioni insieme per generare la tua trasformazione finale, e l'ordine conta per le rotazioni se le moltiplicazioni non sono commutative.


1
+1, ciao e grazie per l'ottima risposta. Mentre utilizzo OpenGL , il valore Z esce dallo schermo. Nella mia applicazione eseguo l' ordine di moltiplicazione ZYX . Inizialmente, ho pensato, che GLM ha questa funzionalità disponibile, ma vedo, non l'hanno ancora implementata, quindi un'alternativa è creare la conversione manualmente , come si consiglia.
Bunkai.Satori,

Questa è la migliore risposta qui.
Plasmacel,

1
vec3 myEuler (fAngle[0],fAngle[1],fAngle[2]);
glm::quat myQuat (myEuler);

L'angolo deve essere in radianti!


2
Era uno scherzo? O non hai letto le altre risposte (specialmente quelle di Daniel)?
Chris dice di reintegrare Monica il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.