L'exécutable

Algo23.gif (9617 octets)

Algo23.gif (9617 octets)

Le source: Secondaire.cpp

/* Auteur: Nicolas JANEY                 */
/* nicolas.janey@univ-fcomte.fr          */
/* Avril 2001                            */
/* Illustration de la propagation        */
/* des rayons secondaires dans le cadre  */
/* d'un algorithme de lancer de rayons   */

#include <stdio.h>
#include <math.h>

#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>

#include "ModuleCouleurs.h"
#include "ModuleFont.h"
#include "ModuleManipulateur.h"
#include "ModuleMenus.h"

static float oz = 1.0F ;
static float oy = 0.4F ;
static int aff = 0 ;
static float ratio ;
static float alpha = 0.0F ;
static float n = 1.2F ;

int intersection(float px,float py,float pz,float dx,float dy,float dz,float *d1,float *d2) {
  float c = px*px+py*py+pz*pz - 9 ;
  float b = 2*(px*dx+py*dy+pz*dz) ;
  float a = dx*dx+dy*dy+dz*dz ;
  float delta = b*b - 4*a*c ;
  if ( delta < 0 )
    return(0) ;
  if ( delta == 0.0F ) {
    *d1 = -b/2/a ;
    if ( *d1 >= 0.00001F )
      return(1) ;
      else
      return(0) ; }
  *d2 = (-b-(float) sqrt(delta))/2/a ;
  *d1 = (-b+(float) sqrt(delta))/2/a ;
  if ( ( *d1 <= 0.0001F ) && ( *d2 <= 0.00001F ) )
    return(0) ;
  if ( *d2 <= 0.0001F )
    return(1) ;
  return(2) ;
}

void myinit(void) {
  GLfloat light_position0[] = { 0.0F,0.0F,1.0F,0.0F };
  glLightfv(GL_LIGHT0,GL_AMBIENT,couleurNoir());
  glLightfv(GL_LIGHT0,GL_DIFFUSE,couleurBlanc());
  glLightfv(GL_LIGHT0,GL_SPECULAR,couleurNoir());
  glLightfv(GL_LIGHT0,GL_POSITION,light_position0);
  glEnable(GL_LIGHT0);
  glEnable(GL_AUTO_NORMAL);
  glEnable(GL_NORMALIZE);
  glEnable(GL_DEPTH_TEST);
  glDepthFunc(GL_LESS);
  glEnable(GL_ALPHA_TEST);
  glEnable(GL_BLEND);
  glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
}

void rayonOmbre(float x,float y,float z,float px,float py,float pz) {
  glColor4fv(couleurJaune()) ;
  glBegin(GL_LINES);
  glVertex3f(px,py,pz); 
  if ( ( aff != 0 ) && ( alpha > 1.0F ) )
    if ( alpha <= 2.0 )
      glVertex3f(px+(alpha-1.0F)*(x-px),py+(alpha-1.0F)*(y-py),pz+(alpha-1.0F)*(z-pz));
      else
      glVertex3f(x,y,z);
  if ( aff == 0 )
    glVertex3f(x,y,z);
  glEnd();
  glEnable(GL_LIGHTING);
  glMaterialfv(GL_FRONT,GL_DIFFUSE,couleurJaune()) ;
  if ( aff != 0 ) {
    if ( ( alpha > 1.0 ) && ( alpha <= 2.0 ) ) {
      glPushMatrix();
      glTranslatef(px+(alpha-1.0F)*(x-px),py+(alpha-1.0F)*(y-py),pz+(alpha-1.0F)*(z-pz)) ;
      glutSolidSphere(0.1,36,36) ;
      glPopMatrix(); } }
  glPushMatrix();
  glTranslatef(x,y,z) ;
  glutSolidSphere(0.1,36,36) ;
  glPopMatrix();
  glDisable(GL_LIGHTING);
}

void rayonIncident(int n,float d) {
  glPushMatrix();
  glColor4fv(couleurBlanc());
  glBegin(GL_LINES);
  glVertex3f(-8.0F,oy,oz);
  if ( n ) {
    if ( aff == 0 )
      glVertex3f(-8.0F+d,oy,oz);
      else 
      if ( alpha <= 1.0 )
        glVertex3f(-8.0F+alpha*d,oy,oz);
        else
        glVertex3f(-8.0F+d,oy,oz); }
    else {
    glVertex3f(8.0F,oy,oz); }
  glEnd();
  glPopMatrix();
  glEnable(GL_LIGHTING);
  if ( alpha <= 1.0 ) {
    glMaterialfv(GL_FRONT,GL_DIFFUSE,couleurBlanc()) ;
    glPushMatrix();
    glTranslatef(-8.0F+d*alpha,oy,oz) ;
    glutSolidSphere(0.1,36,36) ;
    glPopMatrix(); }
  glDisable(GL_LIGHTING);
}

