/* Auteur: Nicolas JANEY */ /* nicolas.janey@univ-fcomte.fr */ /* Avril 2001 */ /* Calculs mathematiques */ /* sur les transformations geometriques */ #include #include #include #include #include #include #include #include "ModuleCouleurs.h" #include "ModuleManipulateur.h" #include "ModuleMenus.h" #include "ModuleReshape.h" #include "ModuleFont.h" typedef float vecteur[4] ; typedef float matrice[4][4] ; #ifndef M_PI #define M_PI 3.14159265F #endif static int question = 0; float view_rotx = 0.0F; float view_roty = 0.0F; static GLfloat zoom = 3.0F; static float px = 0.0F; static float py = 0.0F; static float pz = 0.0F; static float ax = 0.0F; static float ay = 0.0F; static float vrx = 0.0F; static float vry = 0.0F; void initIdentite(matrice m) { for ( int i = 0 ; i < 4 ; i++ ) for ( int j = 0 ; j < 4 ; j++ ) m[i][j] =( i != j ) ? 0.0F : 1.0F; } void initTranslation(matrice m,float dx,float dy,float dz) { initIdentite(m); m[0][3] = dx; m[1][3] = dy; m[2][3] = dz; } void initRotationX(matrice m,float a) { initIdentite(m); float cs =(float) cos(a*M_PI/180); float sn =(float) sin(a*M_PI/180); m[1][1] = m[2][2] = cs; m[1][2] = -sn; m[2][1] = sn; } void initRotationY(matrice m,float a) { initIdentite(m); float cs =(float) cos(a*M_PI/180); float sn =(float) sin(a*M_PI/180); m[0][0] = m[2][2] = cs; m[0][2] = sn; m[2][0] = -sn; } void initRotationZ(matrice m,float a) { initIdentite(m); float cs =(float) cos(a*M_PI/180); float sn =(float) sin(a*M_PI/180); m[0][0] = m[1][1] = cs; m[0][1] = -sn; m[1][0] = sn; } void initScale(matrice m,float rx,float ry,float rz) { initIdentite(m); m[0][0] = rx; m[1][1] = ry; m[2][2] = rz; } void composition(matrice a,matrice b,matrice m) { for ( int i = 0 ; i < 4 ; i++ ) for ( int j = 0 ; j < 4 ; j++ ) { m[i][j] = 0.0F ; for ( int k = 0 ; k < 4 ; k++ ) m[i][j] += a[i][k]*b[k][j] ; } } void produit(matrice a,vecteur b,vecteur v) { for ( int i = 0 ; i < 4 ; i++ ) { v[i] = 0.0F ; for ( int j = 0 ; j < 4 ; j++ ) v[i] += a[i][j]*b[j] ; } } void printf(matrice m) { for ( int i = 0 ; i < 4 ; i++ ) { for ( int j = 0 ; j < 4 ; j++ ) printf("%7.3f",m[i][j]); printf("\n"); } printf("\n"); } void solidCube(float px,float py,float pz,matrice m,float rx,float ry,float rz) { matrice s; initScale(s,rx,ry,rz); matrice tr; initTranslation(tr,px,py,pz); matrice aux; composition(m,tr,aux); matrice trans; composition(aux,s,trans); GLfloat vdata[8][3] = { { 0.5, 0.5,-0.5},{ 0.5,-0.5,-0.5}, {-0.5,-0.5,-0.5},{-0.5, 0.5,-0.5}, { 0.5, 0.5, 0.5},{ 0.5,-0.5, 0.5}, {-0.5,-0.5, 0.5},{-0.5, 0.5, 0.5}} ; int i; for ( i = 0 ; i < 8 ; i++ ) { vecteur v = { vdata[i][0],vdata[i][1],vdata[i][2],1.0F }; vecteur nv; produit(trans,v,nv); vdata[i][0] = nv[0]; vdata[i][1] = nv[1]; vdata[i][2] = nv[2]; } static GLint t[6][4] = { {0,1,2,3}, {7,6,5,4}, {5,6,2,1}, {0,3,7,4}, {6,7,3,2}, {4,5,1,0}} ; GLfloat ndata[6][3] = { { 0.0, 0.0,-1.0}, { 0.0, 0.0, 1.0}, { 0.0,-1.0, 0.0}, { 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0}, { 1.0, 0.0, 0.0}} ; for ( i = 0 ; i < 6 ; i++ ) { vecteur v = { ndata[i][0],ndata[i][1],ndata[i][2],0.0F }; vecteur nv; produit(trans,v,nv); ndata[i][0] = nv[0]; ndata[i][1] = nv[1]; ndata[i][2] = nv[2]; } for ( i = 0 ; i < 6 ; i++ ) { glBegin(GL_QUADS) ; glNormal3fv(&ndata[i][0]); glVertex3fv(vdata[t[i][0]]); glVertex3fv(vdata[t[i][1]]); glVertex3fv(vdata[t[i][2]]); glVertex3fv(vdata[t[i][3]]); glEnd() ; } } void solidCube(float px,float py,float pz,float rx,float ry,float rz) { GLfloat vdata[8][3] = { { 0.5, 0.5,-0.5},{ 0.5,-0.5,-0.5}, {-0.5,-0.5,-0.5},{-0.5, 0.5,-0.5}, { 0.5, 0.5, 0.5},{ 0.5,-0.5, 0.5}, {-0.5,-0.5, 0.5},{-0.5, 0.5, 0.5}} ; int i; for ( i = 0 ; i < 8 ; i++ ) { vdata[i][0] *= rx; vdata[i][0] += px; vdata[i][1] *= ry; vdata[i][1] += py; vdata[i][2] *= rz; vdata[i][2] += pz; } static GLint t[6][4] = { {0,1,2,3}, {7,6,5,4}, {5,6,2,1}, {0,3,7,4}, {6,7,3,2}, {4,5,1,0}} ; static GLfloat ndata[6][3] = { { 0.0, 0.0,-1.0}, { 0.0, 0.0, 1.0}, { 0.0,-1.0, 0.0}, { 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0}, { 1.0, 0.0, 0.0}} ; for ( i = 0 ; i < 6 ; i++ ) { glBegin(GL_QUADS) ; glNormal3fv(&ndata[i][0]); glVertex3fv(vdata[t[i][0]]); glVertex3fv(vdata[t[i][1]]); glVertex3fv(vdata[t[i][2]]); glVertex3fv(vdata[t[i][3]]); glEnd() ; } } void question1() { glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glPushMatrix(); manipulateurSouris(); manipulateurClavier(); glRotatef(view_rotx,1.0F,0.0F,0.0F); glRotatef(view_roty,0.0F,1.0F,0.0F); glScalef(zoom,zoom,zoom); matrice rx,ry,rxy,ryx; initRotationX(rx,ax); initRotationY(ry,ay); composition(rx,ry,rxy); composition(ry,rx,ryx); glPushMatrix(); solidCube(px,py,pz,0.5F,0.4F,0.3F); glPopMatrix(); glPushMatrix(); solidCube(px,py,pz,rxy,0.5F,0.4F,0.3F); glPopMatrix(); glPushMatrix(); solidCube(px,py,pz,ryx,0.5F,0.4F,0.3F); glPopMatrix(); glPopMatrix(); glDisable(GL_DEPTH_TEST); glDisable(GL_LIGHTING); float xmin = getXmin(); float ymax = getYmax(); float tpix = getTaillePixel(); setAntialiased(1); setBold(1); setEcartementCaracteres(15.0F); glPushMatrix(); glColor4fv(couleurBlanc()); strokeOutput(xmin,ymax-16*tpix,0.65F,"Cube initial : %f %f %f",px,py,pz); matrice tr; initTranslation(tr,px,py,pz); matrice trans; composition(rxy,tr,trans); strokeOutput(xmin,ymax-36*tpix,0.65F,"Rx : %f, Ry : %f",ax,ay); { vecteur v = {0.0F,0.0F,0.0F,1.0F}; vecteur vt; produit(trans,v,vt); strokeOutput(xmin,ymax-56*tpix,0.65F,"Cube par Ry puis Rx : %f %f %f",vt[0],vt[1],vt[2]); } composition(ryx,tr,trans); { vecteur v = {0.0F,0.0F,0.0F,1.0F}; vecteur vt; produit(trans,v,vt); strokeOutput(xmin,ymax-76*tpix,0.65F,"Cube par Rx puis Ry : %f %f %f",vt[0],vt[1],vt[2]); } glPopMatrix(); setAntialiased(0); setBold(0); setEcartementCaracteres(0.0F); } void fleche(float dx,float dy,float dz,float cr,float cl) { glPushMatrix(); glBegin(GL_LINES); glVertex3f(0.0F,0.0F,0.0F); glVertex3f(dx,dy,dz); glEnd(); glPopMatrix(); glPushMatrix(); double d = pow((double) (dx*dx+dy*dy+dz*dz),0.5); dx /= d; dy /= d; dz /= d; double a = acos(dz) * 360 / 3.14159; glRotatef(a/2,-dy,dx,0); glTranslatef(0.0F,0.0F,(float) d); glutSolidCone(cr,cl,10,10); glPopMatrix(); } void question2() { matrice rx,ry,rxy,ryx; initRotationX(rx,vrx); initRotationY(ry,vry); composition(rx,ry,rxy); composition(ry,rx,ryx); glEnable(GL_DEPTH_TEST); glPushMatrix(); glScalef(zoom,zoom,zoom); glPushMatrix(); glColor4fv(couleurJaune()); glTranslatef(0.0F,-0.5F,0.0F); fleche(0.0F,1.0F,0.0F,0.05F,0.2F); glPopMatrix(); glColor4fv(couleurRouge()); glPushMatrix(); vecteur v1 = {0.0F,1.0F,0.0F,0.0F}; vecteur vt1; produit(rxy,v1,vt1); glTranslatef(-1.0F,-0.5F,0.0F); fleche(vt1[0],vt1[1],vt1[2],0.05F,0.2F); glPopMatrix(); glColor4fv(couleurBleu()); glPushMatrix(); vecteur v2 = {0.0F,1.0F,0.0F,0.0F}; vecteur vt2; produit(ryx,v2,vt2); glTranslatef(1.0F,-0.5F,0.0F); fleche(vt2[0],vt2[1],vt2[2],0.05F,0.2F); glPopMatrix(); glPopMatrix(); glDisable(GL_DEPTH_TEST); float xmin = getXmin(); float ymax = getYmax(); float tpix = getTaillePixel(); setAntialiased(1); setBold(1); setEcartementCaracteres(15.0F); glPushMatrix(); glColor4fv(couleurBlanc()); strokeOutput(xmin,ymax-16*tpix,0.65F,"Rx : %f, Ry : %f",vrx,vry); glColor4fv(couleurJaune()); strokeOutput(xmin,ymax-36*tpix,0.65F,"Vecteur original : 0.0000 1.0000 0.0000"); glColor4fv(couleurRouge()); strokeOutput(xmin,ymax-56*tpix,0.65F,"Ry puis Rx : %f %f %f",vt1[0],vt1[1],vt1[2]); glColor4fv(couleurBleu()); strokeOutput(xmin,ymax-76*tpix,0.65F,"Rx puis Ry : %f %f %f",vt2[0],vt2[1],vt2[2]); glPopMatrix(); setAntialiased(0); setBold(0); setEcartementCaracteres(0.0F); } void display() { glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT); glPushMatrix(); switch ( question ) { case 0 : question1(); break; case 1 : question2(); break; } glPopMatrix(); glutSwapBuffers(); glFlush(); } void key(unsigned char key,int x,int y) { switch ( key ) { case '1' : if ( question == 1 ) vrx -= 1.0F; else ax -= 1.0F; break; case '7' : if ( question == 1 ) vrx += 1.0F; else ax += 1.0F; break; case '2' : if ( question == 1 ) vry -= 1.0F; else ay -= 1.0F; break; case '8' : if ( question == 1 ) vry += 1.0F; else ay += 1.0F; break; case 'x' : px -= 0.05F; break; case 'X' : px += 0.05F; break; case 'y' : py -= 0.05F; break; case 'Y' : py += 0.05F; break; case 'z' : pz -= 0.05F; break; case 'Z' : pz += 0.05F; break; case 45 : zoom /= 1.02F; break; case 43 : zoom *= 1.02F; break; case 0x0D : question = (question+1)%2; break; case '\033' : exit(0); break ; } glutPostRedisplay(); } static void special(int k,int x,int y) { switch (k) { case GLUT_KEY_UP : if ( question == 1 ) vrx += 1.0F; else view_rotx += 2.0; break; case GLUT_KEY_DOWN : if ( question == 1 ) vrx -= 1.0F; else view_rotx -= 2.0; break; case GLUT_KEY_LEFT : if ( question == 1 ) vry += 1.0F; else view_roty += 2.0; break; case GLUT_KEY_RIGHT : if ( question == 1 ) vry -= 1.0F; else view_roty -= 2.0; break; } glutPostRedisplay(); } void myInit(void) { GLfloat mat_shininess[] = { 50.0 }; GLfloat light0_position[] = { 1.0,1.0,1.0,0.0 }; GLfloat light1_position[] = { -1.0,1.0,1.0,0.0 }; GLfloat light2_position[] = { 1.0,-1.0,1.0,0.0 }; glMaterialfv(GL_FRONT,GL_SPECULAR,couleurBlanc()); glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess); glLightfv(GL_LIGHT0,GL_DIFFUSE,couleurRouge()); glLightfv(GL_LIGHT1,GL_DIFFUSE,couleurVert()); glLightfv(GL_LIGHT2,GL_DIFFUSE,couleurBleu()); glLightfv(GL_LIGHT0,GL_POSITION,light0_position); glLightfv(GL_LIGHT1,GL_POSITION,light1_position); glLightfv(GL_LIGHT2,GL_POSITION,light2_position); glEnable(GL_LIGHT0); glEnable(GL_LIGHT1); glEnable(GL_LIGHT2); glDepthFunc(GL_LESS); glEnable(GL_NORMALIZE); glEnable(GL_AUTO_NORMAL); glShadeModel(GL_SMOOTH); } int main(int argc,char **argv) { glutInit(&argc,argv); glutInitWindowSize(400,400); glutInitWindowPosition(50,50); glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE); glutCreateWindow("Mathematiques 2"); myInit(); creationMenuBasique(); setParametresOrthoBasique(-6.0,6.0,-6.0,6.0,-500.0,500.0); setManipulateurDistance(1.0F); glutReshapeFunc(reshapeOrthoBasique); glutMotionFunc(motionBasique); glutMouseFunc(sourisBasique); glutKeyboardFunc(key); glutSpecialFunc(special); glutDisplayFunc(display); glutMainLoop(); return(0); }