IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Physique Discussion :

Composée de rotations


Sujet :

Physique

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 112
    Points : 45
    Points
    45
    Par défaut Composée de rotations
    Bonjour,

    Je voudrais calculer la composée de deux rotations, je me suis donc renseigné sur les quaternions.
    Donc pour ce que jai compris, il faut que je trouve le quaternion correspondant à mes deux rotations, les multiplier, puis retrouver la rotation correspondant au quaternion résultat de la multiplication.
    Mais je ne trouve nulle part comment calculer la rotation à partir du quaternion. Est-ce qu'il y a une méthode simple?

    Merci

  2. #2
    Expert éminent

    Profil pro
    Fabricant et casseur d'avions
    Inscrit en
    Avril 2004
    Messages
    3 813
    Détails du profil
    Informations personnelles :
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Fabricant et casseur d'avions
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2004
    Messages : 3 813
    Points : 7 638
    Points
    7 638
    Par défaut
    Salut,

    Ca devrait répondre à ta question: GPWiki
    "Errare humanum est, sed perseverare diabolicum"

    Ma page sur DVP.com

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 112
    Points : 45
    Points
    45
    Par défaut
    OK merci beaucoup.
    Il me reste deux questions. Comment ça se fait qu'on peut trouver l'angle juste en faisant "*angle = acos(w) * 2.0f;"? Parce qu'il y a 2 angles différents qui peuvent donner le même cosinus, donc avec cette méthode, ça rend toujours celui entre 0 et pi, mais est-ce que c'est forcément celui qui correspond, donc je pensais qu'il faudrait utiliser le sinus aussi?
    Du coup j'ai fait une fonction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    float angleFromCosAndSin(float cosinus, float sinus)
    {
    	float sol1 = acos(cosinus);
    	float sol2 = -sol1;
    	if(sin(sol1) == sinus)
    		return sol1;
    	if(sin(sol2) == sinus)
    		return sol2;
    	printf("pas de solution : cos=%f, sin=%f, sol1=%f, sol2=%f\n", cosinus, sinus, sol1, sol2);
    	return -1;
    }
    pourtant dans mon application, ça me balance des "pas de solution" tout le temps. Je me suis trompé qqpart?
    J'ai oublié la deuxième question pour l'instant...

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 112
    Points : 45
    Points
    45
    Par défaut
    Ah oui! L'autre question c'était est-ce que la classe Quaternion dont ils parlent existe dans une librairie?

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 112
    Points : 45
    Points
    45
    Par défaut
    Je mets tout mon code pour info.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    float angleFromCosAndSin(float cosinus, float sinus)
    {
    	float sol1 = acos(cosinus);
    	float sol2 = -sol1;
    	if(sin(sol1) == sinus)
    		return sol1;
    	if(sin(sol2) == sinus)
    		return sol2;
    	char c[128];
    	sprintf(c, "pas de solution : cos=%f, sin=%f, sol1=%f, sol2=%f\n", cosinus, sinus, sol1, sol2);
    	printf("pas de solution : cos=%f, sin=%f, sol1=%f, sol2=%f\n", cosinus, sinus, sol1, sol2);
    	return -1;
    }
     
    void crossProd(float v1[3], float v2[3], float out[3])				// Calculates Normal For A Quad Using 3 Points
    {
    	static const int x = 0;						// Define X Coord
    	static const int y = 1;						// Define Y Coord
    	static const int z = 2;						// Define Z Coord
     
    	// Compute The Cross Product To Give Us A Surface Normal
    	out[x] = v1[y]*v2[z] - v1[z]*v2[y];				// Cross Product For Y - Z
    	out[y] = v1[z]*v2[x] - v1[x]*v2[z];				// Cross Product For X - Z
    	out[z] = v1[x]*v2[y] - v1[y]*v2[x];				// Cross Product For X - Y
    }
     
    void scalarProd(float v1[3], float v2[3], float &out)				// Calculates Normal For A Quad Using 3 Points
    {
    	static const int x = 0;						// Define X Coord
    	static const int y = 1;						// Define Y Coord
    	static const int z = 2;						// Define Z Coord
     
    	// Compute The Scalar Product
    	out = v1[x]*v2[x] + v1[y]*v2[y] + v1[z]*v2[z];
    }
     
    void quatProd(float u1, float v1[3], float u2, float v2[3], float &uOut, float vOut[3])
    {
    	static const int x = 0;						// Define X Coord
    	static const int y = 1;						// Define Y Coord
    	static const int z = 2;						// Define Z Coord
    	float scalProd;
    	float vectProd[3];
    	scalarProd(v1, v2, scalProd);
    	uOut = u1*u2 - scalProd;
    	crossProd(v1, v2, vectProd);
    	vOut[0] = u1*v2[0] + u2*v1[0] + vectProd[0];
    	vOut[1] = u1*v2[1] + u2*v1[1] + vectProd[1];
    	vOut[2] = u1*v2[2] + u2*v1[2] + vectProd[2];
    }
     
    float norme(float vec[3])
    {
    	return sqrt(vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]);
    }
     
    void normaliser(float vec[3])
    {
    	float norm=norme(vec);
    	int i;
    	for(i=0;i<3;i++)
    		vec[i]=vec[i]/norm;
    }
     
    void rotationToQuaternion(float angle, float vec[3], float &uOut, float vOut[3])
    {
    	int i;
    	static const int x = 0;						// Define X Coord
    	static const int y = 1;						// Define Y Coord
    	static const int z = 2;						// Define Z Coord
    	normaliser(vOut);
    	uOut = cos(angle/2);
    	for(i=0;i<3;i++)
    		vOut[0] = vec[0]*sin(angle/2);
    }
     
    void quaternionToRotation(float u, float v[3], float &angle, float vec[3])
    {
    	int i;
    	float cos = u;
    	float sin = norme(v);
    	angle = 2 * angleFromCosAndSin(cos, sin);
    	for(i=0;i<3;i++)
    		vec[i] = v[i]/sin;
    }
     
    void composee(float angle1, float vec1[3], float angle2, float vec2[3], float &angleOut, float vecOut[3])
    {
    	float u1, u2, uRes;
    	float v1[3], v2[3], vRes[3];
    	rotationToQuaternion(angle1, vec1, u1, v1);
    	rotationToQuaternion(angle2, vec2, u2, v2);
    	quatProd(u2, v2, u1, v1, uRes, vRes);
    	quaternionToRotation(uRes, vRes, angleOut, vecOut);
    }
     
    ds le main :
     
    	float angle1, angle2, angleOut;
    	float vec1[3], vec2[3], vecOut[3];
    	angle1=90.0f; vec1[0]=1.0f; vec1[1]=0.0f; vec1[2]=0.0f; 
    	angle2=90.0f; vec2[0]=0.0f; vec2[1]=1.0f; vec2[2]=0.0f; 
    	composee(angle1, vec1, angle2, vec2, angleOut, vecOut);
    Voilà, et là ça me donne des "pas de solution : cos=-0.390704, sin=1.190966, sol1=1.972192, sol2=-1.972192"...

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 112
    Points : 45
    Points
    45
    Par défaut
    Oups! Désolé, je n'ai pas assez relu mon code avant de poster... (erreur très con dans rotationToQuaternion, ensuite il fallait utiliser les fonctions de comparaison de floats, pas l'habitude...).

    Alors maintenant le calcul se fait bien, seulement quand je fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    float angle1, angle2, angleOut;
    float vec1[3], vec2[3], vecOut[3];
    angle1=90.0f; vec1[0]=1.0f; vec1[1]=0.0f; vec1[2]=0.0f; 
    angle2=90.0f; vec2[0]=0.0f; vec2[1]=1.0f; vec2[2]=0.0f; 
    glRotatef(angle1, vec1[0], vec1[1], vec1[2]);
    glRotatef(angle2, vec2[0], vec2[1], vec2[2]);
    ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    float angle1, angle2, angleOut;
    float vec1[3], vec2[3], vecOut[3];
    angle1=90.0f; vec1[0]=1.0f; vec1[1]=0.0f; vec1[2]=0.0f; 
    angle2=90.0f; vec2[0]=0.0f; vec2[1]=1.0f; vec2[2]=0.0f; 
    composee(angle1, vec1, angle2, vec2, angleOut, vecOut);
    glRotatef(angleOut, vecOut[0], vecOut[1], vecOut[2]);
    Ca ne donne pas le même résultat après. J'ai bien transformé les degrès en radians. Je remets tout le code.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    float angleFromCosAndSin(float cosinus, float sinus)
    {
    	float sol1 = acos(cosinus);
    	float sol2 = -sol1;
    	if(sin(sol1) - sinus < FLT_EPSILON)
    		return sol1;
    	if(sin(sol2) - sinus < FLT_EPSILON)
    		return sol2;
    	return -1;
    }
     
    void crossProd(float v1[3], float v2[3], float out[3])				// Calculates Normal For A Quad Using 3 Points
    {
    	static const int x = 0;						// Define X Coord
    	static const int y = 1;						// Define Y Coord
    	static const int z = 2;						// Define Z Coord
     
    	// Compute The Cross Product To Give Us A Surface Normal
    	out[x] = v1[y]*v2[z] - v1[z]*v2[y];				// Cross Product For Y - Z
    	out[y] = v1[z]*v2[x] - v1[x]*v2[z];				// Cross Product For X - Z
    	out[z] = v1[x]*v2[y] - v1[y]*v2[x];				// Cross Product For X - Y
    }
     
    void scalarProd(float v1[3], float v2[3], float &out)				// Calculates Normal For A Quad Using 3 Points
    {
    	static const int x = 0;						// Define X Coord
    	static const int y = 1;						// Define Y Coord
    	static const int z = 2;						// Define Z Coord
     
    	// Compute The Scalar Product
    	out = v1[x]*v2[x] + v1[y]*v2[y] + v1[z]*v2[z];
    }
     
    void quatProd(float u1, float v1[3], float u2, float v2[3], float &uOut, float vOut[3])
    {
    	float scalProd;
    	float vectProd[3];
    	scalarProd(v1, v2, scalProd);
    	crossProd(v1, v2, vectProd);
    	uOut = u1*u2 - scalProd;
    	vOut[0] = u1*v2[0] + u2*v1[0] + vectProd[0];
    	vOut[1] = u1*v2[1] + u2*v1[1] + vectProd[1];
    	vOut[2] = u1*v2[2] + u2*v1[2] + vectProd[2];
    }
     
    float norme(float vec[3])
    {
    	return sqrt(vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]);
    }
     
    void normaliser(float vec[3])
    {
    	float norm=norme(vec);
    	int i;
    	for(i=0;i<3;i++)
    		vec[i]=vec[i]/norm;
    }
     
    void rotationToQuaternion(float angle, float vec[3], float &uOut, float vOut[3])
    {
    	float angleRad = DegreeToRadian(angle);
    	int i;
    	normaliser(vOut);
    	uOut = cos(angleRad/2);
    	for(i=0;i<3;i++)
    		vOut[i] = vec[i]*sin(angleRad/2);
    }
     
    void quaternionToRotation(float u, float v[3], float &angle, float vec[3])
    {
    	int i;
    	float cos = u;
    	float sin = norme(v);
    	float angleRad = 2 * angleFromCosAndSin(cos, sin);
    	angle = RadianToDegree(angleRad);
    	for(i=0;i<3;i++)
    		vec[i] = v[i]/sin;
    }
     
    void composee(float angle1, float vec1[3], float angle2, float vec2[3], float &angleOut, float vecOut[3])
    {
    	float u1, u2, uRes;
    	float v1[3], v2[3], vRes[3];
    	rotationToQuaternion(angle1, vec1, u1, v1);
    	rotationToQuaternion(angle2, vec2, u2, v2);
    	quatProd(u2, v2, u1, v1, uRes, vRes);
    	quaternionToRotation(uRes, vRes, angleOut, vecOut);
    }
    Sinon reste la deuxième question, est-ce que la classe Quaternions est incluse dans une librairie?

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 112
    Points : 45
    Points
    45
    Par défaut
    Sachant que si je mets
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    glRotatef(angleOut, vecOut[0], vecOut[1], -vecOut[2]);
    (le - en plus), ca marche...

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 112
    Points : 45
    Points
    45
    Par défaut
    Désolé pour le monologue. Oubliez la dernière remarque.
    Alors en fait il semble que je fasse la multiplication dans le mauvais sens (dans l'autre sens ça marche). Pourtant j'ai bien lu partout qu'il fallait faire la multiplication dans le sens inverse de l'ordre des rotations. Et c'est ce que je fais il me semble.

  9. #9
    Expert éminent

    Profil pro
    Fabricant et casseur d'avions
    Inscrit en
    Avril 2004
    Messages
    3 813
    Détails du profil
    Informations personnelles :
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Fabricant et casseur d'avions
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2004
    Messages : 3 813
    Points : 7 638
    Points
    7 638
    Par défaut
    Citation Envoyé par bourriquet_42 Voir le message
    donc avec cette méthode, ça rend toujours celui entre 0 et pi
    entre 0 et 2*Pi plutôt... l'acos te donne une valeur entre 0 et Pi, et il y a un facteur 2.
    Pour l'autre angle, le vecteur rotation serait inversé.


    Citation Envoyé par bourriquet_42 Voir le message
    Ah oui! L'autre question c'était est-ce que la classe Quaternion dont ils parlent existe dans une librairie?
    Roh oui...
    Sinon tu as tout le code qu'il te faut pour l'écrire dans le lien que je t'ai donné


    Et pour le monologue, plutôt que de faire 36 messages où on ne sait plus où on en est au final, édite le premier
    "Errare humanum est, sed perseverare diabolicum"

    Ma page sur DVP.com

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 112
    Points : 45
    Points
    45
    Par défaut
    Alright, j'avais oublié qu'on pouvait éditer... Merci.
    Donc quelqu'un comprend pourquoi je suis obligé d'inverser ma multiplication alors que je fais bien Q2*Q1 pour R1oR2...

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 112
    Points : 45
    Points
    45
    Par défaut
    Encore une question. Je voudrais faire une rotation avec glRotatef, suivie d'une autre rotation selon un axe dont je connais les coordonnées dans l'ancien système mais pas le nouveau.
    Pour faire simple, je veux tourner d'un certain angle autour de y, puis tourner d'un certain angle autour de x, mais pas le nouveau après rotation sur y, l'ancien.
    Est-ce qu'il y a une méthode plus simple que de calculer les coordonnées de l'ancien x dans le nouveau système? (x et y sont des exemples)

    Merci

  12. #12
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2008
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2008
    Messages : 60
    Points : 74
    Points
    74
    Par défaut
    si tu utilise les quaternion a la fin tu doit te retrouver, soit avec un matrice de rotation, soit avec un axe de rotation et un angle qui correspond au total de tes rotation,

    en ouvrant les sources de n'importe quel moteur 3d tu doit pouvoir trouver comment obtenir ta matrice ou ton axe et ton angle

    sinon tu peut carrément utiliser les classe d'un moteur physique ou graphique existant,tu gagnera un temps fou,mais c est moins instructif

    sinon regarde la
    http://www.cprogramming.com/tutorial...aternions.html

    y a un dessin des matrices assez parlant

    haha!! mais je viens de voir que le premier lien poster repond a toutes tes questions lol,,en plus il est plus clair

  13. #13
    Expert éminent
    Avatar de raptor70
    Inscrit en
    Septembre 2005
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Septembre 2005
    Messages : 3 173
    Points : 6 812
    Points
    6 812
    Par défaut
    Beaucoup de tes questions trouverons une réponse par ici http://jeux.developpez.com/faq/matquat/?filtre=OOOOOOO
    Mes Tutos DirectX, OpenGL, 3D : http://raptor.developpez.com/

Discussions similaires

  1. Réponses: 1
    Dernier message: 23/06/2002, 00h15
  2. Existe t'il un composant permettant de jouer un son wav?
    Par scorpiwolf dans le forum C++Builder
    Réponses: 5
    Dernier message: 20/06/2002, 14h10
  3. Redéfinir l'événement OnExit de mon composant TEditFloat
    Par Seb des Monts dans le forum C++Builder
    Réponses: 5
    Dernier message: 18/06/2002, 16h10
  4. Installer ses composants
    Par Geronimo dans le forum C++Builder
    Réponses: 14
    Dernier message: 18/06/2002, 14h51
  5. Re-dimensionnement automatique de composants
    Par ludo_7 dans le forum C++Builder
    Réponses: 10
    Dernier message: 16/05/2002, 16h35

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo