L'exécutable

Le source : CourbesLissees.cpp

/* Auteur: Nicolas JANEY         */ 
/* nicolas.janey@univ-fcomte.fr  */
/* Decembre 2008                 */
/* Des courbes lissees           */

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

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

#include "ModuleFont.h"

/* Variables globales                           */

static const GLfloat jaune[4] = { 1.0F,1.0F,0.0F,0.0F };
static const GLfloat cyan[4] = { 0.0F,1.0F,1.0F,0.0F };
static const GLfloat magenta[4] = { 1.0F,0.0F,1.0F,0.0F };
static const GLfloat rouge[4] = { 1.0F,0.0F,0.0F,0.0F };
static const GLfloat couleurs[5][4] = { { 1.0F,1.0F,0.0F,0.0F },
                                        { 0.0F,1.0F,1.0F,0.0F },
                                        { 1.0F,0.0F,1.0F,0.0F },
                                        { 0.0F,1.0F,0.0F,0.0F },
                                        { 0.0F,0.0F,1.0F,0.0F } };

static float rx = 0.0F;
static float ry = 0.0F;
static int mouvement = 0;
static int button = 0;
static int mx;
static int my;

static GLfloat pts[8][4] = { 
  {-3.0F,-3.0F,-3.0F,1.0F },
  {-2.0F, 3.0F, 1.0F,1.0F }, 
  { 0.0F, 3.0F,-2.0F,1.0F },
  { 3.0F, 0.0F,-3.0F,1.0F }, 
  {-2.0F,-1.0F, 2.0F,1.0F },
  { 3.0F,-3.0F,-1.0F,1.0F },
  { 2.0F, 3.0F, 3.0F,1.0F },
  { 0.0F, 0.0F, 0.0F,1.0F } }; 
static int aff = 2;
static int m = 0;
static int n = 20;
static int dsp = 0;
  
typedef struct coord_3D {
  GLfloat x;
  GLfloat y;
  GLfloat z;
  GLfloat t; } coord_3D;

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

typedef float matrice[4][4] ;

polygone pl = { aff,(coord_3D *) &pts[0][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 pixel(float x,float y,float z) {
    glVertex3f(x,y,z); 
  }

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

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->p[j].x;
      y += fac * p->p[j].y;
      z += fac * p->p[j].z; }
    pixel(x,y,z); }
  free(cn);
}

void display1(void) { 
  int i; 
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 
  glPushMatrix();
  glEnable(GL_DEPTH_TEST);
  glRotatef(rx,1.0F,0.0F,0.0F);
  glRotatef(ry,0.0F,1.0F,0.0F);
  glColor4fv(cyan); 
  glBegin(GL_LINE_STRIP); 
  for( i = 0 ; i <= n ; i++ ) 
    glEvalCoord1f((GLfloat) i/n); 
  glEnd(); 
  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); 
  glBegin(GL_POINTS); 
  bezier(&pl,n);
  glEnd(); 
  glDisable(GL_DEPTH_TEST);
  glColor4fv(jaune); 
  for( i = 0 ; i < aff ; i++ )  {
    placeFontCursor(pts[i][0]+0.3F,pts[i][1]+0.3F,pts[i][2]+0.3F);
    simpleBitmapOutput("%d",i); }
  glPopMatrix();
  glFlush();
  glutSwapBuffers();


void lisse(coord_3D *p,int n,matrice m) { 
  int i,j,k ;
  float tt[4],ttt[4],x,y,z ;
  for ( i = 0 ; i < n ; i++ ) {
    float t =(float) i/(n-1) ;
    tt[0] = t*t*t ;
    tt[1] = t*t ;
    tt[2] = t ;
    tt[3] = 1 ;
    for ( j = 0 ; j < 4 ; j++ )
      for ( k = 0,ttt[j] = 0 ; k < 4 ; k++ )
        ttt[j] += tt[k] * m[k][j] ;
    x = y = z = 0 ;
    for ( j = 0 ; j < 4 ; j++ ) {
      x += ttt[j] * p[j].x ;
      y += ttt[j] * p[j].y ;
      z += ttt[j] * p[j].z ; }
    pixel(x,y,z) ; }
}

