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

Moteurs 3D Discussion :

Probleme Rotation (avec ou sans quaternion)


Sujet :

Moteurs 3D

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

    Informations forums :
    Inscription : Juillet 2008
    Messages : 52
    Points : 41
    Points
    41
    Par défaut Probleme Rotation (avec ou sans quaternion)
    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

  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

    Citation Envoyé par Scheb Voir le message
    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?)
    Oserais-je dire que non?

    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.
    "Errare humanum est, sed perseverare diabolicum"

    Ma page sur DVP.com

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

    Informations forums :
    Inscription : Juillet 2008
    Messages : 52
    Points : 41
    Points
    41
    Par défaut
    Oserais-je dire que non?
    C'est possible oui, mais avec l'utilisation des quaternions (ou de GLFrame), je souhaitais pouvoir combiné ces rotations. (ne pas avoir d'ordre de rotation à suivre)

    Citation Envoyé par plegat Voir le message
    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.
    C'est exacte, c'est la forme demander par la fonction glRotate d'OpenGl. Cependant ce n'est pas vraiment pratique pour l'utilisateur qui veut effectuer effectué plusieurs rotation combiné. Voilà pourquoi mes 3 paramètres correspondent à 3 valeur d'angles en degrés (pour les 3 axes).

    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

  4. #4
    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 Scheb Voir le message
    C'est possible oui, mais avec l'utilisation des quaternions (ou de GLFrame), je souhaitais pouvoir combiné ces rotations. (ne pas avoir d'ordre de rotation à suivre)
    Ce qui mathématiquement est impossible à faire, une combinaison Rx puis Ry étant différente d'une combinaison Ry puis Rx. Les rotations ne sont pas commutatives (sauf cas particuliers de certains angles, mais peut-on réellement parler de cas particuliers...), ce qui nécessite d'imposer un ordre. Les fonctions ne prenant que 3 angles pour effectuer une rotation combinée imposent implicitement cet ordre de par leur algorithme (genre Rx, puis Ry, puis Rz... à confirmer en jetant un oeil au code de la fonction)

    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).
    "Errare humanum est, sed perseverare diabolicum"

    Ma page sur DVP.com

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

    Informations forums :
    Inscription : Juillet 2008
    Messages : 52
    Points : 41
    Points
    41
    Par défaut
    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.

  6. #6
    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 Scheb Voir le message
    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)
    Cette fonction là effectue une rotation d'un certain angle autour d'un certain axe. Dans ce cas, la transformée inverse est effectivement la rotation d'angle opposé avec le même axe.
    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! )


    Citation Envoyé par Scheb Voir le message
    Après je cherche juste un moyen de convertir mes 3 paramètres angulaires en ces 4 paramètres pour effectuer une unique rotation.
    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)
    "Errare humanum est, sed perseverare diabolicum"

    Ma page sur DVP.com

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

    Informations forums :
    Inscription : Juillet 2008
    Messages : 52
    Points : 41
    Points
    41
    Par défaut
    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

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Rotation avec quaternion selon un repère précis
    Par Scheb dans le forum Développement 2D, 3D et Jeux
    Réponses: 1
    Dernier message: 24/03/2013, 13h11
  2. rotation avec des quaternions
    Par tiloup367 dans le forum Mathématiques
    Réponses: 2
    Dernier message: 09/11/2010, 13h17
  3. Problème avec clavier sans fil + switch
    Par gwendal84 dans le forum Matériel
    Réponses: 1
    Dernier message: 31/03/2006, 14h50
  4. probleme sql avec delphi
    Par lil_jam63 dans le forum Bases de données
    Réponses: 7
    Dernier message: 25/02/2004, 04h32
  5. probleme GRAVE avec directx 9
    Par l'arbre en plastique dans le forum DirectX
    Réponses: 3
    Dernier message: 02/09/2003, 23h59

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