|  | Solutions des exercices | |
| Mini-langage
    pour OpenGL,
    fonctions basiques pour Auxiliary library Caméras, implantation en VRML et en OpenGL Mise en route en VRML et en OpenGL Utilisation des primitives graphiques 
 
 Dernière modification | 
 
 
 
 
 Push Push T(1.5,0,-1.5) C Pop Push T(-1.5,0,-1.5) R(30,0,1,0) T(0,0,-0.5) C Pop Push T(-1.5,0,1.5) Z(1,1,2) C Pop Push T(1.5,0,1.5) R(45,0,1,0) C Pop Pop Push R(r1,0,1,0) T(1.5,0,0) Push Z(3,1,1) C Pop T(1.5,0,0) R(r2,0,1,0) T(1.5,0,0) Push Z(3,0.8,0.8) C Pop T(1.8,0,0) R(r3,1,0,0) Push Z(0.6,1.2,1.8) C Pop T(0.8,0,0) Push T(0,0,-0.2-d) Push Z(1.0,1.2,0.4) C Pop Pop Push T(0,0,0.2+d) Push Z(1.0,1.2,0.4) C Pop Pop Pop 
 
 
 
 
 
 
 
      
 
 
 
 
 
 L = Ip Kd cos(q) L = Ip Kd ( #include <stdio.h>
#include <math.h>
typedef struct coord_3D {
  float x ;
  float y ;
  float z ; } coord_3D ;
typedef struct couleur {
  float r ;
  float v ;
  float b ; } couleur ;
typedef struct direction_3D {
  float dx ;
  float dy ;
  float dz ; } direction_3D ;
typedef struct pointLight {
  coord_3D pos ;
  couleur coul ;
  float energie ; } pointLight ;
typedef struct materiau {
  couleur diffusion ;
  couleur reflexion ;
  couleur transmission ;
  couleur emission ; } materiau ;
typedef struct energie {
  float er ;
  float ev ;
  float eb ; } energie ;
float distance(coord_3D *p1,
               coord_3D *p2) {
  double x = p1->x - p2->x ; 
  double y = p1->y - p2->y ; 
  double z = p1->z - p2->z ;
  double d2 = x*x + y*y + z*z ;
  return((float) pow(d2,0.5)) ;
} 
void calculVecteurNorme(coord_3D *pi,
                        coord_3D *pf,
                        direction_3D *n) {
  double x = pf->x - pi->x ; 
  double y = pf->y - pi->y ; 
  double z = pf->z - pi->z ;
  double d2 = x*x + y*y + z*z ;
  d2 = pow(d2,0.5) ;
  n->dx =(float) (x / d2) ;
  n->dy =(float) (y / d2) ;
  n->dz =(float) (z / d2) ;
} 
float produitScalaire(direction_3D *d1,
                      direction_3D *d2) {
  return(d1->dx*d2->dx +
         d1->dy*d2->dy +
         d1->dz*d2->dz) ;
} 
/* En entree les coordonnees du point p
et la pointlight l. En sortie l'energie
recue*/
void calculEnergieRecue(coord_3D *p,
                        pointLight *l,
                        energie *e) {
  float d = distance(p,&l->pos) ;
  float atten = 1.0F / d / d ;
  e->er = atten * l->energie * l->coul.r ;
  e->ev = atten * l->energie * l->coul.v ;
  e->eb = atten * l->energie * l->coul.b ;
}
/* En entree les coordonnees du point p,
la normale n a la surface au point p, le
materiau m de la surface, la pointlight l.
En sortie l'energie diffusee*/
void calculEnergieDiffusee(coord_3D *p,
                           direction_3D *n,
                           materiau *m,
                           pointLight *l,
                           energie *e) {
  energie recu ;
  calculEnergieRecue(p,l,&recu) ;
  direction_3D li ;
  calculVecteurNorme(p,&l->pos,&li) ;
  float scal = produitScalaire(&li,n) ;
  if ( scal < 0.0F )
    scal = 0.0F ;
  e->er = recu.er * scal * m->diffusion.r ;
  e->ev = recu.ev * scal * m->diffusion.v ;
  e->eb = recu.eb * scal * m->diffusion.b ;
}
void main(void) {
  coord_3D p = { 1.0F,2.0F,0.0F } ;
  direction_3D n = { 0.0F,0.0F,1.0F } ;
  pointLight l = { {-1.0F,2.0F,4.0F},
                   {1.0F,0.5F,0.5F},
                   5.0F } ;
  materiau m = { {0.5F,0.5F,1.0F},
                 {0.0F,0.0F,0.0F},
                 {0.0F,0.0F,0.0F},
                 {0.0F,0.0F,0.0F} } ;
  energie e ;
  energie ed ;
  calculEnergieRecue(&p,&l,&e) ;
  printf("Energie recue    : %f %f %f\n",
         e.er,e.ev,e.eb) ;
  calculEnergieDiffusee(&p,&n,&m,&l,&ed) ;
  printf("Energie diffusee : %f %f %f\n",
         ed.er,ed.ev,ed.eb) ;
}
 Fichier source: TD-Diffusion.cpp 
 
 
 #include <stdio.h>
#include <math.h>
typedef struct coord_3D {
  float x ;
  float y ;
  float z ; } coord_3D ;
typedef struct direction_3D {
  float dx ;
  float dy ;
  float dz ; } direction_3D ;
typedef struct rayon {
  coord_3D pos ;
  direction_3D dir ; } rayon ;
/* En entree le rayon r teste. En sortie
le nombre d'intersection(s) */
int intersectionSphere(rayon *r) {
  float a = r->dir.dx*r->dir.dx +
            r->dir.dy*r->dir.dy +
            r->dir.dz*r->dir.dz ;
  float b = 2*(r->dir.dx*r->pos.x +
               r->dir.dy*r->pos.y +
               r->dir.dz*r->pos.z) ;
  float c = r->pos.x*r->pos.x +
            r->pos.y*r->pos.y +
            r->pos.z*r->pos.z - 1 ;
  float delta = b*b - 4*a*c ;
  if ( delta > 0 )
    return(2) ;
  if ( delta == 0 )
    return(1) ;
  return(0) ;
}
int posIntersectionSphere(rayon *r,
                          coord_3D *p) {
  float a = r->dir.dx*r->dir.dx +
            r->dir.dy*r->dir.dy +
            r->dir.dz*r->dir.dz ;
  float b = 2*(r->dir.dx*r->pos.x + 
               r->dir.dy*r->pos.y + 
               r->dir.dz*r->pos.z) ;
  float c = r->pos.x*r->pos.x + 
            r->pos.y*r->pos.y + 
            r->pos.z*r->pos.z - 1 ;
  float delta = b*b - 4*a*c ;
  if ( delta > 0 ) {
    float rcn =(float) pow(delta,0.5) ;
    float d = (-b-rcn)/2/a ;
    if ( d > 0 ) {
      p->x = r->pos.x + d * r->dir.dx ;
      p->y = r->pos.y + d * r->dir.dy ;
      p->z = r->pos.z + d * r->dir.dz ;
      return(1) ; }
      else {
      float d = (-b+rcn)/2/a ;
      if ( d > 0 ) {
        p->x = r->pos.x + d * r->dir.dx ;
        p->y = r->pos.y + d * r->dir.dy ;
        p->z = r->pos.z + d * r->dir.dz ;
        return(1) ; } }
    return(0) ; }
  if ( delta == 0 ) {
    float d = -b/2/a ;
    p->x = r->pos.x + d * r->dir.dx ;
    p->y = r->pos.y + d * r->dir.dy ;
    p->z = r->pos.z + d * r->dir.dz ;
    return(1) ; }
  return(0) ;
}
float produitScalaire(direction_3D *d1,
                      direction_3D *d2) {
  return(d1->dx*d2->dx +
         d1->dy*d2->dy +
         d1->dz*d2->dz) ;
} 
void calculReflexion(rayon *r,
                     float d,
                     rayon *ref) {
  ref->pos.x = r->pos.x + d * r->dir.dx ;
  ref->pos.y = r->pos.y + d * r->dir.dy ;
  ref->pos.z = r->pos.z + d * r->dir.dz ;
  direction_3D n = { ref->pos.x,
                     ref->pos.y,
                     ref->pos.z } ;
  direction_3D i = { -r->dir.dx,
                     -r->dir.dy,
                     -r->dir.dz } ;
  float scal = produitScalaire(&n,&i) ;
  ref->dir.dx = 2 * n.dx * scal - i.dx ;
  ref->dir.dy = 2 * n.dy * scal - i.dy ;
  ref->dir.dz = 2 * n.dz * scal - i.dz ;
}
/* En entree le rayon r teste. En sortie
un booleen indiquant l'existence d'un
rayon reflechi, le rayon reflechi ref */
int rayonReflechiSphere(rayon *r,
                        rayon *ref) {
  float a = r->dir.dx*r->dir.dx +
            r->dir.dy*r->dir.dy +
            r->dir.dz*r->dir.dz ;
  float b = 2*(r->dir.dx*r->pos.x +
               r->dir.dy*r->pos.y +
               r->dir.dz*r->pos.z) ;
  float c = r->pos.x*r->pos.x +
            r->pos.y*r->pos.y +
            r->pos.z*r->pos.z - 1 ;
  float delta = b*b - 4*a*c ;
  a *= 2 ;
  if ( delta > 0 ) {
    float rcn =(float) pow(delta,0.5) ;
    float d = (-b-rcn)/a ;
    if ( d > 0 ) {
      calculReflexion(r,d,ref) ;
      return(1) ; }
      else {
      float d = (-b+rcn)/2 ;
      if ( d > 0 ) {
        calculReflexion(r,d,ref) ;
        return(1) ; } }
    return(0) ; }
  if ( delta == 0 ) {
    float d = -b/a ;
    calculReflexion(r,d,ref) ;
    return(1) ; }
  return(0) ;
}
void main(void) {
/*  rayon r = { {3.0F,-0.2F,-0.3F},
              {-0.95F,0.22F,0.22F} } ;*/
/*  rayon r = { {3.0F,0.7071067811F,
                 0.7071067811F},
              {-1.0F,0.0F,0.0F} } ;*/
/*  rayon r = { {3.0F,0.7071067811F,0.0F},
              {-1.0F,0.0F,0.0F} } ;*/
  rayon r = { {3.0F,0.0F,0.7071067811F},
              {-1.0F,0.0F,0.0F} } ;
  printf("Rayon initial : %f %f %f\n",
         r.pos.x,r.pos.y,r.pos.z) ;
  printf("                %f %f %f\n",
         r.dir.dx,r.dir.dy,r.dir.dz) ;
  int n = intersectionSphere(&r) ;
  printf("Nombre intersections  : %d\n",n) ;
  coord_3D p ;
  int inter = posIntersectionSphere(&r,&p) ;
  if ( inter ) {
    printf("Pos intersection : %f %f %f\n",
           p.x,p.y,p.z) ; }
    else {
    printf("Pas d'intersection\n") ; }
  rayon ref ;
  inter = rayonReflechiSphere(&r,&ref) ;
  if ( inter ) {
    printf("Rayon reflechi : %f %f %f\n",
           ref.pos.x,ref.pos.y,ref.pos.z) ;
    printf("                 %f %f %f\n",
           ref.dir.dx,
           ref.dir.dy,
           ref.dir.dz) ; }
    else {
    printf("Pas de reflexion\n") ; }
}
 Fichier source: TD-Reflexion.cpp 
 #include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct coord_3D {
  float x ;
  float y ;
  float z ; } coord_3D ;
