GLM: Euler Angles au Quaternion

12

J'espère que vous connaissez GL Mathematics ( GLM ) parce que j'ai un problème, je ne peux pas casser:

J'ai un ensemble d' angles d'Euler et je dois effectuer une interpolation fluide entre eux. La meilleure façon est de les convertir en quaternions et d'appliquer l' alrogirthm SLERP.

Le problème que j'ai est de savoir comment initialiser glm :: quaternion avec Euler Angles, s'il vous plaît?

J'ai lu la documentation GLM encore et encore, mais je ne trouve pas approprié Quaternion constructor signature, cela prendrait trois angles d'Euler. Le plus proche que j'ai trouvé est la fonction angleAxis () , prenant la valeur de l'angle et un axe pour cet angle. Notez, s'il vous plaît, ce que je cherche si un moyen, comment analyser RotX, RotY, RotZ.


Pour votre information, voici la signature de fonction angleAxis () mentionnée ci-dessus :

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

Réponses:

13

Je ne suis pas familier avec GLM, mais en l'absence d'une fonction pour convertir directement des angles d'Euler en quaternions, vous pouvez utiliser vous-même les fonctions de "rotation autour d'un axe" (telles que "angleAxis").

Voici comment (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;

(Ou vous devrez peut-être changer ces multiplications de quaternions, selon l'ordre dans lequel vos rotations d'angle d'Euler doivent être appliquées)

Alternativement, en regardant dans la documentation de GLM, il semble que vous puissiez convertir les angles euler -> matrix3 -> quaternion comme ceci:

toQuat( orient3( EulerAngles ) )
Trevor Powell
la source
bonne réponse car c'est moins ambigu quant à l'ordre d'application.
Richard Fabian
@Trevor: +1, Salut Trevor, merci pour votre bonne réponse. Cela ressemble à la solution la plus pratique ici. Je peux facilement basculer entre l'ordre de multiplication des rotations. Il est possible que le nombre de combinaisons soit la raison pour laquelle la conversion Angle d'Euler en Quaterion n'est pas disponible dans GLM.
Bunkai.Satori
Bien que toutes les réponses sont bonnes et précieuses, à mon avis, c'est le plus pratique. Je voudrais le marquer comme réponse acceptée .
Bunkai.Satori
@Trevor: Dans Quaternion finalOrientation = QuatAroundX * QuatAroundY * QuatAroundZ ;, quel type de multiplication avez-vous voulu dire? Je suis surpris que GLM ne surcharge pas operator *pour la multiplication Quaternion, donc je devrai peut-être effectuer la multiplication manuellement .
Bunkai.Satori
3
@Bunkai, le concept de multiplication quaternionique est similaire à la multiplication matricielle, il n'est ni produit en point ni produit croisé. Si vous voulez comprendre l'utilisation des quaternions, puis vous habituer aux matrices et comprendre les angles d'axe, leur concept de base est assez similaire aux quaternions, les mathématiques sont un peu plus avancées, mais une fois que vous avez compris les angles d'axe, les quaternions ne sont plus plus loin.
Maik Semder
16
glm::quat myquaternion = glm::quat(glm::vec3(angle.x, angle.y, angle.z));

angleest un glm::vec3contenant de tangage, lacet, roulis , respectivement.

PS. En cas de doute, allez dans les en-têtes et regardez. La définition peut être trouvée dans 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;    
}

Où se quattrouve une typographie flottante tquat.

caviar décéléré
la source
C'est assez ambigu, dans quel ordre cela s'appliquerait-il? Les Eulers sont des rotations ordonnées et le constructeur de quaternion ici ne semble pas s'en soucier.
Richard Fabian
La définition de la fonction est exactement la même que la vôtre; Je l'ai posté dans ma réponse si cela importait.
deceleratedcaviar
pas l'ordre des arguments, l'ordre d'application de la rotation. Ma réponse contient la commande XYZ, tirée de l'article de wikipedia, cependant, nous utilisons la commande d'application ZYX dans mon ancienne entreprise et YZX dans ma société actuelle. l'angle x est toujours la première valeur dans la liste des vecteurs / arguments dans tous les cas, mais la transformation résultante réelle n'est pas la même.
Richard Fabian
J'ai corrigé ma réponse pour le rotationQuat, afin que vous puissiez voir comment vous pouvez facilement changer l'ordre. Par défaut, il accepte XYZ, mais vous pouvez facilement changer cela.
deceleratedcaviar
2
-1 pour ne pas avoir mentionné l'ordre de rotation, ce qui est très important pour la question
Maik Semder
7

La solution est dans wikipedia: http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles

en utilisant cela:

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

Constructeurs pour un quaternion, étant donné un Euler (où l'application de la rotation est XYZ ou ZYX). Cependant, ce n'est que deux des six combinaisons possibles d'angles d'Euler. Vous avez vraiment besoin de savoir dans quel ordre les angles d'Euler sont construits lors de la conversion en matrice de transformation. Ce n'est qu'alors que la solution peut être définie.

Dans l'ancienne entreprise dans laquelle je travaillais, nous avions Z comme attaquants (comme la plupart des cartes graphiques), donc l'ordre d'application était ZYX, et dans mon entreprise actuelle, l'axe Y est en avant et Z est en hausse, donc notre ordre d'application est YZX. Cet ordre est l'ordre dans lequel vous multipliez vos quaternions ensemble pour générer votre transformation finale, et l'ordre des rotations est que les multiplications ne sont pas commutatives.

Richard Fabian
la source
1
+1, salut et merci pour la bonne réponse. Lorsque j'utilise OpenGL , la valeur Z sort de l'écran. Dans mon application, j'exécute l' ordre de multiplication ZYX . À l'origine, je pensais que GLM avait cette fonctionnalité disponible, mais je vois, ils ne l'ont pas encore implémentée, donc une alternative consiste à créer la conversion manuellement , comme vous le recommandez.
Bunkai.Satori
C'est la meilleure réponse ici.
plasmacel
1
vec3 myEuler (fAngle[0],fAngle[1],fAngle[2]);
glm::quat myQuat (myEuler);

fAngle doit être en radians!

Carlos
la source
2
C'était une blague? Ou avez-vous tout simplement pas lu les autres réponses (en particulier celle de Daniel)?
Chris dit Réintégrer Monica