void rayonReflechi(float px,float py,float pz) {
  float nx = px/3.0F ;
  float ny = py/3.0F ;
  float nz = pz/3.0F ;
  float ix = -1.0F ;
  float iy = 0.0F ;
  float iz = 0.0F ;
  float scal = nx*ix ;
  float rx = 2*nx*scal-ix ;
  float ry = 2*ny*scal-iy ;
  float rz = 2*nz*scal-iz ;
  glPushMatrix();
  glColor4fv(couleurRouge(0.5F));
  glBegin(GL_LINES);
  glVertex3f(px,py,pz);
  if ( aff == 0 )
    glVertex3f(px+5*rx,py+5*ry,pz+5*rz);
    else 
    if ( alpha > 1.0F )
      if ( alpha <= 2.0F )
        glVertex3f(px+(alpha-1)*5*rx,py+(alpha-1)*5*ry,pz+(alpha-1)*5*rz);
        else
        glVertex3f(px+5*rx,py+5*ry,pz+5*rz);
  glEnd();
  glPopMatrix();
  glEnable(GL_LIGHTING);
  if ( alpha > 1.0 ) {
    glMaterialfv(GL_FRONT,GL_DIFFUSE,couleurRouge(0.5F)) ;
    glPushMatrix();
    if ( alpha <= 2.0F )
      glTranslatef(px+(alpha-1)*5*rx,py+(alpha-1)*5*ry,pz+(alpha-1)*5*rz) ;
      else 
      glTranslatef(px+5*rx,py+5*ry,pz+5*rz) ;
    glutSolidSphere(0.1,36,36) ;
    glPopMatrix(); }
  glDisable(GL_LIGHTING);
}

void transmis(float nx,float ny,float nz,float ix,float iy,float iz,float n,float *tx,float *ty,float *tz) {
  float scal = nx*ix ;
  float t = n*scal-(float) sqrt(1.0F-n*n*(1-scal*scal)) ;
  *tx = t*nx-n*ix ;
  *ty = t*ny-n*iy ;
  *tz = t*nz-n*iz ;
}

void rayonTransmis(float px,float py,float pz) {
  float nx = px/3.0F ;
  float ny = py/3.0F ;
  float nz = pz/3.0F ;
  float ix = -1.0F ;
  float iy = 0.0F ;
  float iz = 0.0F ;
  float tx ;
  float ty ;
  float tz ;
  transmis(nx,ny,nz,ix,iy,iz,n,&tx,&ty,&tz);
  float d1 ;
  float d2 ;
  int ni = intersection(px,py,pz,tx,ty,tz,&d1,&d2) ;
  float pix = px+tx*d1 ;
  float piy = py+ty*d1 ;
  float piz = pz+tz*d1 ;
  float nix = pix / 3.0F ;
  float niy = piy / 3.0F ;
  float niz = piz / 3.0F ;
  float tix ;
  float tiy ;
  float tiz ;
  transmis(-nix,-niy,-niz,-tx,-ty,-tz,n,&tix,&tiy,&tiz);
  glPushMatrix();
  glColor4fv(couleurBleu());
  glBegin(GL_LINES);
  glVertex3f(px,py,pz);
  if ( aff == 0 )
    glVertex3f(px+d1*tx,py+d1*ty,pz+d1*tz);
    else 
    if ( alpha > 1.0 )
      if ( alpha <=2.0 )
        glVertex3f(px+(alpha-1)*d1*tx,py+(alpha-1)*d1*ty,pz+(alpha-1)*d1*tz);
        else
        glVertex3f(px+d1*tx,py+d1*ty,pz+d1*tz);
  glEnd();
  glPopMatrix();
  glPushMatrix();
  glColor4fv(couleurMagenta());
  glBegin(GL_LINES);
  glVertex3f(pix,piy,piz);
  if ( aff == 0 )
    glVertex3f(pix+4*tix,piy+4*tiy,piz+4*tiz);
    else
    if ( alpha > 2.0 )
      glVertex3f(pix+(alpha-2.0F)*4*tix,piy+(alpha-2.0F)*4*tiy,piz+(alpha-2.0F)*4*tiz);
  glEnd();
  glPopMatrix();
  glEnable(GL_LIGHTING);
  if ( alpha > 1.0 ) {
    glMaterialfv(GL_FRONT,GL_DIFFUSE,couleurBleu()) ;
    glPushMatrix();
    if ( alpha <= 2.0 )
      glTranslatef(px+(alpha-1)*d1*tx,py+(alpha-1)*d1*ty,pz+(alpha-1)*d1*tz) ;
      else
      glTranslatef(px+d1*tx,py+d1*ty,pz+d1*tz) ;
    glutSolidSphere(0.1,36,36) ;
    glPopMatrix(); }
  if ( alpha > 2.0 ) {
    glMaterialfv(GL_FRONT,GL_DIFFUSE,couleurMagenta()) ;
    glPushMatrix();
    glTranslatef(pix+(alpha-2.0F)*4*tix,piy+(alpha-2.0F)*4*tiy,piz+(alpha-2.0F)*4*tiz);
    glutSolidSphere(0.1,36,36) ;
    glPopMatrix(); }
  glDisable(GL_LIGHTING);
}