typedef struct polygone {
  int n ;
  coord_3D *c ; } polygone ;
void pixel(float x,float y,float z) {
    printf("%f %f %f\n",x,y,z) ; 
  }
double power(double v,int p) {
  return(( !v && !p ) ?
    1.:
    pow(v,(double) p)) ;
}
/* En entree le polygone p, le nombre
de points n */
void bezier(polygone *p,int n) {
  int i,j ;
  float t,mt ;
  float *cn,x,y,z,fac ;
  cn =(float *) calloc(p->n,sizeof(float));
  cn[0] = 1 ;
  cn[1] =(float) (p->n-1) ;
  for ( i = 2 ; i < p->n ; i++ )
    cn[i] = cn[i-1] * (p->n - i) / i ;
  for ( i = 0 ; i < n ; i++ ) {
    t =(float) i/(n-1) ;
    mt = 1-t ;
    x = y = z = 0.0F ;
    for ( j = 0 ; j < p->n ; j++ ) {
      fac = cn[j]*(float) power(t,j)*
            (float) power(mt,p->n-1-j);
      x += fac * p->c[j].x ;
      y += fac * p->c[j].y ;
      z += fac * p->c[j].z ; }
    pixel(x,y,z) ; }
  free(cn) ;
}
void main(void) {
  coord_3D c[8] = { {-6.0F,-6.0F, 3.0F},
                    {-6.0F,-1.0F, 1.0F},
                    {-5.0F, 2.0F,-1.0F},
                    {-1.0F, 3.0F, 1.0F},
                    { 2.0F, 1.0F, 4.0F},
                    { 4.0F, 2.0F, 2.0F},
                    { 5.0F, 5.0F,-2.0F},
                    { 6.0F, 6.0F,-4.0F} } ;
  polygone p = { 8,c } ;
  bezier(&p,50) ;
}Fichier source: TD-Bezier.cpp static GLfloat pts[7][3] = { {3,2,-1},{-4,5,-4}, {-5,4,3},{-1,-3,-2}, {4,-1,0}}; void traceBezierGL(void) { glMap1f(GL_MAP1_VERTEX_3, 0.0,1.0,3,5,&pts[0][0]); glEnable(GL_MAP1_VERTEX_3); glColor3f(0.0,1.0,1.0); glBegin(GL_POINTS); for ( int i = 0 ; i <= 100 ; i++ ) glEvalCoord1f((GLfloat) i/100.0F); glEnd(); } Fichier source complet: TD-Bezier-GL.cpp 
 float p = 0.55 ;
