/* Auteur: Nicolas JANEY */
/* nicolas.janey@univ-fcomte.fr */
/* Avril 2001 */
/* Illustration de la generation */
/* d'une courbe B-Spline par morceaux */
#include <math.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 "ModuleReshape.h"
static GLfloat pts[6][3] = {
{ 1.0,-3.0,-3.0},{-2.0,2.0,3.0},
{ 2.0,3.0,-2.0},{ -3.0,0.0,-4.0},
{ -2.0,-3.0,2.0},{ 3.0,-4.0,-1.0}};
static int aff = 0 ;
static int pt = 0 ;
static int disc = 30 ;
struct coord_3D {
GLfloat x,y,z ; } ;
struct polygone {
int n ;
coord_3D *p ; } ;
typedef float matrice[4][4] ;
void pixel(float x,float y,float z) {
glVertex3f(x,y,z);
}
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++ )
lisse(&p->p[i],n,m) ;
}
polygone pl = { 6,(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 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 < 6 ; i++ )
glVertex3fv(&pts[i][0]);
glEnd();
glPointSize(5.0);
glBegin(GL_POINTS);
for ( i = 0 ; i < 6 ; i++ ) {
glColor4fv((i == pt) ? couleurRouge() : couleurJaune());
glVertex3fv(&pts[i][0]); }
glEnd();
glColor4fv(couleurMagenta());
glPointSize(3.0);
glBegin(GL_POINTS);
b_spline(&pl,( aff ) ? m1 : m2,disc);
glEnd();
glDisable(GL_DEPTH_TEST);
for ( i = 0 ; i < 6 ; 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.8F,0.0);
simpleBitmapOutput("%s",((aff) ? "NRUBS" : "Catmull Rom"));
glPopMatrix();
glFlush();
glutSwapBuffers();
}
void myinit(void) {
glClearColor(0.0,0.0,0.0,1.0);
glMap1f(GL_MAP1_VERTEX_3,0.0,1.0,3,6,&pts[0][0]);
glEnable(GL_MAP1_VERTEX_3);
glShadeModel(GL_FLAT);
glDepthFunc(GL_LESS);
}
void special(int k, int x, int y) {
switch (k) {
case GLUT_KEY_UP : pl.p[pt].y += 0.1F;
glutPostRedisplay();
break;
case GLUT_KEY_DOWN : pl.p[pt].y -= 0.1F;
glutPostRedisplay();
break;
case GLUT_KEY_LEFT : pl.p[pt].x -= 0.1F;
glutPostRedisplay();
break;
case GLUT_KEY_RIGHT : pl.p[pt].x += 0.1F;
glutPostRedisplay();
break; }
}
void key(unsigned char key,int x,int y) {
if ( keyManipulateur(key,x,y) )
glutPostRedisplay();
else
switch ( key ) {
case 'd' : pl.p[pt].z -= 0.1F ;
glutPostRedisplay();
break;
case 'D' : pl.p[pt].z += 0.1F ;
glutPostRedisplay();
break;
case 43 : disc++ ;
glutPostRedisplay();
break;
case 45 : disc-- ;
if ( disc < 3 )
disc = 3 ;
glutPostRedisplay();
break;
case 0x0D : aff = 1-aff ;
glutPostRedisplay();
break;
case 32 : pt = pt+1 ;
if ( pt == 6 )
pt = 0 ;
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 B-Spline par morceaux");
myinit();
creationMenuBasique();
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);
}