|
Publicité ' | |||||||||||||||||||||||
|
|
#1 |
|
Futur Membre du Club
![]() Inscription : juillet 2008 Messages : 50 ![]() |
Voilà quelques jours que je m'acharne à maitriser les rotations d'une simple boite.
Impossible d'obtenir de bon résultat malgré les divers méthodes que j'ai tenté. J'ai tout d'abord naïvement essayé de gérer mes rotations avec les angles d'Euler. Je suis rapidement tombé sur un problème connu nommé le blocage de cardan (ou gimbal lock). Ce problème engendre, par exemple l'alignement de 2 axes ( une rotation sur l'axe des X peut donner le même résultat qu'une rotation sur l'axe des Z ). Après quelques recherche, je lis qu'en utilisant des Quaternions, il est possible d'évité le problème. J'implémente et expérimente cette solution et le blocage de cardan est totalement évité. À ce stade, j'ai donc une fonction membre dans mes objets prototypé ainsi: void Rotate(double x, double y, double z); //angle en Degree Cependant, après de nombreux tests, je constate une imperfection. J'isole l'action qui pose problème; Si j'effectue 2 appels consécutifs à ma fonction Rotate(10, 10, 0) puis Rotate(-10, -10, 0), une rotation est effectué sur l'axe des Z (alors que normalement, l'objet devrait resté immobile, non?) Est-ce que j'ai mal implémenté les quaternions ? peut être. C'est pourquoi j'ai remplacer mes quaternions pas ceux de la lib glm (OpenGL math). Toujours le même problème ! J'ai alors décidé de changer de méthode. Je suis tombé sur la technique des GLFrame dans le livre de la Bible d'OpenGL. J'ai implémenter cette nouvelle class, et essayé à nouveau. Pas de gimbal lock non plus avec cette solution ("Youpi"), mais...Toujours le même problème ! Je ne sais plus quoi faire et je commence sérieusement à me demander comment les rotations sont implémenté dans les moteurs 3D. Pour ce qui de mon problème, j'ai réalisé un code minimal qui mets en évidence ce dernier. Il a été réalisé avec SFML et OpenGL. Les instructions sont affiché à l'execution du programme. Un executable est présent dans l'archive pour observer rapidement le problème. Un autres action problématique peut être exécuté dans la démonstration; il s'agit d'une boucle qui exécuté 360 fois une rotation de (1, 1, 0) (donc on devrait revenir au début, et ce n'est pas la cas !). Lien du telechargement: http://uploading.com/files/eef4cb1e/...deMinimal.rar/ Merci d'avance
|
|
|
00
|
|
|
#2 | |
|
Expert Confirmé Sénior
![]() ![]() Jean-Michel BORLOTFabricant et casseur d'avions Inscription : avril 2004 Messages : 3 239 ![]() |
Salut
Citation:
En gros, tes deux instructions reviennent à faire quatre rotations, une Rx(10), un Ry(10),une Rx(-10) et un Ry(-10). Encore faudrait-il avoir l'algorithme pour en être sûr... mais si ça fait ça dans cet ordre-ci, normal que ça bouge. L'objet reviendrait à sa position initiale si ça faisait Rx(10)/Ry(10)/Ry(-10)/Rx(-10). A confirmer... A quoi correspondent les trois paramètres de ta fonction rotate? D'habitude pour définir une rotation, on en utilise 4, les 3 composantes de l'axe, et l'angle de roation. |
|
|
00
|
|
|
#3 | ||
|
Futur Membre du Club
![]() Inscription : juillet 2008 Messages : 50 ![]() |
Citation:
Citation:
En faite, j'ai eu l'occasion de tester certains moteur 3D qui utilisé ce genre de fonction très pratique. (c'est le cas du moteur Shiva3D par exemple, avec la fonction "object.rotate ( hObject, nRx, nRy, nRz, kSpace )"). Je pensais donc que l'élaboration d'une telle fonction était largement faisable. En tout cas c'est ce que je cherche à réaliser en tout cas, merci de t’intéresser au problème
|
||
|
|
00
|
|
|
#4 | |
|
Expert Confirmé Sénior
![]() ![]() Jean-Michel BORLOTFabricant et casseur d'avions Inscription : avril 2004 Messages : 3 239 ![]() |
Citation:
Donc si tu veux faire une transformation inverse, il ne faut pas utiliser la même fonction avec les angles de rotation opposé, mais plutôt utiliser/créer la fonction rotate inverse (celle qui fera les rotations suivant la combinaison Rz, puis Ry puis Rx). |
|
|
10
|
|
|
#5 |
|
Futur Membre du Club
![]() Inscription : juillet 2008 Messages : 50 ![]() |
Je ne vois pas pourquoi ce serait impossible. Prenons le cas de la fonction qui prends 4 paramètres; glRotate(MonAngle, AxeX, AxeY, AxeZ). l'inverse de cette rotation est bien glRotate(- MonAngle, AxeX, AxeY, AxeZ). (en tout cas cela marche sur opengl, je viens de tester)
Après je cherche juste un moyen de convertir mes 3 paramètres angulaires en ces 4 paramètres pour effectuer une unique rotation. |
|
|
00
|
|
|
#6 | |
|
Expert Confirmé Sénior
![]() ![]() Jean-Michel BORLOTFabricant et casseur d'avions Inscription : avril 2004 Messages : 3 239 ![]() |
Citation:
Quand je disais que c'était impossible, c'était pour dire que c'est impossible de résumer un enchainement de trois rotations en un unique quaternion sans définir un ordre permettant de préciser la séquence d'enchainement des trois rotations. Pour illustrer, si tu prends la séquence suivante: Rx de alpha degrés, Ry de beta degrés, Rz de gamma degré, tu vas pouvoir résumer ça en un rotation avec un quaternion (angle, axeX,axeY,axeZ) Si tu prends la séquence Rx de -alpha degrés, Ry de -beta degrés, Rz de -gamma degré, ça va te donner autre chose que le quaternion (-angle, axeX,axeY,axeZ) (à noter que je dis ça sans tester... mais logiquement, ça ne doit pas! )Ce que tu as déjà fait d'après ce que tu nous as expliqué dans ton premier post. Le seul truc à comprendre, c'est que la transformée inverse par la méthode des trois angles n'est pas la même fonction avec l'opposé des angles... tout ça parce que l'ordre d'application des rotations est important (comprendre: les rotations 3D ne sont pas commutatives) |
|
|
00
|
|
|
#7 |
|
Futur Membre du Club
![]() Inscription : juillet 2008 Messages : 50 ![]() |
Ok merci, je pense avoir compris
Ce qui m'embête, c'est que je n'arrive pas encore à saisir le même résultat de cette transformation manuellement (en vrai, avec un crayon^^) que la transformation qui résulte de mon programme. Cependant je vois bien maintenant, qu'à l'évidence (en le simulant avec mon crayon) les résultats ne sont pas ceux que je pensais avoir au début. Aussi j'ai comparé mon programme à un moteur (shiva3d) disposant d'une telle fonction pour confirmer cette nouvelle affirmation. VOUI; les résultats sont les même que dans mon programme donc il ne s'agissait que d'un principe mathématique que je n'arrivais pas à saisir. Merci de ton aide
|
|
|
00
|
Copyright © 2000-2013 - www.developpez.com