/* Auteur: Nicolas JANEY */ /* nicolas.janey@univ-fcomte.fr */ /* Fevrier 2019 */ /* Illustration de la generation */ /* d'une courbe B-Spline par morceaux */ #include #include #include #include #include #include "ModuleCouleurs.h" #include "ModuleFont.h" #include "ModuleManipulateur.h" #include "ModuleMenus.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[6][4] = { { 1.0F,-3.0F,-3.0F, 1.0F }, { -2.0F, 2.0F, 3.0F, 1.0F }, { 2.0F, 3.0F,-2.0F, 1.0F }, { -3.0F, 0.0F,-4.0F, 1.0F }, { -2.0F,-3.0F, 2.0F, 1.0F }, { 3.0F,-4.0F,-1.0F, 1.0F } }; static int aff = 0; static int pt = 0; static int disc = 30; void point(float x,float y,float z) { glVertex3f(x,y,z); } void morceauBSpline(coord_3D *p,int n,matrice m) { int j,k; float tt[4],ttt[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; 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; } point(x,y,z); } } void b_spline(polygone *p,matrice m,int n) { for ( int i = 0 ; i < p->n-3 ; i++ ) morceauBSpline(&p->p[i],n,m); } 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}; 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 init(void) { glClearColor(0.0,0.0,0.0,1.0); } 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) { pl.n = 6; 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 par morceaux"); init(); 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); }