/* Calcul des directions de reflexion */ /* et de transmission a l'interface */ /* entre deux milieux */ /* */ /* Auteur: Nicolas JANEY */ /* nicolas.janey@univ-fcomte.fr */ /* Novembre 2012 */ #include #include #include #include #include #include "Position3D.h" #include "Direction3D.h" #include "Rotation3D.h" #include "ModuleFleche.h" /* Variables et constantes globales */ #ifndef M_PI #define M_PI 3.1415926535897932384626433832795 #endif static const float blanc[] = { 1.0F,1.0F,1.0F,1.0F }; static const float rouge[] = { 1.0F,0.0F,0.0F,1.0F }; static const float bleu[] = { 0.0F,0.0F,1.0F,1.0F }; static const float jaune[] = { 1.0F,1.0F,0.0F,1.0F }; static const float magenta[] = { 1.0F,0.0F,1.0F,1.0F }; static const float gris[] = { 0.7F,0.7F,0.7F,1.0F }; static float rx = -70.0F; static float ry = 0.0F; static float rz = -75.0F; static double az = 0.0; static double a = 10.0; static double ni = 1.3333333; static double nt = 1.3333333; /* 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 de l'appui */ /* d'une touche de curseur ou d'une touche */ /* page up ou page down */ static void special(int key,int x,int y) { int mod = glutGetModifiers(); switch(key) { case GLUT_KEY_UP : switch ( mod ) { case GLUT_ACTIVE_SHIFT : a++; break; case GLUT_ACTIVE_CTRL : ni = pow(ni,101.0/100.0); break; case GLUT_ACTIVE_ALT : nt = pow(nt,101.0/100.0); break; default : rx++; break; } glutPostRedisplay(); break; case GLUT_KEY_DOWN : switch ( mod ) { case GLUT_ACTIVE_SHIFT : a--; break; case GLUT_ACTIVE_CTRL : ni = pow(ni,100.0/101.0); break; case GLUT_ACTIVE_ALT : nt = pow(nt,100.0/101.0); break; default : rx--; break; } glutPostRedisplay(); break; case GLUT_KEY_LEFT : if ( mod == GLUT_ACTIVE_SHIFT ) az++; else ry++; glutPostRedisplay(); break; case GLUT_KEY_RIGHT : if ( mod == GLUT_ACTIVE_SHIFT ) az--; else ry--; glutPostRedisplay(); break; case GLUT_KEY_PAGE_UP : rz++; glutPostRedisplay(); break; case GLUT_KEY_PAGE_DOWN : rz--; glutPostRedisplay(); break; } } /* Fonction d'initialisation des parametres */ /* OpenGL ne changeant pas au cours de la vie */ /* du programme */ static void init(void) { glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); glEnable(GL_NORMALIZE); glEnable(GL_AUTO_NORMAL); glEnable(GL_LIGHT0); } /* Scene dessinee */ static void traceRayon(Direction3D *rayon,const float *coul) { glEnable(GL_LIGHTING); glMaterialfv(GL_FRONT,GL_DIFFUSE,coul); flecheEnVolume(rayon->c[0],rayon->c[1],rayon->c[2],0.06F,0.3F,0.02F); glDisable(GL_LIGHTING); } static void scene(void) { TransformationGeometrique3D *m = new TransformationGeometrique3D(); Rotation3D *rtx = new Rotation3D(rx,1.0,0.0,0.0); Rotation3D *rty = new Rotation3D(ry,0.0,1.0,0.0); Rotation3D *rtz = new Rotation3D(rz,0.0,0.0,1.0); m->compose(rtz); m->compose(rty); m->compose(rtx); delete(rtx); delete(rty); delete(rtz); Position3D *p1 = new Position3D( 1.0, 1.0,0.0); Position3D *p2 = new Position3D(-1.0, 1.0,0.0); Position3D *p3 = new Position3D(-1.0,-1.0,0.0); Position3D *p4 = new Position3D( 1.0,-1.0,0.0); m->transforme(p1); m->transforme(p2); m->transforme(p3); m->transforme(p4); glPushMatrix(); glColor3fv(blanc); glBegin(GL_LINE_LOOP); glVertex3d(p1->c[0],p1->c[1],p1->c[2]); glVertex3d(p2->c[0],p2->c[1],p2->c[2]); glVertex3d(p3->c[0],p3->c[1],p3->c[2]); glVertex3d(p4->c[0],p4->c[1],p4->c[2]); glEnd(); glPopMatrix(); Direction3D *v1 = new Direction3D(p1,p3); Direction3D *n = new Direction3D(p1,p2); n->produitVectoriel(v1); n->normalisation(); delete(v1); delete(p1); delete(p2); delete(p3); delete(p4); Rotation3D *rtaz = new Rotation3D(az,0.0,0.0,1.0); rtaz->compose(m); Direction3D *d1 = new Direction3D(1.0,0.0,0.0); rtaz->transforme(d1); Rotation3D *rta = new Rotation3D(a,d1->c[0],d1->c[1],d1->c[2]); Direction3D *i = new Direction3D(n); rta->transforme(i); delete(rta); delete(d1); delete(rtaz); delete(m); Direction3D *r = new Direction3D(); Direction3D *t = new Direction3D(); traceRayon(n,magenta); traceRayon(i,jaune); printf("ni: %9.4lf, nt:%9.4lf\nai: %9.4lf\n",ni,nt,a); printf("Normale : "); n->print(); printf("\n"); printf("rayon incident : "); i->print(); printf("\n"); printf("rayon reflechi : "); if ( r->reflexion(i,n) ) { traceRayon(r,rouge); r->print(); } else { printf("N/A"); } printf("\n"); printf("rayon transmis : "); if ( t->transmission(i,n,ni,nt) ) { traceRayon(t,bleu); t->print(); printf(" %9.4lf",acos(-n->produitScalaire(t))*180.0/M_PI); } else { printf("N/A"); } printf("\n\n"); delete(r); delete(t); delete(i); delete(n); } /* Fonction executee lors d'un rafraichissement */ /* de la fenetre de dessin */ static void display(void) { glClearColor(0.5F,0.5F,0.5F,1.0F); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); scene(); glPopMatrix(); glFlush(); glutSwapBuffers(); int error = glGetError(); if ( error != GL_NO_ERROR ) printf("Erreur OpenGL: %d\n",error); } /* Fonction executee lors d'un changement */ /* de la taille de la fenetre OpenGL */ /* -> Ajustement de la camera de visualisation */ static void reshape(int x,int y) { glViewport(0,0,x,y); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if ( x > y ) glOrtho(-1.1*(double) x/y,1.1*(double) x/y,-1.1,1.1,-2.0,2.0); else glOrtho(-1.1,1.1,-1.1*(double) y/x,1.1*(double) y/x,-2.0,2.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } /* Fonction principale */ int main(int argc,char **argv) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE); glutInitWindowSize(300,300); glutInitWindowPosition(50,50); glutCreateWindow("Reflexion et transmission"); init(); glutKeyboardFunc(keyboard); glutSpecialFunc(special); glutReshapeFunc(reshape); glutDisplayFunc(display); glutMainLoop(); return(0); }