/* 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 "Pos3D.h" #include "Dir3D.h" #include "Rt3D.h" #include "TG3D.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 ai = 25.0; static double ni = 2.4244; static double nt = 1.3333; static int val = 0; /* Fonction executee lors de la frappe */ /* d'une touche du clavier */ static void keyboard(unsigned char key,int x,int y) { switch ( key ) { case 0x0D : val = (val+1)%3; glutPostRedisplay(); break; 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 : ai++; 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 : ai--; 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(Dir3D *rayon,const float *coul) { glEnable(GL_LIGHTING); glMaterialfv(GL_FRONT,GL_DIFFUSE,coul); flecheEnVolume(rayon->x,rayon->y,rayon->z,0.06F,0.3F,0.02F); glDisable(GL_LIGHTING); } static void scene(void) { Rt3D rtx(rx,1.0,0.0,0.0); Rt3D rty(ry,0.0,1.0,0.0); Rt3D rtz(rz,0.0,0.0,1.0); TG3D m1(&rty,&rtz); TG3D m2(&rtx,&m1); Pos3D p1( 1.0F, 1.0F, 0.0F); Pos3D p2(-1.0F, 1.0F, 0.0F); Pos3D p3(-1.0F,-1.0F, 0.0F); Pos3D p4( 1.0F,-1.0F, 0.0F); p1.transformation(&m2); p2.transformation(&m2); p3.transformation(&m2); p4.transformation(&m2); glPushMatrix(); glColor3fv(blanc); glBegin(GL_LINE_LOOP); glVertex3d(p1.x,p1.y,p1.z); glVertex3d(p2.x,p2.y,p2.z); glVertex3d(p3.x,p3.y,p3.z); glVertex3d(p4.x,p4.y,p4.z); glEnd(); glPopMatrix(); Dir3D v1(&p1,&p3); Dir3D n(&p1,&p2); n.produitVectoriel(&v1); n.normalisation(); Rt3D rtaz0(az,0.0F,0.0F,1.0F); TG3D rtaz(&m2,&rtaz0); Dir3D d1(1.0F,0.0F,0.0F); d1.transformation(&rtaz); Rt3D rta(ai,&d1); Dir3D i(n); i.transformation(&rta); Dir3D r; Dir3D t; traceRayon(&n,magenta); traceRayon(&i,jaune); printf("ni: %9.4lf, nt:%9.4lf\nthetai: %9.4lf\n",ni,nt,acos(n.produitScalaire(&i))*180.0F/M_PI); 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(" thetat: %9.4lf",acos(-n.produitScalaire(&t))*180.0/M_PI); } else { printf("N/A"); } printf("\n\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(); switch (val) { case 0 : ni = 2.4244; nt = 1.3333; ai = 25.0; break; case 1 : ni = 1.5547; nt = 2.7958; ai = 53.026449; break; case 2 : ni = 1.8127; nt = 1.2844; ai = 46.012272; break; } 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); }