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

OpenGL Discussion :

Rotation d'une sphère avec axes fixes


Sujet :

OpenGL

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 10
    Points : 5
    Points
    5
    Par défaut Rotation d'une sphère avec axes fixes
    Bonjour,

    J'essaye de réaliser un jeu dans le genre de kula-world en utilisant OpenGL dans lequel j'ai besoin de faire rouler une sphere selon 3 axes qui restent fixes dans l'espace (au depart : x=gauche-droite / y=avant-arriere / z=haut-bas).

    Le problème que je rencontre est qu'avec la fonction glRotatef, le repère tourne : après une rotation selon X, les axes Y et Z n'ont plus la même orientation.

    Je cherche un moyen de faire une rotation selon X, suivi d'une rotation selon l'axe Y (tel qu'il etait avant la rotation sur X) puis selon l'axe Z (tel qu'il était avant les rotations sur X et Y). (cela donne l'impression que l'on pousse la balle pour la faire avancer en roulant sur les différents axes)

    Après moult recherches et essais, voici la technique que je pense mettre en place :

    • Je définis 3 vecteurs axeX=(1,0,0) axeY=(0,1,0) et axeZ=(0,0,1)
    • Je fais une rotation du repere selon axeX (avec un angle x)
    • Je calcule les nouvelles coordonnées des vecteur axeY et axeZ dans ce nouveau repere afin qu'ils aient toujours "visuellement" la meme orientation qu'au départ.
    • Je realise la rotation selon axeY (qui ne correspond plus au a l'axe Y du repere opengl.)
    • Je calcule les nouvelles coordonnées des vecteurs axeX et axeZ pour qu'ils aient l'air de rester fixes
    • Je réalise finalement la rotation selon axeZ (qui ne correspond plus du tout a l'axe Z de depart puisque ce dernier a subi 2 rotations).
    • J'affiche ma gluSphere.
    • Et ainsi de suite...


    Pour vous donnez une idée j'ai 2 vidéos :

    La première illustre le problème d'axe : dès que la sphere n'a pas fait un tour complet sur un axe avant de rouler sur un autre axe, la balle roule selon un axe faux. (puisque dans cette vidéo, j'utilise les axes du repere opengl qui subissent les rotations) http://www.youtube.com/watch?v=AdQnh7q_w7o

    La deuxième vidéo donne une idée du développement actuel : avec des rotations de la balle cela serait mieux... http://www.youtube.com/watch?v=XAKLWJFElgw

    Avant de partir sur une n-ième fausse piste, j'aimerais avoir votre avis sur la question. Ma méthode peut-elle fonctionner ? Y-a-t-il plus simple pour garder des axes fixes lors d'une rotation ?

    Merci.
    Jean-Michel.

  2. #2
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 10
    Points : 5
    Points
    5
    Par défaut
    Si vous me le permettez, je tente une seconde formulation sûrement plus compréhensible :

    Comment appliquer à une sphère 3 rotations successives sur chacun des 3 axes globaux à la scène et non sur les 3 axes locaux de la sphère ?

    (et si vous ne me le permettez pas... ben tant pis, c'est fait )

  3. #3
    Membre éclairé Avatar de MatRem
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    750
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 750
    Points : 693
    Points
    693
    Par défaut
    Malheureusement je penses que c'est à toi de voir de quelle façon évolue le repère local, pour appliquer la bonne rotation.

  4. #4
    Rédacteur
    Avatar de bafman
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    2 574
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2003
    Messages : 2 574
    Points : 5 323
    Points
    5 323
    Par défaut
    je dirait (au pif) qu'il faut transformer ta matrice de rotation globale dans la matrice de rotation inversé de la balle (mais en même temps, c'est le matin et je suis pas trop réveillé
    * Il est infiniment plus simple de faire rapidement un code qui marche que de faire un code rapide qui marche
    * pour faciliter les recherches, n'oubliez pas de voter pour les réponses pertinentes
    Mes articles

  5. #5
    Membre habitué Avatar de razmott
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    133
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 133
    Points : 142
    Points
    142
    Par défaut
    Salut !

    La solution est surement les quaternions. Tu trouveras des exemples de la FAQ de développez.com :

    http://jeux.developpez.com/faq/matqu...ge=quaternions

    Bon coding !

    @+
    Mieux vaut prévoir que patcher.

  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 10
    Points : 5
    Points
    5
    Par défaut
    Merci, le problème reste le même avec les quaternions, le repere est celui de la sphere (il subit les rotations en meme temps que la sphere).

    Je crois avoir trouvé une piste et je crois que ça correspond à ce que veut dire bafman (je me suis mis très récemment à la programmation 3D (et la géométrie dans l'espace) donc j'ai un peu de mal à me faire comprendre et à comprendre)

    - je récupère la matrice modelview apres avoir fait tourner la balle
    - j'applique l'inverse de cette matrice à 3 vecteurs correspondant aux trois axes qui ne doivent pas tourner
    - la prochaine rotation aura lieu selon les axes précedemment obtenus

    en théorie ca me parait pas mal, j'attends quand même de voir le résultat avant de mettre "résolu"

  7. #7
    Membre habitué Avatar de razmott
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    133
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 133
    Points : 142
    Points
    142
    Par défaut
    Salut !

    Merci, le problème reste le même avec les quaternions, le repere est celui de la sphere (il subit les rotations en meme temps que la sphere).
    Normalement non, mais bon, je vais me renseigner.
    Dis nous si ta nouvelle méthode marche.

    @+
    Mieux vaut prévoir que patcher.

  8. #8
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 10
    Points : 5
    Points
    5
    Par défaut
    Bon... Après un mois de recherche (pas à plein temps heureusement ) j'ai enfin résolu mon problème.

    En passant par les quaternions cela marche de manière impéccable :

    - un quaternion 1 qui stocke l'orientation de la balle (résultante de toutes les rotations précédentes)

    - un quaternion 2 qui stocke la prochaine rotation

    On multiplie le premier par le deuxième et le tour est joué : les axes sont invariables. (tu avais bien raison razmott)

    Vidéo sur YouTube

    Merci à vous !

  9. #9
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 27
    Points : 7
    Points
    7
    Par défaut
    Bonjour,

    J'ai exactement le meme probleme, du a un besoin de faire tourner un objet grace a la souris.
    Je me sert donc des quaternions, mais le probleme persiste, ma seconde rotation se fait a partir de la premiere, ce que je ne comprend pas.

    voila le bout de code qui s'en charge :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    glMatrixMode( GL_MODELVIEW );
      glLoadIdentity();
      gluLookAt(0,0,10,0,0,0,0,1,0);				// Place the camera
      if(size < 0)
        size = 0;
      glScalef((float)(size),(float)(size),(float)(size));		// Change size (zoom)
      glTranslatef(hshift, vshift, 0);				// Translate (user's movements)
      q1.createFromAxisAngle(0,1,0,hAng);
      q2.createFromAxisAngle(1,0,0,vAng);
      q1 = q1*q2;
      q1.normalise();
      q1.createMatrix(matrix);
      glMultMatrixf(matrix);
    Pour la class des quaternions, je me suis servi de la FAQ et du tuto de NeHe. (juste histoire d'avoir plusieures sources).
    Et voici ma methode de multipication des Quaternions :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    glQuaternion 
    glQuaternion::operator *(glQuaternion q){
      glQuaternion r;
      r.w = w*q.w - x*q.x - y*q.y - z*q.z;
      r.x = w*q.x + x*q.w + y*q.z - z*q.y;
      r.y = w*q.y + y*q.w + z*q.x - x*q.z;
      r.z = w*q.z + z*q.w + x*q.y - y*q.x;
     
      return r;
    };

  10. #10
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 10
    Points : 5
    Points
    5
    Par défaut
    Voici quelques détails sur la solution que j'ai utilisé :

    dans le constructeur du ballon :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    //Quaternion correspondant à l'orientation de la balle dans l'espace:
    quat_ballon=new Quaternion(1,0,0,0);
     
    //Quaternion stockant la prochaine rotation à effectuer	:
    quat_rotation=new Quaternion(1,0,0,0);


    Quand il y a besoin d'appliquer une rotation au ballon:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    void Ballon::RotationRoule()
    {
    // je crée un quaternion contenant la nouvelle rotation à appliquer
    // depuis la derniere frame à partir d'un angle et d'un axe global invariable
    // exemple si je veux une rotation sur l'axe Z, j'utilise axeX=0, axeY=0, axeZ=1
    quat_rotation->EulerVersQuat(angle_de_rotation_a_appliquer, axeX, axeY, axeZ);
     
    //je multiplie le quat contenant l'orientation du ballon
    //par celui contenant la nouvelle rotation à appliquer
    //equivalent à quat_ballon=quat_ballon*quat_rotation
    quat_ballon->Mult(quat_rotation);
    }

    Pour afficher la sphere
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    //on se place au centre du ballon
    glTranslated( posX, posY, posZ);
     
    //on fait tourner le ballon en transformant
    //le quaternion d'orientation en représentation ange/axe
    glRotatef(quat_ballon->GetAngle(), quat_ballon->GetAxe()->x,
             quat_ballon->GetAxe()->y, quat_ballon->GetAxe()->z);
     
    //on affiche la sphère
    gluSphere(params,rayon,30,30);
    et ainsi de suite...


    Pour le code utilisé dans ma classe quaternion :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    //GetAngle() : Retourne l'angle de rotation à appliquer selon l'axe GetAxe();
    float Quaternion::GetAngle()
    {
    double angle=acos(w)*2*180/pi;
    return (float) angle;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    //GetAxe() : Retourne le vecteur unitaire de l'axe de rotation
    Vecteur3D* Quaternion::GetAxe()
    {
    scale = sqrt(x*x + y*y+ z*z);
    Axe->Set((float) x/scale, (float) y/scale, (float) z/scale);	
    return Axe;
    }

  11. #11
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 27
    Points : 7
    Points
    7
    Par défaut
    Merci pour ton code jmb462.

    Mais cela ne resout pas mon probleme, je ne comprend toujours pas. Pourtant mon code est sensiblement identiqe au tiens :
    - J'initialise mes deux quaternion a 1,0,0,0 pour w,x,y,z
    - Je stocke la preire rotation avec la fonction createFromAxisAngle de la FAQ
    - Je multiplie mes deux quaterions (le ref par la rotation)
    - Je stocke une nouvelle rotation dans mon quaternion de rotation
    - Je fait une seconde multiplication
    - Je tranforme mon quaternion de ref en angle et axe, toujours d'apres la FAQ
    - je fait tourner mon objet avec glRotatef()

    J'ai egalement essaye les deux dernier point en utilisant une matrice de rotation, cela revient au meme.
    Au final, ma seconde rotation est toujours relative a la premiere. Mais la troisieme par contre se fait corectemant, avec la quatrieme relative a la troisieme. et ainsi de suite.

    Ce qui est tres etrange au final. Pour meux vous expliquer ce que j'obtient : Je fait en boucle deux rotation a la suite, pour suivre les deplacement a la souris, une sur x, puis une sur y.
    Et les rotations sur x se font toujours par rapport au repere global, alors que celles sous y se font toujours par rapport au repere de l'objet

    Une idee d'ou se trouve le probleme ?

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

Discussions similaires

  1. Problème pour faire la rotation d'une image(Avec ImageJ)
    Par tadjara dans le forum Débuter avec Java
    Réponses: 0
    Dernier message: 10/04/2010, 11h33
  2. [GD] rotation d'une image avec GD
    Par DiverSIG dans le forum Bibliothèques et frameworks
    Réponses: 1
    Dernier message: 09/09/2009, 09h23
  3. [Débutant] afficher une image avec axes
    Par Nideis dans le forum Interfaces Graphiques
    Réponses: 3
    Dernier message: 20/02/2009, 16h33
  4. Dessiner une sphère avec un vertex shader
    Par zeyous dans le forum OpenGL
    Réponses: 10
    Dernier message: 18/03/2008, 11h34
  5. Réponses: 2
    Dernier message: 19/11/2007, 16h53

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