L'exécutable

CoordonneesHomogenes.h - CoordonneesHomogenes.cpp - Position3D.h - Position3D.cpp

Le source : Bezier.cpp

/* Implantation mathematique             */
/* du calcul d'une courbe de Bezier      */
/*                                       */
/* Auteur: Nicolas JANEY                 */
/* nicolas.janey@univ-fcomte.fr          */
/* Novembre 2011                         */

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

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

#include "Position3D.h"

/* Variables et constantes globales             */
/* pour les angles et les couleurs utilises     */

static int f1;
static int aff = 1;
static int n = 20;
static int m = 500;

static float rx = 10.0F;
static float ry = 30.0F;
static float rz = 10.0F;

static Position3D *ptCtrl1[21] = {
  new Position3D( 5.0, -10.0,  5.0),
  new Position3D(-5.0,  -9.1,  5.0),
  new Position3D(-5.0,  -7.8, -5.0),
  new Position3D( 5.0,  -7.2, -5.0),
  new Position3D( 5.0,  -5.8,  5.0),
  new Position3D(-5.0,  -5.1,  5.0),
  new Position3D(-5.0,  -4.0, -5.0),
  new Position3D( 5.0,  -3.2, -5.0),
  new Position3D( 5.0,  -1.7,  5.0),
  new Position3D(-5.0,  -1.4,  5.0),
  new Position3D(-5.0,   0.0, -5.0),
  new Position3D( 5.0,   1.2, -5.0),
  new Position3D( 5.0,   2.0,  5.0),
  new Position3D(-5.0,   3.1,  5.0),
  new Position3D(-5.0,   4.3, -5.0),
  new Position3D( 5.0,   4.7, -5.0),
  new Position3D( 5.0,   6.2,  5.0),
  new Position3D(-5.0,   7.1,  5.0),
  new Position3D(-5.0,   8.1, -5.0),
  new Position3D( 5.0,   9.3, -5.0),
  new Position3D( 5.0,  10.0,  5.0) };

static Position3D *ptCtrl2[21] = {
  new Position3D( 5.0, -10.0,  5.0),
  new Position3D(-5.0,  -9.1,  5.0),
  new Position3D(-5.0,  -7.2,-15.0),
  new Position3D( 5.0,  -7.8,-15.0),
  new Position3D(15.0,  -5.1,  5.0),
  new Position3D(-5.0,  -5.8,  5.0),
  new Position3D(-5.0,  -4.0, -5.0),
  new Position3D( 5.0,  -3.2, -5.0),
  new Position3D( 5.0,  -1.7, 15.0),
  new Position3D(-5.0,  -1.4,  5.0),
  new Position3D(-5.0,   0.0, -5.0),
  new Position3D( 5.0,   1.2, -5.0),
  new Position3D(15.0,   2.0, 15.0),
  new Position3D(-5.0,   4.1,  5.0),
  new Position3D(-5.0,   3.3,-15.0),
  new Position3D( 5.0,   4.7, -5.0),
  new Position3D(15.0,   7.2,  5.0),
  new Position3D(-5.0,   6.1, 15.0),
  new Position3D(-5.0,   8.1, -5.0),
  new Position3D( 5.0,   9.3, -5.0),
  new Position3D( 5.0,  10.0,  5.0) };

static Position3D **ptCtrl = ptCtrl1;

static void postRedisplay(void) {
  glutPostWindowRedisplay(f1);
}

/* Fonction executee lors d'un changement       */
/* de la taille de la fenetre (1)               */

void reshape(int w,int h) {
  glViewport(0,0,w,h); 
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(-14.0F,14.0,(float) h/w*-14.0,(float) h/w*14.0,-50.0,50.0);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
}

/* Fonction executee lors d'un rafraichissement */
/* de la fenetre de dessin (1)                  */

long long factoriel(int n) {
  if ( n == 0 )
    return(1L);
    else
    return(n*factoriel(n-1));
}

long long c(int i,int n) {
  return(factoriel(n)/factoriel(i)/factoriel(n-i));
}