void displayObjets(void) {
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  glPushMatrix();
  manipulateurSouris();
  manipulateurClavier();
  glTranslatef(1.0F,0.0F,0.0F);
  float d1 ;
  float d2 ;
  int n = intersection(-8.0F,oy,oz,1.0F,0.0F,0.0F,&d1,&d2) ;
  float px = -8.0F+d2 ;
  rayonIncident(n,d2) ;
  if ( n ) {
    switch ( aff ) {
      case 0 :
      case 1 : rayonOmbre(-4.0F,3.0F,4.0F,px,oy,oz) ;
               rayonOmbre(5.0F,-5.0F,-5.0F,px,oy,oz) ;
               rayonOmbre(-5.0F,-1.0F,5.0F,px,oy,oz) ;
               rayonReflechi(px,oy,oz) ;
               rayonTransmis(px,oy,oz) ;
               break ;
      case 2 : rayonOmbre(-4.0F,3.0F,4.0F,px,oy,oz) ;
               rayonOmbre(5.0F,-5.0F,-5.0F,px,oy,oz) ;
               rayonOmbre(-5.0F,-1.0F,5.0F,px,oy,oz) ;
               break ;
      case 3 : rayonReflechi(px,oy,oz) ;
               break ;
      case 4 : rayonTransmis(px,oy,oz) ;
               break ; } }
  glEnable(GL_LIGHTING);
  glPushMatrix();
  glMaterialfv(GL_FRONT,GL_DIFFUSE,couleurVert(0.5F)) ;
  glutSolidSphere(3.0,36,36) ;
  glPopMatrix();
  glDisable(GL_LIGHTING);
  glPopMatrix();
}

void display(void) {
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  float xmin;
  float ymin;
  if ( ratio > 1.0F ) {
    xmin = -8.0F ;
    ymin = ratio*xmin;
    glOrtho(-8.0,8.0,-ratio*8.0,ratio*8.0,-150.0,150.0); }
    else {
    ymin = -8.0F ;
    xmin = ymin/ratio;
    glOrtho(-8.0/ratio,8.0/ratio,-8.0,8.0,-150.0,150.0); }
  setManipulateurDistance(1.0F);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  glPushMatrix() ;
  glEnable(GL_DEPTH_TEST);
  displayObjets() ;
  glDisable(GL_DEPTH_TEST);
  glColor4fv(couleurBlanc());
  placeFontCursor(xmin+1.0F,ymin+1.0F,0.0F);
  simpleBitmapOutput("n = %f",n);
  glPopMatrix() ;
  glFlush();
  glutSwapBuffers();
}

void reshape(int w,int h) {
  glViewport(0,0,w,h);
  ratio =(float) h/w ;
}

void key(unsigned char key,int x,int y) {
  if ( keyManipulateur(key,x,y) )
    glutPostRedisplay();
    else
    switch ( key ) {
      case '2'  : oy += 0.1F;
                  glutPostRedisplay();
                  break;
      case '8'  : oy -= 0.1F;
                  glutPostRedisplay();
                  break;
      case '4'  : oz += 0.1F;
                  glutPostRedisplay();
                  break;
      case '6'  : oz -= 0.1F;
                  glutPostRedisplay();
                  break;
      case 0x0D : alpha = 0.0F ;
                  aff = (aff+1)%5 ;
                  glutPostRedisplay();
                  break;
      case 43   : n *= 1.02F;
                  glutPostRedisplay();
                  break;
      case 45   : n /= 1.02F;
                  glutPostRedisplay();
                  break; }
}

void idle(void) {
  if ( aff == 0 ) {
    alpha += 0.02F ;
    if ( alpha > 1.0F )
      alpha = 0.0F ; }
  if ( aff != 0 ) {
    alpha += 0.02F ;
    if ( alpha > 3.0F )
      alpha = 0.0F ; }
  glutPostRedisplay() ;
}

int main(int argc,char **argv) {
  glutInit(&argc,argv);
  glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
  glutInitWindowSize(300,300); 
  glutInitWindowPosition(50,50); 
  glutCreateWindow("Rayons secondaires"); 
  myinit(); 
  creationMenuBasique();
  glutKeyboardFunc(key);
  glutSpecialFunc(specialBasique);
  glutMotionFunc(motionBasique);
  glutMouseFunc(sourisBasique);
  glutIdleFunc(idle);
  glutReshapeFunc(reshape);
  glutDisplayFunc(display);
  glutMainLoop();
  return(0);
}

Les modules utilitaires : Modules.zip

WB01624_.gif (281 octets) RETOUR