float pts1[4][3] = { {1.0F,0.0F,0.0F},
                     {1.0F,p,0.0F},
                     {p,1.0F,0.0F},
                     {0.0F,1.0F,0.0F} } ;
void traceQuartCercleBezierGL(float r) {
  glPushMatrix() ;
  glScalef(r,r,r) ;
  glMap1f(GL_MAP1_VERTEX_3,
          0.0,1.0,3,4,&pts1[0][0]); 
  glEnable(GL_MAP1_VERTEX_3); 
  glColor3f(0.0,1.0,1.0);
  glBegin(GL_POINTS); 
  for ( int i = 0 ; i <= n ; i++ ) 
    glEvalCoord1f((GLfloat) i/100.0F); 
  glEnd(); 
  glPopMatrix() ;
}
void traceCercleBezierGL(float r) {
  glPushMatrix() ;
  traceQuartCercleBezierGL(r) ;
  glRotatef(90.0F,0.0F,0.0F,1.0F) ;
  traceQuartCercleBezierGL(r) ;
  glRotatef(90.0F,0.0F,0.0F,1.0F) ;
  traceQuartCercleBezierGL(r) ;
  glRotatef(90.0F,0.0F,0.0F,1.0F) ;
  traceQuartCercleBezierGL(r) ;
  glPopMatrix() ;
}
 Fichier source complet: TD-Bezier-GL-Cercle.cpp 
 float p = 0.55F ;
