Transformations géométriques
Par Xavier Michelon


 
 
Le programme exemple :

L'exemple que je vous propose illustre le principe de composition de transformations. Intéressons-nous tout d'abord à la fonction d'affichage. L'objectif est de dessiner un carré 2D centré en l'origine, auquel on a appliqué une rotation d'angle a autour de l'axe Z, suivie d'une translation de vecteur (0.5,0.0,0.0) et d'une rotation d'angle b autour de Z. En appliquant la procédure que je viens d'énoncer dans plus haut, voici ce que nous devons mettre dans la fonction d'affichage :

glLoadIdentity();
glRotatef(b,0.0,0.0,1.0);
glTranslatef(0.5,0.0,0.0);
glRotatef(a,0.0,0.0,1.0);


glBegin(GL_POLYGON);
glVertex3f(-0.2,-0.2, 0.0);
glVertex3f( 0.2,-0.2, 0.0);
glVertex3f( 0.2, 0.2, 0.0);
glVertex3f(-0.2, 0.2, 0.0);
glEnd();

Pour animer notre cube, nous allons utiliser une nouvelle fonction de rappel : la fonction d'oisiveté (idle en anglais). Cette fonction est appelée chaque fois que le gestionnaire d'évènement n'a aucun autre évènement à traiter.

void idle()
{ 
  a+=inca;
  if (a>360)
    a-=360; 
  b+=incb; 
    if (b>360) 
  b-=360;
  glutPostRedisplay();
}


Dans la fonction idle, les valeurs des angles de rotation a et b sont incrémentées, puis une demande de rafraîchissement est faite. Le cube est alors redessiné à l'écran avec prise en compte des nouvelles valeurs des angles de rotation. En tenant compte du fait qu'une rotation de 360 degrés nous ramène au point de départ, on prend soin d'éviter les dépassements de capacité en ôtant 360 degrés aux angles dès qu'ils dépassent cette valeur.

Afin de vous permettre de visualiser l'effet de chacune des rotations, le programme vous donne la possibilité de modifier les incréments appliqués aux angles a et b à chaque pas d'animation. La touche 'a' augmente l'incrément de la rotation d'angle a. 'Shift+a' le diminue. De la même manière, les combinaisons de touches 'b' et 'Shift+b' modifient l'incrément de la rotation d'angle b.

Précision sur les rotations

Vous avez peut-être remarqué que glRotate() ne permet de générer que des rotations dont l'axe passe par l'origine. Comment faire si on souhaite obtenir une rotation dont l'axe passe par un point P de coordonnées (Px,Py,Pz) ? C'est très simple : il suffit de ramener le point P à l'origine par une translation de vecteur (-Px,-Py,-Pz), d'appliquer la rotation, puis de ramener l'objet à sa position initiale avec une translation de vecteur (Px,Py,Pz), ce qui donne en OpenGL :

glTranslatef(Px,Py,Pz); 
glRotatef(a,Ax,Ay,Az);
glTranslatef(-Px,-Py,-Pz);