/* Mathematiques de l'Infographie */ /* Test des classes TG3D, Tr3D, Rt3D et Sc3D */ /* */ /* Auteur: Nicolas JANEY */ /* nicolas.janey@univ-fcomte.fr */ /* Mars 2020 */ #if defined(WIN32) || defined(WIN64) #define _CRTDBG_MAP_ALLOC #if defined(_DEBUG) #define _AFXDLL #include #endif #endif #include #if defined(WIN32) || defined(WIN64) #include #endif #include #include #include #include #include #include "Pos3D.h" #include "Dir3D.h" #include "Tr3D.h" #include "Rt3D.h" #include "Sc3D.h" #include "TG3D.h" ////////////////////////////////////////////////// static Dir3D tr; static float angle = 0.0F; static Dir3D axeR(1.0F,0.0F,0.0F); static float scx = 1.0F; static float scy = 1.0F; static float scz = 1.0F; /* Modelisation en fil de fer d'un cube */ /* transforme par la TG3D tg */ static void modeliseCubeEnFilDeFer(TG3D *tg) { Pos3D pCube[8] = { Pos3D( 0.5F, 0.5F, 0.5F), Pos3D(-0.5F, 0.5F, 0.5F), Pos3D( 0.5F,-0.5F, 0.5F), Pos3D( 0.5F, 0.5F,-0.5F), Pos3D( 0.5F,-0.5F,-0.5F), Pos3D(-0.5F, 0.5F,-0.5F), Pos3D(-0.5F,-0.5F, 0.5F), Pos3D(-0.5F,-0.5F,-0.5F) }; int iCube [12][2] = { { 0,1 }, { 0,2 }, { 0,3 }, { 1,6 }, { 1,5 }, { 2,4 }, { 2,6 }, { 3,4 }, { 3,5 }, { 7,6 }, { 7,5 }, { 7,4 } } ; glBegin(GL_LINES); for ( int i = 0 ; i < 12 ; i++ ) { Pos3D p0(pCube[iCube[i][0]]); Pos3D p1(pCube[iCube[i][1]]); p0.transformation(tg); p1.transformation(tg); glVertex3f(p0.x,p0.y,p0.z); glVertex3f(p1.x,p1.y,p1.z); } glEnd(); } /* Calcul et retour de la TG3D obtenue */ /* par composition */ /* de la translation de direction tr, */ /* de la rotation de angle degres */ /* autour de l'axe de direction axe */ /* passant par l'origine, */ /* et du zoom de rapports rx, ry et rz */ static TG3D *transformationModelisation(Dir3D *tr, float angle,Dir3D *axe, float rx,float ry,float rz) { Tr3D translation(tr); Rt3D rotation(angle,axe); Sc3D scale(rx,ry,rz); TG3D tg(&translation,&rotation); return(new TG3D(&tg,&scale)); } /* Fonction executee lors d'un rafraichissement */ /* de la fenetre de dessin */ static void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); TG3D *trz = transformationModelisation(&tr,angle,&axeR,scx,scy,scz); modeliseCubeEnFilDeFer(trz); delete(trz); glPopMatrix(); glutSwapBuffers(); int error = glGetError(); if ( error != GL_NO_ERROR ) printf("Erreur OpenGL: %d\n",error); } ////////////////////////////////////////////////// /* Fonction d'initialisation des parametres */ /* OpenGL ne changeant pas au cours de la vie */ /* du programme */ void initialisationsOpenGL(void) { glClearColor(1.0F,1.0F,1.0F,1.0F); glColor3f(0.0F,0.0F,0.0F); } /* Fonction executee lors de la frappe */ /* d'une touche du special clavier */ static void special(int code,int x,int y) { switch ( code ) { case GLUT_KEY_RIGHT : switch ( glutGetModifiers() ) { case GLUT_ACTIVE_ALT : scx += 0.01F; break; case GLUT_ACTIVE_SHIFT : tr.x += 0.01F; break; case GLUT_ACTIVE_CTRL : axeR.x += 0.01F; break; default : angle += 1.0F; } glutPostRedisplay(); break; case GLUT_KEY_LEFT : switch ( glutGetModifiers() ) { case GLUT_ACTIVE_ALT : scx -= 0.01F; if ( scx <= 0.0F ) scx = 0.01F; break; case GLUT_ACTIVE_SHIFT : tr.x -= 0.01F; break; case GLUT_ACTIVE_CTRL : axeR.x -= 0.01F; break; default : angle -= 1.0F; } glutPostRedisplay(); break; case GLUT_KEY_UP : switch ( glutGetModifiers() ) { case GLUT_ACTIVE_ALT : scy += 0.01F; break; case GLUT_ACTIVE_SHIFT : tr.y += 0.01F; break; case GLUT_ACTIVE_CTRL : axeR.y += 0.01F; break; default : angle += 1.0F; } glutPostRedisplay(); break; case GLUT_KEY_DOWN : switch ( glutGetModifiers() ) { case GLUT_ACTIVE_ALT : scy -= 0.01F; if ( scy <= 0.0F ) scy = 0.01F; break; case GLUT_ACTIVE_SHIFT : tr.y -= 0.01F; break; case GLUT_ACTIVE_CTRL : axeR.y -= 0.01F; break; default : angle -= 1.0F; } glutPostRedisplay(); break; case GLUT_KEY_PAGE_UP : switch ( glutGetModifiers() ) { case GLUT_ACTIVE_ALT : scz += 0.01F; break; case GLUT_ACTIVE_SHIFT : tr.z += 0.01F; break; case GLUT_ACTIVE_CTRL : axeR.z += 0.01F; break; default : angle += 1.0F; } glutPostRedisplay(); break; case GLUT_KEY_PAGE_DOWN : switch ( glutGetModifiers() ) { case GLUT_ACTIVE_ALT : scz -= 0.01F; if ( scz <= 0.0F ) scz = 0.01F; break; case GLUT_ACTIVE_SHIFT : tr.z -= 0.01F; break; case GLUT_ACTIVE_CTRL : axeR.z -= 0.01F; break; default : angle -= 1.0F; } glutPostRedisplay(); break; } } /* Fonction executee lors de la frappe */ /* d'une touche du clavier */ static void keyboard(unsigned char key,int x,int y) { switch ( key ) { case 0x1B : exit(0); break; } } /* Fonction executee lors d'un changement */ /* de la taille de la fenetre OpenGL */ void reshape(int wx,int wy) { glViewport(0,0,wx,wy); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-wx/200.0,wx/200.0,-wy/200.0,wy/200.0,-1000.0,1000.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } static void clean() { } /* Fonction principale */ int main(int argc,char **argv) { #if defined(WIN32) || defined(WIN64) #if defined(_DEBUG) _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); //_crtBreakAlloc = 119; #endif #endif atexit(clean); glutInit(&argc,argv); glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE); glutInitWindowSize(450,300); glutInitWindowPosition(50,50); glutCreateWindow("Transformations géométriques sur un cube en fil de fer"); initialisationsOpenGL(); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutSpecialFunc(special); glutDisplayFunc(display); glutInitWindowPosition(250,100); glutMainLoop(); return(0); }