L'exécutable

  TD10-02.png (4574 octets)

Le source : BezierCurve.cpp

/* Une courbe de Bezier          */
/*                               */
/* Auteur: Nicolas JANEY         */ 
/* nicolas.janey@univ-fcomte.fr  */
/* Novembre 2009                 */

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

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

static float rx = 0.0F;
static float ry = 0.0F;
static float rz = 0.0F;
static GLfloat cyan[4] = { 0.0F,1.0F,1.0F,1.0F };
static GLfloat magenta[4] = { 1.0F,0.0F,1.0F,1.0F };
static GLfloat jaune[4] = { 1.0F,1.0F,0.0F,1.0F };
static GLfloat rouge[4] = { 1.0F,0.0F,0.0F,1.0F };

static GLfloat pts[8][4] = { 
  {-3.0,-3.0,-3.0,1.0},{-2.0, 3.0, 1.0,1.0}, 
  { 2.0,-3.0,-2.0,1.0},{ 3.0, 3.0,-3.0,1.0}, 
  {-2.0,-1.0, 2.0,1.0},{ 3.0,-3.0,-1.0,1.0},
  { 2.0, 3.0, 3.0,1.0},{ 0.0, 0.0, 0.0,1.0} }; 
static int aff = 2;
static int nbp = 40;
  
typedef struct coord_3D {
  GLfloat x,y,z,w; } coord_3D;

typedef struct lignePolygonale {
  int n;
  coord_3D *p; } lignePolygonale;

double power(double v,int p) {
  return(( !v && !p ) ?
    1.:
    pow(v,(double) p));
}

void bezier(lignePolygonale *p,int n,lignePolygonale *b) {
  int i,j;
  float t,mt;
  float *cn,fac;
  b->n = n;
  b->p =(coord_3D *) calloc(n,sizeof(coord_3D));
  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;
    for ( j = 0 ; j < p->n ; j++ ) {
      fac = cn[j]*(float) power(t,j)*
                  (float) power(mt,p->n-1-j);
      b->p[i].x += fac * p->p[j].x;
      b->p[i].y += fac * p->p[j].y;
      b->p[i].z += fac * p->p[j].z; } }
  free(cn);
}

static lignePolygonale pl = { aff,(coord_3D *) &pts[0][0] };

void display(void) { 
  int i; 
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 
  glPushMatrix();
  glRotatef(rx,1.0F,0.0F,0.0F);
  glRotatef(ry,0.0F,1.0F,0.0F);
  glRotatef(rz,0.0F,0.0F,1.0F);
  glPointSize(5.0); 
  glColor4fv(jaune); 
  glBegin(GL_POINTS); 
  for( i = 0 ; i < aff ; i++ ) 
    glVertex3fv(&pts[i][0]); 
  glEnd(); 
  glColor4fv(rouge);
  glBegin(GL_LINE_STRIP);
  for( i = 0 ; i < aff ; i++ ) 
    glVertex3fv(&pts[i][0]); 
  glEnd(); 
  glColor4fv(magenta); 
  glPointSize(3.0);
  lignePolygonale bz; 
  bezier(&pl,nbp,&bz);
  glBegin(GL_POINTS);
  for ( i = 0 ; i < bz.n ; i++ )
    glVertex3fv((GLfloat *)&bz.p[i]);
  glEnd();
  free(bz.p);
  glPopMatrix();
  glFlush();
  glutSwapBuffers();
  int error = glGetError();
  if ( error != GL_NO_ERROR )
    printf("Erreur OpenGL\n",error);


/* Fonction executee lorsqu'aucun evenement     */
/* n'est en file d'attente                      */

void idle(void) {
  rx += 0.4256F;
  ry += 0.6117F;
  rz += 0.4174F;
  glutPostRedisplay() ;
}

/* Fonction executee lors d'un changement       */
/* de la taille de la fenetre OpenGL            */

void reshape(int x,int y) {
  glViewport(0,0,x,y); 
  glMatrixMode(GL_PROJECTION) ;
  glLoadIdentity() ;
  gluPerspective(50.0F,(float) x/y,1.0,40.0) ;
  glMatrixMode(GL_MODELVIEW) ;
  glLoadIdentity() ;
  gluLookAt(0.0,0.0,10.0,0.0,0.0,0.0,0.0,1.0,0.0);
}

/* Fonction executee lors de l'appui            */
/* d'une touche de curseur ou d'une touche      */
/* page up ou page down                         */

void special(int key,int x,int y) {
  switch(key) {
    case GLUT_KEY_UP :
      rx++;
      glutPostRedisplay() ;
      break;
    case GLUT_KEY_DOWN :
      rx--;
      glutPostRedisplay() ;
      break;
    case GLUT_KEY_LEFT :
      ry++;
      glutPostRedisplay() ;
      break;
    case GLUT_KEY_RIGHT :
      ry--;
      glutPostRedisplay() ;
      break;
    case GLUT_KEY_PAGE_UP :
      rz++;
      glutPostRedisplay() ;
      break;
    case GLUT_KEY_PAGE_DOWN :
      rz--;
      glutPostRedisplay() ;
      break; }
}

void myinit(void) { 
  glClearColor(0.0,0.0,0.0,1.0); 
  glEnable(GL_DEPTH_TEST);
  glShadeModel(GL_FLAT); 
  glDepthFunc(GL_LESS);
  glEnable(GL_AUTO_NORMAL);
  glEnable(GL_NORMALIZE);

  
void keyboard(unsigned char key,int x,int y) {
  switch ( key ) {
    case 43 :
      nbp++;
      glutPostRedisplay();
      break;
    case 45 :
      nbp--;
      if ( nbp < 2 )
        nbp = 2;
      glutPostRedisplay();
      break;
    case 0x1B :
      exit(0);
      break;
    case 0x20 :
      { static int anim = 0;
        anim = !anim;
        glutIdleFunc(( anim ) ? idle : NULL); }
      break;
    case 0x0D :
      aff++;
      if ( aff == 9 )
        aff = 2;
      pl.n = aff;
      glutPostRedisplay();
      break; }
}

int main(int argc,char **argv) {
  glutInit(&argc,argv);
  glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
  glutInitWindowSize(300,300); 
  glutInitWindowPosition(50,50); 
  glutCreateWindow("Courbe de Bezier"); 
  myinit(); 
  glutReshapeFunc(reshape);
  glutKeyboardFunc(keyboard);
  glutSpecialFunc(special);
  glutDisplayFunc(display);
  glutMainLoop();
  return(0);
}

RETOUR