float pts1[16][3] = { {1.0F,0.0F,1.0F},
                      {1.0F,p,1.0F},
                      {p,1.0F,1.0F},
                      {0.0F,1.0F,1.0F},
                      {1.0F,0.0F,0.3F},
                      {1.0F,p,0.3F},
                      {p,1.0F,0.3F},
                      {0.0F,1.0F,0.3F},
                      {1.0F,0.0F,-0.3F},
                      {1.0F,p,-0.3F},
                      {p,1.0F,-0.3F},
                      {0.0F,1.0F,-0.3F},
                      {1.0F,0.0F,-1.0F},
                      {1.0F,p,-1.0F},
                      {p,1.0F,-1.0F},
                      {0.0F,1.0F,-1.0F} } ;
void traceQuartTuyauBezierGL(float r,
                             float h) {
  glPushMatrix() ;
  glScalef(r,r,h/2) ;
  glMap2f(GL_MAP2_VERTEX_3,0.0F,1.0F,
          3,4,
          0.0F,1.0F,
          12,4,
          (float *) pts1); 
  glEnable(GL_MAP2_VERTEX_3); 
  glEnable(GL_AUTO_NORMAL); 
  glEnable(GL_NORMALIZE); 
  glMapGrid2f(np1,0.0,1.0,np2,0.0,1.0); 
  if ( ff )
    glEvalMesh2(GL_LINE,0,np1,0,np2); 
    else
    glEvalMesh2(GL_FILL,0,np1,0,np2); 
  glPopMatrix() ;
}
void traceTuyauBezierGL(float r,float h) {
  glPushMatrix() ;
  traceQuartTuyauBezierGL(r,h) ;
  glRotatef(90.0F,0.0F,0.0F,1.0F) ;
  traceQuartTuyauBezierGL(r,h) ;
  glRotatef(90.0F,0.0F,0.0F,1.0F) ;
  traceQuartTuyauBezierGL(r,h) ;
  glRotatef(90.0F,0.0F,0.0F,1.0F) ;
  traceQuartTuyauBezierGL(r,h) ;
  glPopMatrix() ;
}Fichier source complet: TD-Bezier-GL-Tuyau.cpp   Fichier source complet: TD-Bezier-GL-Tuyau2.cpp 
 float p = 0.55F ;
