/* Auteur: Nicolas JANEY */ /* nicolas.janey@univ-fcomte.fr */ /* Fevrier 2019 */ /* Illustration de la generation */ /* d'une courbe B-Spline */ #include #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 int aff = 0; static int pt = 0; static int mode = 0; static int disc = 30; 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 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 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 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); morceauBSpline(pl.p,disc,*m); glEnd(); } if ( ( mode == 1 ) || ( mode == 2 ) ) { glColor4fv(couleurMagenta()); glBegin(GL_POINTS); morceauBSpline(pl.p,disc,*m); glEnd(); } 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); } void special(int k, int x, int y) { switch (k) { case GLUT_KEY_LEFT : pl.p[pt].x -= 0.1F; glutPostRedisplay(); break; case GLUT_KEY_RIGHT : pl.p[pt].x += 0.1F; glutPostRedisplay(); break; 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_PAGE_UP : pl.p[pt].z -= 0.1F; glutPostRedisplay(); break; case GLUT_KEY_PAGE_DOWN : pl.p[pt].z += 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; glutPostRedisplay(); break; case 0x0D : aff = (aff+1)%3; glutPostRedisplay(); break; case 'a' : mode = (mode+1)%3; 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; } } void select3(int selection) { switch (selection) { case 10 : disc = 3; glutPostRedisplay(); break; case 11 : disc = 10; glutPostRedisplay(); break; case 12 : disc = 30; glutPostRedisplay(); break; case 13 : disc = 50; glutPostRedisplay(); break; case 14 : disc = 100; glutPostRedisplay(); break; case 6 : disc++; glutPostRedisplay(); break; case 7 : disc--; if ( disc < 3 ) disc = 3; 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); 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"); 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); }