B-Splines de Bezier
B-Splines non rationnelles uniformes et de Catmull-Rom
B-Splines de Catmull-Rom et B-Splines non rationnelles uniformes
La méthode fonctionne.
B-Splines de Bézier
La méthode ne fonctionne pas.
/* Auteur: Nicolas JANEY */
/* nicolas.janey@univ-fcomte.fr */
/* Novembre 2007 */
/* Trace de B-Splines */
#include <stdio.h>
#include <stdlib.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
/* Variables et constantes globales */
static int solution = 0;
static int disc = 25;
static int mode = 0;
static int el = 0;
static int mat = 2;
/* Variables globales de gestion */
/* de l'interactivite clavier et souris */
static int clic = 0;
static int mx;
static int my;
static float rx = 0.0F;
static float ry = 0.0F;
/* Type de stockage d'une position */
typedef struct position {
double x;
double y;
double z;
double t; } position;
/* Type de stockage d'une matrice de base */
typedef double matriceDeBase[4][4];
/* Type de stockage d'une ligne polygonale */
typedef struct lignePolygonale {
int n;
position *pts; } lignePolygonale;
/* Donnees statiques constantes */
static const float blanc[] = { 1.0F,1.0F,1.0F,1.0F };
static const float rouge[] = { 1.0F,0.0F,0.0F,1.0F };
static const float vert[] = { 0.0F,1.0F,0.0F,1.0F };
static const float bleu[] = { 0.0F,0.0F,1.0F,1.0F };
static const float jaune[] = { 1.0F,1.0F,0.0F,1.0F };
static const float cyan[] = { 0.0F,1.0F,1.0F,1.0F };
static const float magenta[] = { 1.0F,0.0F,1.0F,1.0F };
static const float c1[] = { 0.3F,0.5F,0.7F,1.0F };
static const float c2[] = { 0.5F,0.7F,0.3F,1.0F };
static const float c3[] = { 0.7F,0.3F,1.5F,1.0F };
static const float *couleurs[10] = { rouge,vert,
bleu,cyan,
jaune,c3,
magenta,c1,
c2,blanc };
/* Donnees statiques */
static matriceDeBase mBNRU =
{ { -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 matriceDeBase mBCR =
{ { -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 matriceDeBase mBB =
{ { -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 } };
static matriceDeBase *mb = &mBB;
static position p1[10] =
{ { -6.0,-1.0, 5.0, 1.0 },
{ -1.0,-6.0,-4.0, 1.0 },
{ 3.0,-4.0, 1.0, 1.0 },
{ 6.0,-1.0, 0.0, 1.0 },
{ 5.0, 3.0,-2.0, 1.0 },
{ 1.0, 6.0, 4.0, 1.0 },
{ -1.0, 2.0, 1.0, 1.0 },
{ -4.0, 2.0, 2.0, 1.0 },
{ -5.0, 6.0,-3.0, 1.0 },
{ -2.0, 5.0,-6.0, 1.0 } };
static lignePolygonale lp = { 10,p1 };
/* Fonction de calcul du tableau de positions */
/* d'evaluation d'une B-Spline cree */
/* entre quatre positions */
position *calculBSpline(matriceDeBase m,position *pts,int n) {
position *p =(position *) calloc(n,sizeof(position));
for ( int i = 0 ; i < n ; i++ ) {
double t =(double) i/(n-1);
double tt[4] = { t*t*t,t*t,t,1.0 };
double tn[4] = { 0.0,0.0,0.0,0.0 };
int j;
for ( j = 0 ; j < 4 ; j++ )
for ( int k = 0 ; k < 4 ; k++ )
tn[j] += tt[k]*m[k][j];
for ( j = 0 ; j < 4 ; j++ ) {
p[i].x += tn[j]*pts[j].x;
p[i].y += tn[j]*pts[j].y;
p[i].z += tn[j]*pts[j].z; }
p[i].t = 1.0; }
return(p);
}
/* Fonction d'initialisation des parametres */
/* OpenGL ne changeant pas au cours de la vie */
/* du programme */
void init(void) {
glClearColor(0.0,0.0,0.0,0.0);
}
void dessine(position *p,int n) {
glPushMatrix();
glBegin(GL_LINE_STRIP);
for ( int i = 0 ; i < n ; i++ )
glVertex3dv((double *) &p[i]);
glEnd();
glPopMatrix();
}
void solutionQuestionA(void) {
switch (mode) {
case 0 :
case 1 :
case 2 : position *p = calculBSpline(*mb,&p1[el],disc);
glColor4fv(vert);
dessine(p,disc);
free(p);
glColor4fv(blanc);
dessine(&p1[el],4);
break; }
}
void solutionQuestionB(void) {
int i;
switch (mode) {
case 0 : glColor4fv(blanc);
dessine(lp.pts,lp.n);
break;
case 1 : glColor4fv(blanc);
dessine(lp.pts,lp.n);
glColor4fv(vert);
for ( i = 0 ; i < lp.n-3 ; i++ ) {
position *p = calculBSpline(*mb,&lp.pts[i],disc);
dessine(p,disc);
free(p); }
break;
case 2 : glColor4fv(blanc);
dessine(lp.pts,lp.n);
for ( i = 0 ; i < lp.n-3 ; i++ ) {
glColor4fv(couleurs[i]);
position *p = calculBSpline(*mb,&lp.pts[i],disc);
dessine(p,disc);
free(p); }
break; }
}
/* Scene dessinee */
void scene(void) {
glPushMatrix();
switch (solution) {
case 0 : solutionQuestionA();
break;
case 1 : solutionQuestionB();
break; }
glPopMatrix();
}
/* Fonction executee lors d'un rafraichissement */
/* de la fenetre de dessin */
void display(void) {
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);
scene();
glPopMatrix();
glFlush();
glutSwapBuffers();
}
/* Fonction executee lors de la frappe */
/* d'une touche alphanumerique du clavier */
void key(unsigned char key,int x,int y) {
switch ( key ) {
case 43 : disc++;
glutPostRedisplay();
break;
case 45 : disc--;
if ( disc < 2 )
disc = 2;
glutPostRedisplay();
break;
case 'a' : el = (el+1)%7;
glutPostRedisplay();
break;
case 'm' : mat =(mat+1)%3;
switch ( mat ) {
case 0 : mb = &mBCR;
break;
case 1 : mb = &mBNRU;
break;
case 2 : mb = &mBB;
break;}
glutPostRedisplay();
break;
case 0x20 : mode = (mode+1)%3;
glutPostRedisplay();
break;
case 0x0D : solution = (solution+1)%2;
glutPostRedisplay();
break;
case 0x1B : exit(0);
break; }
}
/* Fonction executee lors d'un clic de souris */
/* dans la fenetre */
void mouse(int bouton,int etat,int x,int y) {
if ( bouton == GLUT_LEFT_BUTTON ) {
if ( etat == GLUT_DOWN ) {
clic = 1;
mx = x;
my = y; }
if ( etat == GLUT_UP ) {
clic = 0; } }
}
/* Fonction executee lors d'un deplacement */
/* de la souris sur la fenetre */
/* avec un bouton appuye */
void motion(int x,int y) {
if ( clic ) {
ry += (x-mx);
rx += (y-my);
mx = x;
my = y;
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();
glOrtho(-8.0,8.0,(double) -8.0*y/x,(double) 8.0*y/x,-8.0,8.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
/* Fonction principale */
int main(int argc,char **argv) {
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
glutInitWindowSize(300,300);
glutInitWindowPosition(50,50);
glutCreateWindow("Dessin de B-Splines");
init();
glutReshapeFunc(reshape);
glutKeyboardFunc(key);
glutMotionFunc(motion);
glutMouseFunc(mouse);
glutDisplayFunc(display);
glutMainLoop();
return(0);
}