float pts1[10][2] = { {0.0F,-5.0F},
                      {5.0F,-5.0},
                      {4.5F,-4.0F},
                      {2.0F,-2.0F},
                      {1.5F,0.0F},
                      {0.2F,1.0F},
                      {0.2F,2.0F},
                      {1.5F,4.0F},
                      {1.5F,5.0F},
                      {0.5F,5.0F} } ;
void points(float *pts) {
  glDisable(GL_LIGHTING) ;
  glPointSize(5.0); 
  glColor3f(0.0,1.0,1.0); 
  glBegin(GL_POINTS); 
  for ( int i = 0 ; i < 40 ; i++ ) 
    glVertex3fv(&pts[i*3]); 
  glEnd(); 
  glEnable(GL_LIGHTING) ;
}
void traceQuartVaseBezierGL(void) {
  glPushMatrix() ;
  float pts[10][4][3] ;
  for ( int i = 0 ; i < 10 ; i++ ) {
    pts[i][0][0] = pts1[i][0] ; 
    pts[i][0][1] = pts1[i][1] ; 
    pts[i][0][2] = 0.0F ; 
    pts[i][1][0] = pts1[i][0] ; 
    pts[i][1][1] = pts1[i][1] ; 
    pts[i][1][2] = p*pts1[i][0] ; 
    pts[i][2][0] = p*pts1[i][0] ; 
    pts[i][2][1] = pts1[i][1] ; 
    pts[i][2][2] = pts1[i][0] ; 
    pts[i][3][0] = 0.0F ;
    pts[i][3][1] = pts1[i][1] ; 
    pts[i][3][2] = pts1[i][0] ; }
  glMap2f(GL_MAP2_VERTEX_3,
          0.0F,1.0F,
          3,4,
          0.0F,1.0F,
          12,10,
          (float *) pts); 
  glEnable(GL_MAP2_VERTEX_3); 
  glEnable(GL_AUTO_NORMAL); 
  glEnable(GL_NORMALIZE); 
  glMapGrid2f(np1,0.0,1.0,np2,0.0,1.0); 
  if ( ff )
    glEvalMesh2(GL_LINE,0,np1,0,np2); 
    else
    glEvalMesh2(GL_FILL,0,np1,0,np2); 
  glPopMatrix() ;
}
void traceVaseBezierGL(void) {
  glPushMatrix() ;
  traceQuartVaseBezierGL() ;
  glRotatef(90.0F,0.0F,1.0F,0.0F) ;
  traceQuartVaseBezierGL() ;
  glRotatef(90.0F,0.0F,1.0F,0.0F) ;
  traceQuartVaseBezierGL() ;
  glRotatef(90.0F,0.0F,1.0F,0.0F) ;
  traceQuartVaseBezierGL() ;
  glPopMatrix() ;
}Fichier source complet: TD-Bezier-GL-Revolution.cpp 
 
 
 
 
 |