L'exécutable

 

 

Le source : BSplineCurve.cpp

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

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

#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
  
typedef struct coord_3D {
  GLfloat x,y,z,w; } coord_3D;

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

typedef float matrice[4][4];

static float rx = 0.0F;
static float ry = 0.0F;
static float rz = 0.0F;
static GLfloat vert[4] = { 0.0F,1.0F,0.0F,1.0F };
static GLfloat bleu[4] = { 0.0F,0.0F,1.0F,1.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 coord_3D ptsi[28] = { 
  {-3.0,-3.0,-3.0,1.0},{-3.0, 3.0,-3.0,1.0}, 
  { 3.0, 3.0,-3.0,1.0},{ 3.0,-3.0,-3.0,1.0}, 
  {-3.0,-3.0,-2.0,1.0},{-3.0, 3.0,-2.0,1.0}, 
  { 3.0, 3.0,-2.0,1.0},{ 3.0,-3.0,-2.0,1.0}, 
  {-3.0,-3.0,-1.0,1.0},{-3.0, 3.0,-1.0,1.0}, 
  { 3.0, 3.0,-1.0,1.0},{ 3.0,-3.0,-1.0,1.0}, 
  {-3.0,-3.0, 0.0,1.0},{-3.0, 3.0, 0.0,1.0}, 
  { 3.0, 3.0, 0.0,1.0},{ 3.0,-3.0, 0.0,1.0}, 
  {-3.0,-3.0, 1.0,1.0},{-3.0, 3.0, 1.0,1.0}, 
  { 3.0, 3.0, 1.0,1.0},{ 3.0,-3.0, 1.0,1.0}, 
  {-3.0,-3.0, 2.0,1.0},{-3.0, 3.0, 2.0,1.0}, 
  { 3.0, 3.0, 2.0,1.0},{ 3.0,-3.0, 2.0,1.0}, 
  {-3.0,-3.0, 3.0,1.0},{-3.0, 3.0, 3.0,1.0}, 
  { 3.0, 3.0, 3.0,1.0},{ 3.0,-3.0, 3.0,1.0} }; 
static coord_3D pts[28];
static int aff = 28;
static int nbp = 300;
static int m = 0;
static int p = 0;

static lignePolygonale pl = { 28,(coord_3D *) &pts[0] };
matrice m1 = { -0.1666666F, 0.5F,      -0.5F,      0.1666666F,
                0.5F      ,-1.0F,       0.5F,      0.0F,
               -0.5F      , 0.0F,       0.5F,      0.0F,
                0.1666666F, 0.6666666F, 0.1666666F,0.0F } ;
matrice m2 = { -0.5F, 1.5F,-1.5F, 0.5F,
                1.0F,-2.5F, 2.0F,-0.5F,
               -0.5F, 0.0F, 0.5F, 0.0F,
                0.0F, 1.0F, 0.0F, 0.0F } ;

void calculPoint(coord_3D *p,coord_3D *g,float t,matrice m) {
  float tt[4],ttt[4] ;
  tt[0] = t*t*t ;
  tt[1] = t*t ;
  tt[2] = t ;
  tt[3] = 1.0F ;
  for ( int j = 0 ; j < 4 ; j++ ) {
    ttt[j] = 0 ;
    for ( int k = 0 ; k < 4 ; k++ )
      ttt[j] += tt[k] * m[k][j] ; }
  for ( int j = 0 ; j < 4 ; j++ ) {
    p->x += ttt[j] * g[j].x ;
    p->y += ttt[j] * g[j].y ;
    p->z += ttt[j] * g[j].z ; }
  p->w = 1.0F;
}

void bspline(lignePolygonale *p,int n,lignePolygonale *b,matrice m) {
  b->n = n;
  b->p =(coord_3D *) calloc(n,sizeof(coord_3D));
  for ( int i = 0 ; i < n ; i++ ) {
    float t =(float) (p->n-3)*i/(n-1);
    int crv = t;
    t -= crv;
    if ( crv == p->n-3 ) {
      crv = p->n-4;
      t = 1.0F; }
    calculPoint(&b->p[i],&p->p[crv],t,m); }
}

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((GLfloat *) &pts[i]); 
  glEnd(); 
  glColor4fv(rouge);
  glBegin(GL_LINE_STRIP);
  for( i = 0 ; i < aff ; i++ ) 
    glVertex3fv((GLfloat *) &pts[i]); 
  glEnd(); 
  glPointSize(3.0);
  lignePolygonale bsp; 
  bspline(&pl,nbp,&bsp,(m) ? m2 : m1);
  glBegin(GL_POINTS);
  for ( i = 0 ; i < bsp.n ; i++ ) {
    float t =(float) (pl.n-3)*i/(bsp.n-1);
    int crv = t;
    if ( crv == pl.n-3 ) {
      crv = pl.n-4; }
    switch (crv%4) {
      case 0 :
        glColor4fv(magenta);
        break
      case 1 :
        glColor4fv(cyan);
        break
      case 2 :
        glColor4fv(vert);
        break
      case 3 :
        glColor4fv(bleu);
        break; }
    glVertex3fv((GLfloat *)&bsp.p[i]); }
  glEnd();
  free(bsp.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(65.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) {
  for ( int i = 0 ; i < 28 ; i++ )
    pts[i] = ptsi[i];
  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 0x0D :
      p = !p;
      for ( int i = 0 ; i < 28 ; i++ ) {
        pts[i].x = ptsi[i].x + ((p) ? -0.5F + (rand()%100)/100.0F : 0.0F);
        pts[i].y = ptsi[i].y + ((p) ? -0.5F + (rand()%100)/100.0F : 0.0F);
        pts[i].z = ptsi[i].z + ((p) ? -0.5F + (rand()%100)/100.0F : 0.0F); }
      glutPostRedisplay();
      break;
    case 0x1B :
      exit(0);
      break;
    case 0x20 :
      { static int anim = 0;
        anim = !anim;
        glutIdleFunc(( anim ) ? idle : NULL); }
      break;
    case 'm' :
      m = !m;
      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 BSpline"); 
  myinit(); 
  glutReshapeFunc(reshape);
  glutKeyboardFunc(keyboard);
  glutSpecialFunc(special);
  glutDisplayFunc(display);
  glutMainLoop();
  return(0);
}

RETOUR