void b_spline(struct polygone *p,matrice m,int n) { 
  for ( int i = 0 ; i < p->n-3 ; i++ ) {
    glColor4fv(couleurs[i]); 
    lisse(&p->p[i],n,m) ; }
}

void display2(void) { 
  int i; 
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 
  glPushMatrix();
  glEnable(GL_DEPTH_TEST);
  glRotatef(rx,1.0F,0.0F,0.0F);
  glRotatef(ry,0.0F,1.0F,0.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(); 
  glPointSize(3.0); 
  glBegin(GL_POINTS); 
  b_spline(&pl,( m ) ? m1 : m2,n);
  glEnd();
  glDisable(GL_DEPTH_TEST);
  glColor4fv(jaune); 
  for( i = 0 ; i < aff ; i++ )  {
    placeFontCursor(pts[i][0]+0.3F,pts[i][1]+0.3F,pts[i][2]+0.3F);
    simpleBitmapOutput("%d",i); }
  glPopMatrix();
  glFlush();
  glutSwapBuffers();


void myinit(void) { 
  glClearColor(0.0,0.0,0.0,1.0); 
  glMap1f(GL_MAP1_VERTEX_4,0.0,1.0,4,aff,&pts[0][0]); 
  glEnable(GL_MAP1_VERTEX_4); 
  glShadeModel(GL_FLAT); 
  glDepthFunc(GL_LESS);
  glEnable(GL_AUTO_NORMAL);
  glEnable(GL_NORMALIZE);
}

/* Fonction executee lors de l'appui            */
/* d'une touche de la souris                    */

void mouse(int bouton,int etat,int x,int y) {
  button = bouton;
  mx = x;
  my = y; 
  if ( etat == GLUT_DOWN ) {
    mouvement = 1; }
  if ( etat == GLUT_UP ) {
    mouvement = 0; } 
}

/* Fonction executee lors du deplacement        */
/* de la souris devant la fenetre               */
/* avec le bouton appuye                        */

void motion(int x,int y) {
  switch ( button ) {
    case GLUT_LEFT_BUTTON :
      if ( mouvement == 1 ) {
        rx += (y-my);
        ry += (x-mx);
        mx = x; 
        my = y; 
        glutPostRedisplay(); }
        break; }
}

/* Fonction executee lors d'un changement       */
/* de la taille de la fenetre OpenGL            */
/* Configuration d'une camera de visualisation  */
/* en projection en perspective                 */

void reshape(int tx,int ty) {
  glViewport(0,0,tx,ty);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  float ratio =(float) tx/ty;
  glOrtho(-5.0,5.0,-5.0/ratio,5.0/ratio,-50.0,50.0);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
}

/* Fonction executee lors de la frappe          */
/* d'une touche alphanumerique du clavier       */

void key(unsigned char key,int x,int y) {
  switch ( key ) {
    case 0x20 :
      dsp = (dsp+1)%2;
      glutDisplayFunc((dsp) ? display2 : display1);
      glutPostRedisplay();
      break;
    case 43 :
      n++;
      glutPostRedisplay();
      break;
    case 45 :
      n--;
      if ( n < 4 )
        n = 4;
      glutPostRedisplay();
      break;
    case 'm' :
    case 'M' :
      m = !m; 
      glutPostRedisplay();
      break;
    case 0x0D :
      aff++;
      if ( aff == 9 )
        aff = 2;
      pl.n = aff;
      glMap1f(GL_MAP1_VERTEX_4,0.0,1.0,4,aff,&pts[0][0]); 
      glutPostRedisplay();
      break;
    case 0x1B :
      exit(0); }
}

int main(int argc,char **argv) {
  glutInit(&argc,argv);
  glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
  glutInitWindowSize(300,300); 
  glutInitWindowPosition(50,50); 
  glutCreateWindow("Courbes lissées"); 
  myinit(); 
  glutReshapeFunc(reshape);
  glutKeyboardFunc(key);
  glutMotionFunc(motion);
  glutMouseFunc(mouse);
  glutDisplayFunc(display1);
  glutMainLoop();
  return(0);
}

ModuleFont.cpp

ModuleFont.h

RETOUR