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 :

orientation de cylindre


Sujet :

OpenGL

  1. #1
    Membre habitué
    Inscrit en
    Juillet 2009
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 12
    Par défaut orientation de cylindre
    Bonjour tout le monde!

    J'ai un petit problème qui je suis sur a une solution pas si compliqué mais j'ai le nez dessus depuis tellement longtemps que je n'arrive plus a rien. En fait voila je crée un cylindre avec gluCylinder que je place verticalement en lui appliquant la rotation suivante :
    glRotatef(-90, 1, 0, 0);

    Jusque là tout va bien. Seulement voilà, ce cylindre j'aimerais pouvoir changer son orientation comme je veux en cliquant sur des boutons. C'est à dire lui appliquer d'autre rotations par rapport aux Ox Oy et Oz. Et là ça bloque. si je considère un seul axe ça va mais kan je fais des rotations par rapport à l'axe Oy et ensuite que je le fais tourner un peu par à l'axe Oy et ben j'obtiens pas ce sue je veux. Je n'arrive pas à l'aligner correctement.
    j'ai pensé à récupérer son orientation en calculant l'angle de sa hauteur avec les trois axes Ox Oy et Oz mais là je m'embrouille et je n'y arrive pas.
    Pouvez vous m'aider SVP.

  2. #2
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 150
    Billets dans le blog
    150
    Par défaut
    Bonjour,

    J'ai pas tout compris ce que vous voulez ( enfin le fait que ça ne marche pas ).
    La seule chose que je peux dire, c'est que lorsque on veut faire des rotations sur les trois angles, il faut utiliser les quaternions, pour eviter un effet appeler le gimbal lock si je me rapelle bien ( qui est un effet de perte d'un axe de rotation après avoir fait une rotation ... ( voir wiki ) ).
    Peut être que c'est votre problème
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  3. #3
    Membre habitué
    Inscrit en
    Juillet 2009
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 12
    Par défaut
    mon problème vient de la non commutativité des rotations.
    en fait quand je fais une rotation d'angle a1 /Ox at ensuite une rotation de a2 /Oy et enfin une rotation de a3 / Ox dans mon code j'écris :
    glRotatef(a1 + a3, 1, 0, 0);
    glRotatef(a2, 0, 1, 0);

    alors qu'en fait j'ai fait
    glRotatef(a3, 1, 0, 0);
    glRotatef(a2, 0, 1, 0);
    glRotatef(a1, 1, 0, 0);

    mon cylindre n'est donc pas correctement orienté. J'ai donc pensé à récupérer son orientation avec les angles d'euler mais je sais pas comment faire.

    pour ce qui est des quaternions jc pas trop comment les utiliser ni si mon problème est celui des gimbal lock.

  4. #4
    Membre très actif Avatar de oxyde356
    Homme Profil pro
    Ingénieur Recherche Imagerie
    Inscrit en
    Février 2006
    Messages
    797
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur Recherche Imagerie

    Informations forums :
    Inscription : Février 2006
    Messages : 797
    Par défaut
    Je crois comprendre ton problème, et pour le résoudre je te conseille de passer par les matrices, les glRotate c'est comme les glBegin, glVertex etc... c'est "deprecated"
    Enfaite il faut que tes transformations soient relatives à la frame précédente ce qui n'a pas l'air d'être le cas actuellement.
    Tu dois donc avoir une matrice représentant les transformations appliquées à ton objet et la mettre à jour à chaque frame et en la prenant en considération dans ton calcul de la sorte :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    //matWorld contient les transformations de l'objet à la frame précédente
    QUATERNION quatRotation(1.0f,0.0f,0.0f,PI*fTimeElapsed);
    MATRIX matRotation;
    matRotation.quaternionToMatrix(quatRotation);
    m_matWorld *= matRotation;
    //matWorld contient maintenant les transformations de l'objet à la frame courante
    Petite description :
    On créé un quaternion (en somme une structure définissant une rotation grâce à un axe et un angle, voir tes math ). Celui-ci nous permet de définir une rotation et d'éviter certains problèmes dû à ce genre de transformation. On créé ensuite une matrice, et on convertie ce quaternion en matrice (ça se trouve facilement sur le net). Puis on multiplie la matrice matWorld représentant les transformations (ici rotation) de l'objet à la frame précédente avec la nouvelle rotation et on obtient la matrice résultat, qui définit les transformations de ton objet à ta frame courante.
    Après dans ta fonction de rendu tu n'as plus qu'à faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    glPushMatrix();
    glMultMatrixf(m_matWorld);
    drawCylinder();
    glPopMatrix();
    A toi de surcharger l'opérateur de cast pour que ta matrice puisse être prise en paramètre de glMultMatrix ce qui ne devrait pas être trop dur.

    Si tu tiens vraiment à utiliser et à éviter les quaternions tu peux peut être faire comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    glPushMatrix();
    glMultMatrixf(m_matWorld);
    glRotate...
    glRotate...
    glRotate...
    m_matWorld = glGetFloatv(GL_MODELVIEW_MATRIX);
    drawCylinder();
    glPopMatrix();
    Dans ce cas tu met à jour ta matrice courante juste avant l'affichage (ce que je te déconseille) et puis je ne sais pas si tu évitera l'effet de gimbal lock qui est très génant.

    N'hésite pas si tu as des questions.

  5. #5
    Membre habitué
    Inscrit en
    Juillet 2009
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 12
    Par défaut
    Merci oxyde356. jpense que tu as parfaitement compris mon problème.
    par rapport à ta réponse j'ai compris le principe reste plus qu'à mettre ça en code.
    ya juste un truc que j'aimerais que tu m'expliques si possible ce que tu as appelé QUATERNION c'est une classe c ça??? mais c koi que tu lui passes comme paramètres dans son constructeur c pas 4 float?? est -ce que tu pourrais me dire à koi correspondent ces paramètres merci

  6. #6
    Membre très actif Avatar de oxyde356
    Homme Profil pro
    Ingénieur Recherche Imagerie
    Inscrit en
    Février 2006
    Messages
    797
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur Recherche Imagerie

    Informations forums :
    Inscription : Février 2006
    Messages : 797
    Par défaut
    Les quaternions c'est une notion mathématique (comme les matrices, les vecteurs ...) qui te permet de définir une rotation autour d'un axe. Effectivement l'idéal c'est de l'encapsuler dans une classe, mon constructeur prend effectivement 4 flottants, les 3 premiers définissent le vecteur (l'axe de rotation) et le 4° flottant l'angle en radian. Grâce à ce quaternion tu pourras initialiser ta matrice de rotation correctement. Tu ne devrais pas avoir de mal à trouver des infos sur l'implémentation des quaternions dont voici une structure minimaliste, libre à toi de t'en inspirer :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    struct QUATERNION
    	{
    		//Je te conseille de lui faire un constructeur :P
     
    		//X,Y,Z : Coordonnées du vecteur définissant l'axe de rotation
    		FLOAT	m_fX;
    		FLOAT	m_fY;
    		FLOAT	m_fZ;
                    //W : cosf(Angle/2.0f) (je crois ^^)
    		FLOAT	m_fW;
    	};
    Et ici la définition d'une matrice à partir d'un quaternion :
    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
    MATRIX&	MATRIX::quaternionToMatrix(const QUATERNION& qRot)
    	{
    		identity();
     
            GLfloat n, s;
            GLfloat xs, ys, zs;
            GLfloat wx, wy, wz;
            GLfloat xx, xy, xz;
            GLfloat yy, yz, zz;
     
            n = (qRot.m_fX * qRot.m_fX) + (qRot.m_fY * qRot.m_fY) + (qRot.m_fZ * qRot.m_fZ) + (qRot.m_fW * qRot.m_fW);
            s = (n > 0.0f) ? (2.0f / n) : 0.0f;
     
            xs = qRot.m_fX * s;  ys = qRot.m_fY * s;  zs = qRot.m_fZ * s;
            wx = qRot.m_fW * xs; wy = qRot.m_fW * ys; wz = qRot.m_fW * zs;
            xx = qRot.m_fX * xs; xy = qRot.m_fX * ys; xz = qRot.m_fX * zs;
            yy = qRot.m_fY * ys; yz = qRot.m_fY * zs; zz = qRot.m_fZ * zs;
     
    		setValue(0,0,1.0f - (yy + zz));	setValue(1,0,xy - wz);			setValue(2,0,xz + wy);
            setValue(0,1,xy + wz);			setValue(1,1,1.0f - (xx + zz));	setValue(2,1,yz - wx);
            setValue(0,2,xz - wy);			setValue(1,2,yz + wx);			setValue(2,2,1.0f - (xx + yy));
     
    		return (*this);
    	}
    Tu peux trouver des infos sur ce même site, ici :
    http://jeux.developpez.com/faq/matqu...ge=quaternions
    Si tu remonte tu aura aussi la faq sur les matrices.

  7. #7
    Membre habitué
    Inscrit en
    Juillet 2009
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 12
    Par défaut
    Merci oxyde356 pour tes explications. je m'en suis fortement inspiré et résultat ça marche nickel.
    par contre la j'ai un autre souci. quand je ferme mon application j'aimerais ecrire dans un fichier ma matrice de rotation mais sous forme d'un angle et d'un axe. en m'inspirant de la faq sur les quaternions, j'ai écrit des méthodes me permettant de transformer une matrice de rotation en un quaternion et ensuite mon quaternion en un angle et axe de rotation. Seulement en faisant des tests je n'obtiens pas du tout le bon résultat. étant donné que la matrice de rotation est correcte il me semble évident que l'erreur vient de mes fonctions de transformations. je ne penses pas mettre planté en implémentant les algos de la faq donc je trouve ça bizarre. Voila la fonction qui transforme la matrice de rotation en un quaternion:
    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
     
    Quaternion Matrice::MatriceToQuaternion()
    {
       float trace = _valeur[0] + _valeur[5] + _valeur[10];
       float temp, x, y, z, angle;
     
       if(trace > 0)
       {
          temp = 1 / (2 * sqrt(trace));
     
          x = (_valeur[9] - _valeur[6]) * temp;
          y = (_valeur[2] - _valeur[8]) * temp;
          z = (_valeur[4] - _valeur[1]) * temp;
     
          angle = 1 / (4 * temp);
       }
       else
       {
          if(_valeur[0] > _valeur[5] && _valeur[0] > _valeur[10])
          {
             temp = 2 * sqrt(1 + _valeur[0] - _valeur[5] - _valeur[10]);
     
             x = 1 / (2 * temp);
             y = (_valeur[1] - _valeur[4]) / temp;
             z = (_valeur[2] - _valeur[8]) / temp;
     
             angle = (_valeur[6] - _valeur[9]) / temp;
          }
          else if(_valeur[5] > _valeur[0] && _valeur[5] > _valeur[10])
          {
             temp = 2 * sqrt(1 - _valeur[0] + _valeur[5] - _valeur[10]);
     
             x = (_valeur[1] - _valeur[4]) / temp;
             y = 1 / (2 * temp);
             z = (_valeur[6] - _valeur[9]) / temp;
     
             angle = (_valeur[2] - _valeur[8]) / temp;
          }
          else
          {
             temp = 2 * sqrt(1 - _valeur[0] - _valeur[5] + _valeur[10]);
     
             x = (_valeur[2] - _valeur[8]) / temp;
             y = (_valeur[6] - _valeur[9]) / temp;
             z = 1 / (2 * temp);
     
             angle = (_valeur[1] - _valeur[4]) / temp;
          }
       }
     
       return Quaternion(x, y, z, angle);
    }

    pour info les valeurs de ma matrice sont stockées dans un tableau de floattants. _valeur[0] correspond à M[0,0], _valeur[1] correspond à M[0,1], etc...

    Voyez vous une erreur dans mon code???

Discussions similaires

  1. Orientation d'un cylindre
    Par Amroth dans le forum OpenGL
    Réponses: 5
    Dernier message: 16/07/2009, 12h32
  2. [SGBDOO] Base de données orientée objet
    Par Jaona dans le forum Décisions SGBD
    Réponses: 19
    Dernier message: 14/04/2003, 11h07
  3. [web] [Que choisir ?] langages orientés web.
    Par otakuMerlin dans le forum Web
    Réponses: 4
    Dernier message: 07/04/2003, 11h13
  4. [] Datareport.orientation introuvable même avec sp5
    Par khany dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 08/01/2003, 10h06
  5. [Crystal Report] Orientation paysage
    Par Axiome dans le forum SAP Crystal Reports
    Réponses: 2
    Dernier message: 22/10/2002, 10h23

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