/* Auteur: Nicolas JANEY */ /* nicolas.janey@univ-fcomte.fr */ /* Decembre 2008 */ /* Des courbes lissees */ #include #include #include #include #include #include #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); }