L'exécutable

Image419.gif (4182 octets) Image419.gif (4182 octets)

Image419.gif (4182 octets)

Le source : CubiqueTangente.cpp

/* Auteur: Nicolas JANEY          */
/* nicolas.janey@univ-fcomte.fr   */
/* Fevrier 2019                  */
/* Illustration de la generation  */
/* d'une courbe B-Spline          */
/* avec calcul des tangentes      */

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

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

#include "ModuleCouleurs.h"
#include "ModuleFont.h"
#include "ModuleManipulateur.h"
#include "ModuleMenus.h"
#include "ModuleFleche.h"
#include "ModuleReshape.h"

struct coord_3D {
  GLfloat x = 0.0F;
  GLfloat y = 0.0F;
  GLfloat z = 0.0F;
  GLfloat w = 1.0F; };

struct polygone {
  int n = 0;
  coord_3D *p = NULL; };

typedef struct coord_3D coord_3D;
typedef struct polygone polygone;
typedef float matrice[4][4];

static GLfloat pts[4][4] = { 
  {  1.0F,-3.0F,-3.0F, 1.0F },
  {  2.0F, 3.0F,-2.0F, 1.0F },
  { -4.0F, 0.0F, 2.0F, 1.0F }, 
  { -1.0F,-4.0F, 4.0F, 1.0F } };

static int aff = 2;
static int pt = 0;
static int mode = 0;
static int ttan = 1;
static int np = 0;
static int disc = 30;

static polygone pl;
static 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 };
static 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 };
static matrice m3 =
  { -1.0F, 3.0F,-3.0F, 1.0F,
     3.0F,-6.0F, 3.0F, 0.0F,
    -3.0F, 3.0F, 0.0F, 0.0F,
     1.0F, 0.0F, 0.0F, 0.0F };

void point(float x,float y,float z) {
  glVertex3f(x,y,z);
}

void pointIndividuel(float x,float y,float z,float vx,float vy,float vz) {
  glBegin(GL_POINTS);
  glVertex3f(x,y,z);
  glEnd();
  glPushMatrix();
  glTranslatef(x,y,z);
  glEnable(GL_LIGHTING);
  flecheEnVolume(vx,vy,vz,0.04F,0.3F,0.01F);
  glDisable(GL_LIGHTING);
  glPopMatrix();
}

void calcul(float *tt,matrice m,coord_3D *p,float *x,float *y,float *z) {
  int j,k;
  float ttt[4];
  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; }
}

void lisse(coord_3D *p,int n,matrice m) { 
  float tt[4],x,y,z;
  for ( int 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.0F;
    calcul(tt,m,p,&x,&y,&z);
    point(x,y,z); }
}

void tangente(coord_3D *p,int n,matrice m,int pt) { 
  float tt[4],x,y,z,vx,vy,vz;
  float t =(float) pt/(n-1);
  tt[0] = t*t*t;
  tt[1] = t*t;
  tt[2] = t;
  tt[3] = 1.0F;
  calcul(tt,m,p,&x,&y,&z);
  tt[0] = 3*t*t;
  tt[1] = 2*t;
  tt[2] = 1.0F;
  tt[3] = 0.0F;
  calcul(tt,m,p,&vx,&vy,&vz);
  float d = sqrt(vx*vx+vy*vy+vz*vz);
  vx /= d;
  vy /= d;
  vz /= d;
  pointIndividuel(x,y,z,vx,vy,vz);
}

