/* Auteur: Nicolas JANEY */ /* nicolas.janey@univ-fcomte.fr */ /* Juin 2001 */ /* Examen de TD 2000-2001 : Question 2 */ /* Rotation de 60° autour de l'axe */ /* (2,1,3) - (4,2,-1) */ #include #include #include #include #include #include "ModuleReshape.h" #include "ModuleManipulateur.h" #include "ModuleMenus.h" #include "ModuleFont.h" typedef float vecteur[4]; typedef float matrice[4][4]; static float blanc[] = { 1.0F,1.0F,1.0F,1.0F }; static float jaune[] = { 1.0F,1.0F,0.0F,1.0F }; static float rouge[] = { 1.0F,0.0F,0.0F,1.0F }; static float vert[] = { 0.0F,1.0F,0.0F,1.0F }; static float bleu[] = { 0.0F,0.0F,1.0F,1.0F }; static float gris[] = { 0.5F,0.5F,0.5F,1.0F }; static int aff = 0; static int anim = 0; static float angle = 0; static float dist = 0.5F; static float p = 0.0F; static int image = 0; static vecteur p1 = { 2.0F,1.0F,3.0F,1.0F}; static vecteur p2 = { 4.0F,2.0F,-1.0F,1.0F}; static vecteur pO = { 0.0F,0.0F,0.0F,1.0F}; static vecteur px = { 1.0F,0.0F,0.0F,1.0F}; static vecteur py = { 0.0F,1.0F,0.0F,1.0F}; static vecteur pz = { 0.0F,0.0F,1.0F,1.0F}; static float l; static vecteur np1; static vecteur np2; static vecteur nnp1; static vecteur nnp2; static vecteur nnnp1; static vecteur nnnp2; static matrice m; static matrice mp; /* ************************************************** */ /* -------------------------------------------------- */ /* Initialisation a l'identite */ /* -------------------------------------------------- */ void toIdentite(matrice a) { for ( int i = 0 ; i < 4 ; i++ ) for ( int j = 0 ; j < 4 ; j++ ) a[i][j] = ( i == j) ? 1.0F : 0.0F; } /* -------------------------------------------------- */ /* Initialisation a la translation (dx,dy,dz) */ /* -------------------------------------------------- */ void toTranslation(matrice a,float dx,float dy,float dz) { toIdentite(a); a[0][3] = dx; a[1][3] = dy; a[2][3] = dz; } /* -------------------------------------------------- */ /* Initialisation a la rotation d'angle a */ /* autour de Ox */ /* -------------------------------------------------- */ void toRotationX(matrice m,float a) { toIdentite(m); m[2][1] = sin(a); m[1][2] = -m[2][1]; m[1][1] = m[2][2] = cos(a); } /* -------------------------------------------------- */ /* Initialisation a la rotation d'angle a */ /* autour de Oy */ /* -------------------------------------------------- */ void toRotationY(matrice m,float a) { toIdentite(m); m[0][2] = sin(a); m[2][0] = -m[0][2]; m[0][0] = m[2][2] = cos(a); } /* -------------------------------------------------- */ /* Initialisation a la rotation d'angle a */ /* autour de Oz */ /* -------------------------------------------------- */ void toRotationZ(matrice m,float a) { toIdentite(m); m[1][0] = sin(a); m[0][1] = -m[1][0]; m[1][1] = m[0][0] = cos(a); } /* -------------------------------------------------- */ /* Produit matrice matrice */ /* -------------------------------------------------- */ void produitMatriceMatrice(matrice a,matrice b,matrice r) { matrice rr; int i,j; for ( i = 0 ; i < 4 ; i++ ) for ( j = 0 ; j < 4 ; j++ ) { rr[i][j] = 0.0F; for ( int k = 0 ; k < 4 ; k++ ) { rr[i][j] += a[i][k]*b[k][j]; } } for ( i = 0 ; i < 4 ; i++ ) for ( j = 0 ; j < 4 ; j++ ) r[i][j] = rr[i][j]; } /* -------------------------------------------------- */ /* Produit matrice vecteur */ /* -------------------------------------------------- */ void produitMatriceVecteur(matrice m,vecteur v,vecteur r) { vecteur rr; int i; for ( i = 0 ; i < 4 ; i++ ) { rr[i] = 0.0F; for ( int j = 0 ; j < 4 ; j++ ) { rr[i] += m[i][j]*v[j]; } } for ( i = 0 ; i < 4 ; i++ ) { r[i] = rr[i]; } } /* -------------------------------------------------- */ /* La fonction myinit initialise les fonctionnalites */ /* suivantes : */ /* - calcul des matrices de transformation */ /* - une gestion des parties cachees */ /* - normalisation des normales specifiees */ /* -------------------------------------------------- */ void myinit(void) { matrice t; matrice r1; matrice r2; matrice rz; matrice mr2; matrice mr1; matrice mt; toRotationZ(rz,-1.0471975511965977461542144610932F); toTranslation(t,-4.0F,-2.0F,1.0F); toTranslation(mt,4.0F,2.0F,-1.0F); produitMatriceVecteur(t,p1,np1); produitMatriceVecteur(t,p2,np2); toRotationY(r1,0.4636476F); toRotationY(mr1,-0.4636476F); produitMatriceVecteur(r1,np1,nnp1); produitMatriceVecteur(r1,np2,nnp2); toRotationX(r2,-0.22F); toRotationX(mr2,0.22F); produitMatriceVecteur(r2,nnp1,nnnp1); produitMatriceVecteur(r2,nnp2,nnnp2); produitMatriceMatrice(r1,t,m); produitMatriceMatrice(r2,m,m); produitMatriceMatrice(rz,m,m); produitMatriceMatrice(mr2,m,m); produitMatriceMatrice(mr1,m,m); produitMatriceMatrice(mt,m,m); produitMatriceMatrice(mr1,mr2,mp); produitMatriceMatrice(mt,mp,mp); l = nnnp1[2]; glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); glEnable(GL_NORMALIZE) ; glEnable(GL_LIGHT0); } /* -------------------------------------------------- */ /* Dessin d'un sommet modelise par une petite sphere */ /* -------------------------------------------------- */ void dessineSommet(vecteur p) { glPushMatrix(); glTranslatef(p[0],p[1],p[2]); glutSolidSphere(0.1,10,10); glPopMatrix(); } /* -------------------------------------------------- */ /* Dessin d'un axe */ /* -------------------------------------------------- */ void axeDeRotation(vecteur p1,vecteur p2,float fact) { float dx = p1[0]-p2[0]; float dy = p1[1]-p2[1]; float dz = p1[2]-p2[2]; glBegin(GL_LINES); glVertex3f(p1[0]-fact*dx,p1[1]-fact*dy,p1[2]-fact*dz); glVertex3f(p1[0]+fact*dx,p1[1]+fact*dy,p1[2]+fact*dz); glEnd(); } /* -------------------------------------------------- */ /* Dessin des axes du repere */ /* -------------------------------------------------- */ void axes() { glColor4fv(gris) ; axeDeRotation(pO,px,100); axeDeRotation(pO,py,100); axeDeRotation(pO,pz,100); glDisable(GL_DEPTH_TEST); glColor4fv(rouge) ; glBegin(GL_LINES) ; glVertex3f(0.0F,0.0F,0.0F) ; glVertex3f(1.0F,0.0F,0.0F) ; glEnd() ; glRasterPos3f(1.05F,0.05F,0.05F); bitmapOutput("%s","x"); glColor4fv(vert) ; glBegin(GL_LINES) ; glVertex3f(0.0F,0.0F,0.0F) ; glVertex3f(0.0F,1.0F,0.0F) ; glEnd() ; glRasterPos3f(0.05F,1.05F,0.05F); bitmapOutput("%s","y"); glColor4fv(bleu) ; glBegin(GL_LINES) ; glVertex3f(0.0F,0.0F,0.0F) ; glVertex3f(0.0F,0.0F,1.0F) ; glEnd() ; glRasterPos3f(0.05F,0.05F,1.05F); bitmapOutput("%s","z"); glEnable(GL_DEPTH_TEST); } /* -------------------------------------------------- */ /* Fonction display avec differents */ /* niveaux d'affichage */ /* -------------------------------------------------- */ void display(void) { glClearColor(0.3F,0.3F,0.3F,0.0F); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); manipulateurSouris(); manipulateurClavier(); glEnable(GL_LIGHTING); glMaterialfv(GL_FRONT,GL_DIFFUSE,blanc) ; dessineSommet(p1); dessineSommet(p2); glDisable(GL_LIGHTING); glColor4fv(blanc) ; axeDeRotation(p1,p2,100); axes(); switch ( aff ) { case 1 : glEnable(GL_LIGHTING); glMaterialfv(GL_FRONT,GL_DIFFUSE,jaune) ; dessineSommet(np1); dessineSommet(np2); glDisable(GL_LIGHTING); glColor4fv(jaune) ; axeDeRotation(np1,np2,100); break; case 2 : glEnable(GL_LIGHTING); glMaterialfv(GL_FRONT,GL_DIFFUSE,jaune) ; dessineSommet(nnp1); dessineSommet(nnp2); glDisable(GL_LIGHTING); glColor4fv(jaune) ; axeDeRotation(nnp1,nnp2,100); break; case 3 : glEnable(GL_LIGHTING); glMaterialfv(GL_FRONT,GL_DIFFUSE,jaune) ; dessineSommet(nnnp1); dessineSommet(nnnp2); glDisable(GL_LIGHTING); glColor4fv(jaune) ; glDisable(GL_DEPTH_TEST); axeDeRotation(nnnp1,nnnp2,100); glEnable(GL_DEPTH_TEST); break; case 4 : glEnable(GL_LIGHTING); vecteur a; float angle = 3.14159*image/360.0F; a[0] = 0.5F + 2.5F * ((float) (image%1001)/1000)*cos(angle); a[1] = 0.5F + 1.0F * ((float) (image%1001)/1000)*sin(angle);; a[2] = l*((float) (image%501)/500); a[3] = 1.0F; produitMatriceVecteur(mp,a,a); glMaterialfv(GL_FRONT,GL_DIFFUSE,rouge) ; dessineSommet(a); vecteur b; produitMatriceVecteur(m,a,b); glMaterialfv(GL_FRONT,GL_DIFFUSE,bleu) ; dessineSommet(b); glDisable(GL_LIGHTING); glColor4fv(jaune) ; break; } glPopMatrix(); glFlush(); glutSwapBuffers(); } /* -------------------------------------------------- */ void idle(void) { image++; display(); } /* -------------------------------------------------- */ void key(unsigned char key,int x,int y) { if ( keyManipulateur(key,x,y) ) glutPostRedisplay(); else switch ( key ) { case 0x0D : anim = 1-anim; if ( anim ) glutIdleFunc(idle); else glutIdleFunc(NULL); break; case 32 : aff = (aff+1)%5 ; glutPostRedisplay(); break; } } /* -------------------------------------------------- */ void main(void) { glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH); glutInitWindowPosition(10,10); glutInitWindowSize(300,300); glutCreateWindow("Exercice 1 : Rotation autour d'un axe"); myinit(); creationMenuBasique(); setParametresOrthoBasique(-5.0,5.0,-5.0,5.0,-500.0,500.0); setManipulateurDistance(1.0F); setManipulateurClavierAngle(30.0F,-70.0F,0.0F) ; glutReshapeFunc(reshapeOrthoBasique); glutKeyboardFunc(key); glutSpecialFunc(specialBasique); glutMotionFunc(motionBasique); glutMouseFunc(sourisBasique); glutDisplayFunc(display); glutMainLoop(); } /* ************************************************** */