double power(double x,double y) {
  if ( ( x == 0.0 ) && ( y == 0 ) )
    return(1.0);
    else
    return(pow(x,y));
}

void bezier(Position3D **ptCtrl,int n,int m,Position3D **b) {
  for ( int j = 0 ; j < m ; j++ ) {
    double t =(double) j/(m-1);
    b[j]->c[0] = b[j]->c[1] = b[j]->c[2] = 0.0;
    b[j]->c[3] = 1.0;
    for ( int i = 0 ; i <= n ; i++ ) {
      long long v = c(i,n);
      double v1 = power(t,i);
      double v2 = power(1.0-t,n-i);
      b[j]->c[0] += v*v1*v2*ptCtrl[i]->c[0];
      b[j]->c[1] += v*v1*v2*ptCtrl[i]->c[1];
      b[j]->c[2] += v*v1*v2*ptCtrl[i]->c[2]; } }
}

void display() {
  glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
  glPushMatrix();
  glRotatef(rz,0.0F,0.0F,1.0F);
  glRotatef(ry,0.0F,1.0F,0.0F);
  glRotatef(rx,1.0F,0.0F,0.0F);
  glColor3f(1.0F,0.0F,0.0F);
  glPointSize(3.0F);
  glBegin(GL_LINE_STRIP);
  for ( int i = 0 ; i <= n ; i++ )
    glVertex3d(ptCtrl[i]->c[0],ptCtrl[i]->c[1],ptCtrl[i]->c[2]);
  glEnd();
  Position3D **b =(Position3D **) calloc(m,sizeof(Position3D *));
  for ( int i = 0 ; i < m ; i++ )
    b[i] = new Position3D();
  bezier(ptCtrl,n,m,b);
  glColor3f(1.0F,1.0F,0.0F);
  glPointSize(1.0F);
  glBegin(GL_POINTS);
  for ( int i = 0 ; i < m ; i++ )
    glVertex3d(b[i]->c[0],b[i]->c[1],b[i]->c[2]);
  glEnd();
  for ( int i = 0 ; i < m ; i++ )
    delete(b[i]);
  free(b);
  glPopMatrix();
  glutSwapBuffers();
  int error = glGetError();
  if ( error != GL_NO_ERROR )
    printf("Erreur OpenGL: %d\n",error);
}

void myinit(void) {
  glEnable(GL_DEPTH_TEST);
}

/* Fonction executee lors de la frappe          */
/* d'une touche special du clavier:             */
/* - touches de curseur                         */
/* - touches de fonction                        */
/* - ...                                        */

void special(int code,int x,int y) {
  switch ( code ) {
    case GLUT_KEY_UP :
      rx += 1.0F;
      postRedisplay(); 
      break;
    case GLUT_KEY_DOWN :
      rx -= 1.0F;
      postRedisplay(); 
      break;
    case GLUT_KEY_RIGHT :
      ry += 1.0F;
      postRedisplay(); 
      break;
    case GLUT_KEY_LEFT :
      ry -= 1.0F;
      postRedisplay(); 
      break;
    case GLUT_KEY_PAGE_UP :
      rz += 1.0F;
      postRedisplay(); 
      break;
    case GLUT_KEY_PAGE_DOWN :
      rz -= 1.0F;
      postRedisplay(); 
      break; }
}

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

void idle(void) {
  rx += 0.13355F;
  ry += 0.06117F;
  rz += 0.24174F;
  postRedisplay();
}

/* Fonction executee lors de l'appui            */
/* d'une touche alphanumerique du clavier       */

void keyboard(unsigned char key,int x,int y) {
  switch (key) {
    case 'r' :
      rx = 0.0F;
      ry = 0.0F;
      rz = 0.0F;
      postRedisplay();
      break;
    case 0x20 :
      aff = (aff+1)%2;
      if ( aff )
        ptCtrl = ptCtrl1;
        else
        ptCtrl = ptCtrl2;
      postRedisplay();
      break;
    case 0x0D :
      { static int anim = 0;
        anim = !anim;
        glutIdleFunc(( anim ) ? idle : NULL); }
      break;
    case 0x1B :
      exit(0);
      break; }
}

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

RETOUR