Correction |
|
Mercredi 30 Mai 2001 - 1h30 | |
Exercice 1: OpenGL Question a) La spécification d'une normale est obligatoire car un éclairage est demandé à la question c). void facette(void) { glBegin(GL_QUADS); glNormal3f(0.0F,0.0F,1.0F); glVertex2f(0.0F,0.0F); glVertex2f(1.0F,0.0F); glVertex2f(1.0F,1.0F); glVertex2f(0.0F,1.0F); glEnd(); } Question b) void scene(int n) { glPushMatrix(); float dp =(float) -n/2; for ( int i = 0 ; i < n ; i++ ) for ( int j = 0 ; j < n ; j++ ) { glPushMatrix(); glTranslatef(dp+i,dp+j,0.0F); facette(); glPopMatrix(); } glPopMatrix(); } Question c) void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); GLfloat spot_diffuse[] = { 1.0F,0.0F,0.0F,1.0F }; GLfloat spot_specular[] = { 1.0F,0.0F,0.0F,1.0F }; GLfloat spot_position[] = { 0.0F,0.0F,100.0F,1.0F }; GLfloat spot_direction[] = { 0.0F,0.0F,-1.0F }; glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glPushMatrix(); glLightfv(GL_LIGHT0,GL_DIFFUSE,spot_diffuse); glLightfv(GL_LIGHT0,GL_SPECULAR,spot_specular); glLightfv(GL_LIGHT0,GL_POSITION,spot_position); glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,spot_direction); glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,5.0F); scene(45); glPopMatrix(); glFlush(); glutSwapBuffers(); } La rotation à réaliser peut être obtenue par la réalisation successive de 7 transformations géométriques:
On a donc la matrice de transformation M résultante: M = T-1.R1-1.R2-1.R.R2.R1.T Question a) struct coord3D { float x; float y; float z; } ; struct facette { int ns; coord3D *s; } ; Une structure coord3D pour stocker la position d'un sommet dans l'espace. On aurait aussi pu travailler en coordonnées homogènes et donc avoir une quatrième coordonnée utilisable. Une structure facette composée d'un entier représentant le nombre de sommets du polygone et d'un tableau pour stocker les positions de ces sommets. Autre solution: Utiliser une liste chaînée de sommets. Question b) Une méthode simple pour tester la planarité d'un polygone de plus de trois sommets (un polygone à trois ou moins de trois sommets est forcément plan) consiste à utiliser les trois premiers sommets pour calculer la normale à la facette triangulaire qu'ils forment, puis à tester au moyen d'un produit scalaire l'orthogonalité de cette normale avec chacun des cotés du polygone (moins les deux premiers qui sont forcément orthogonaux). Si (sitôt que) une valeur différente de 0 (-> non orthogonalité) est trouvée, on peut conclure à la non planarité. Une méthode plus complexe consiste à utiliser les trois premiers sommets du polygone pour calculer l'équation du plan incluant la facette triangulaire qu'ils forment (ax+by+cz+d = 0), puis ensuite vérifier que tous les autres sommets sont bien dans ce plan. Inconvénient de cette méthode: Trouver a,b,c et d nécessite la résolution d'un système d'équations. Question c) struct direc3D { float x; float y; float z; } ; /* -------------------------------------------------- */ /* Calcul du produit scalaire entre deux vecteurs */ /* -------------------------------------------------- */ float produitScalaire(direc3D *v1,direc3D *v2) { return(v1->x*v2->x+v1->y*v2->y+v1->z*v2->z); } /* -------------------------------------------------- */ /* Calcul du produit vectoriel entre deux vecteurs */ /* -------------------------------------------------- */ void produitVectoriel(direc3D *v1,direc3D *v2,direc3D *v) { v->x = v1->y*v2->z-v2->y*v1->z; v->y = v1->z*v2->x-v2->z*v1->x; v->z = v1->x*v2->y-v2->x*v1->y; } /* -------------------------------------------------- */ /* Calcul du vecteur entre deux sommets */ /* -------------------------------------------------- */ void vecteur(coord3D *p1,coord3D *p2,direc3D *v) { v->x = p2->x - p1->x; v->y = p2->y - p1->y; v->z = p2->z - p1->z; } /* -------------------------------------------------- */ /* Test d'egalite a 0 a epsilon pres */ /* -------------------------------------------------- */ int egalZero(float v) { return(fabs(v) < 0.00001); } /* -------------------------------------------------- */ /* Fonction de test de planarite d'une facette */ /* -------------------------------------------------- */ int testPlanarite(facette *f) { if ( f->ns <= 3 ) return(1); direc3D v1; direc3D v2; direc3D n; vecteur(&f->s[1],&f->s[2],&v1); vecteur(&f->s[2],&f->s[3],&v2); produitVectoriel(&v1,&v2,&n); for ( int i = 2 ; i < f->ns-1 ; i++ ) { direc3D v; vecteur(&f->s[i],&f->s[i+1],&v); float scal = produitScalaire(&n,&v); if ( !egalZero(scal) ) return(0); } return(1); } |
|
Remarques, erreurs |