void display(void) { 
  int i;
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  glPushMatrix();
  glEnable(GL_DEPTH_TEST);
  manipulateurSouris();
  manipulateurClavier();
  glColor4fv(couleurBlanc());
  glBegin(GL_LINE_STRIP);
  for ( i = 0 ; i < 4 ; i++ ) 
    glVertex3fv(&pts[i][0]);
  glEnd();
  glPointSize(5.0);
  glBegin(GL_POINTS);
  for ( i = 0 ; i < 4 ; i++ ) {
    glColor4fv((i == pt) ? couleurRouge() : couleurJaune());
    glVertex3fv(&pts[i][0]); }
  glEnd();
  glPointSize(3.0);
  matrice *m;
  switch (aff) {
    case 0 : m = &m1;
             break;
    case 1 : m = &m2;
             break;
    case 2 : m = &m3;
             break; }
  if ( ( mode == 0 ) || ( mode == 2 ) ) {
    glColor4fv(couleurCyan());
    glBegin(GL_LINE_STRIP);
    lisse(pl.p,disc,*m);
    glEnd(); }
  if ( ( mode == 1 ) || ( mode == 2 ) ) {
    glColor4fv(couleurMagenta());
    glBegin(GL_POINTS);
    lisse(pl.p,disc,*m);
    glEnd(); }
  if ( ttan ) {
    tangente(pl.p,disc,*m,np); }
    else
    for ( i = 0 ; i < disc ; i++ )
      tangente(pl.p,disc,*m,i);
  glDisable(GL_DEPTH_TEST);
  for ( i = 0 ; i < 4 ; i++ )  {
    glColor4fv((i == pt) ? couleurRouge() : couleurJaune());
    placeFontCursor(pts[i][0]+0.3F,pts[i][1]+0.3F,pts[i][2]+0.3F);
    simpleBitmapOutput("%d",i); }
  glPopMatrix();
  glPushMatrix();
  glColor4fv(couleurBlanc());
  placeFontCursor(getXmin()+0.3F,getYmin()+0.6F,0.0F);
  switch (aff) {
    case 0 : simpleBitmapOutput("%s","NRUBS");
             break;
    case 1 : simpleBitmapOutput("%s","Catmull Rom");
             break;
    case 2 : simpleBitmapOutput("%s","Bezier");
             break; }
  glPopMatrix();
  glFlush();
  glutSwapBuffers();


void init(void) { 
  glClearColor(0.0,0.0,0.0,1.0);
  glDepthFunc(GL_LESS);
  GLfloat shinines[] = { 50.0 };
  GLfloat l_pos0[] = { -1.0,1.0,1.0,0.0 };
  GLfloat l_pos1[] = { 1.0,1.0,1.0,0.0 };
  glMaterialfv(GL_FRONT,GL_DIFFUSE,couleurVert());
  glMaterialfv(GL_FRONT,GL_SPECULAR,couleurBlanc());
  glMaterialfv(GL_FRONT,GL_SHININESS,shinines);
  glLightfv(GL_LIGHT0,GL_POSITION,l_pos0);
  glLightfv(GL_LIGHT0,GL_POSITION,l_pos1);
  glEnable(GL_LIGHT0);
  glEnable(GL_LIGHT1);
  glEnable(GL_NORMALIZE);
}
  
void special(int k, int x, int y) {
  switch (k) {
    case GLUT_KEY_LEFT      : pts[pt][0] -= 0.1F;
                              glutPostRedisplay();
                              break;
    case GLUT_KEY_RIGHT     : pts[pt][0] += 0.1F;
                              glutPostRedisplay();
                              break;
    case GLUT_KEY_UP        : pts[pt][1] += 0.1F;
                              glutPostRedisplay();
                              break;
    case GLUT_KEY_DOWN      : pts[pt][1] -= 0.1F;
                              glutPostRedisplay();
                              break;
    case GLUT_KEY_PAGE_UP   : pts[pt][2] += 0.1F;
                              glutPostRedisplay();
                              break;
    case GLUT_KEY_PAGE_DOWN : pts[pt][2] += 0.1F;
                              glutPostRedisplay();
                              break; }
}

void key(unsigned char key,int x,int y) {
  if ( keyManipulateur(key,x,y) )
    glutPostRedisplay();
    else
    switch ( key ) {
      case 43     : disc++;
                    glutPostRedisplay();
                    break;
      case 45     : disc--;
                    if ( disc < 3 )
                      disc = 3;
                    np = np%disc;
                    glutPostRedisplay();
                    break;
      case 0x0D   : aff = (aff+1)%3;
                    glutPostRedisplay();
                    break;
      case 'p'    : np = (np+1)%disc;
                    glutPostRedisplay();
                    break;
      case 'P'    : np = np-1;
                    if ( np  < 3 )
                      np = 3;
                    glutPostRedisplay();
                    break;
      case 'm'    : mode = (mode+1)%3;
                    glutPostRedisplay();
                    break;
      case 't'    : ttan = (ttan+1)%2;
                    np = 0;
                    glutPostRedisplay();
                    break;
      case 32     : pt = (pt+1)%4;
                    glutPostRedisplay();
                    break; }
}

void select1(int selection) {
  switch (selection) {
    case 1  : aff = 0;
              glutPostRedisplay();
              break;
    case 2  : aff = 1;
              glutPostRedisplay();
              break;
    case 3  : aff = 2;
              glutPostRedisplay();
              break; }
}

void select2(int selection) {
  switch (selection) {
    case 4  : pt = (pt+1)%4;
              glutPostRedisplay();
              break;
    case 5  : mode = 0;
              glutPostRedisplay();
              break;
    case 6  : mode = 1;
              glutPostRedisplay();
              break;
    case 7  : mode = 2;
              glutPostRedisplay();
              break;
    case 8  : ttan = 1;
              glutPostRedisplay();
              break;
    case 9  : ttan = 0;
              np = 0;
              glutPostRedisplay();
              break; }
}

void select3(int selection) {
  switch (selection) {
    case 10 : disc = 3;
              np = np%disc;
              glutPostRedisplay();
              break;
    case 11 : disc = 10;
              np = np%disc;
              glutPostRedisplay();
              break;
    case 12 : disc = 30;
              np = np%disc;
              glutPostRedisplay();
              break;
    case 13 : disc = 50;
              np = np%disc;
              glutPostRedisplay();
              break;
    case 14 : disc = 100;
              np = np%disc;
              glutPostRedisplay();
              break;
    case 6  : disc++;
              glutPostRedisplay();
              break;
    case 7  : disc--;
              if ( disc < 3 )
                disc = 3;
              np = np%disc;
              glutPostRedisplay();
              break; }
}

void select(int selection) {
  switch (selection) {
    case 0  : exit(0); }
}

void creationMenu(void) {
  int menu1 = glutCreateMenu(select1);
  glutAddMenuEntry("NRUBS",1);
  glutAddMenuEntry("Catmull Rom",2);
  glutAddMenuEntry("Bezier",3);
  int menu2 = glutCreateMenu(select2);
  glutAddMenuEntry("Changer point",4);
  glutAddMenuEntry("Fil de fer",5);
  glutAddMenuEntry("Points",6);
  glutAddMenuEntry("Fil de fer et points",7);
  glutAddMenuEntry("Une tangente",8);
  glutAddMenuEntry("Toutes les tangentes",9);
  int menu3 = glutCreateMenu(select3);
  glutAddMenuEntry("3",10);
  glutAddMenuEntry("10",11);
  glutAddMenuEntry("30",12);
  glutAddMenuEntry("50",13);
  glutAddMenuEntry("100",14);
  glutAddMenuEntry("Augmenter",6);
  glutAddMenuEntry("Reduire",7);
  glutCreateMenu(select);
  glutAddSubMenu("Matrice",menu1);
  glutAddSubMenu("Affichage",menu2);
  glutAddSubMenu("Discretisation",menu3);
  glutAddMenuEntry("Quitter",0);
  glutAttachMenu(GLUT_RIGHT_BUTTON);
}

int main(int argc,char **argv) {
  
  pl.n = 4;
  pl.p =(coord_3D *) &pts[0][0];

  glutInit(&argc,argv);
  glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
  glutInitWindowSize(300,300);
  glutInitWindowPosition(50,50);
  glutCreateWindow("Courbe B-Spline avec tangentes");
  init();
  creationMenu();
  setParametresOrthoBasique(-5.0,5.0,-5.0,5.0,-500.0,500.0);
  setManipulateurDistance(1.0F);
  glutReshapeFunc(reshapeOrthoBasique);
  glutKeyboardFunc(key);
  glutSpecialFunc(special);
  glutMotionFunc(motionBasique);
  glutMouseFunc(sourisBasique);
  glutDisplayFunc(display);
  glutMainLoop();
  return(0);
}

Les modules utilitaires : Modules.zip

Fleche.gif (281 octets) RETOUR