/* Auteur: Nicolas JANEY */ /* nicolas.janey@univ-fcomte.fr */ /* Fevrier 2019 */ /* Assemblage de deux courbes */ /* de Bezier a quatre sommets */ #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 GLfloat pts[7][4] = { { -4.0F,-2.0F, 4.0F, 1.0F }, { -7.0F, 0.0F, 2.0F, 1.0F}, { -2.0F, 3.0F,-2.0F, 1.0F}, { -1.0F, 0.0F,-1.0F, 1.0F}, { 0.0F,-3.0F, 0.0F, 1.0F}, { 3.0F,-4.0F,-4.0F, 1.0F}, { 5.0F, 2.0F, 4.0F, 1.0F}}; static int pt = 0; static int mode = 0; static int disc = 30; static matrice mbezier = { -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 polygone pl1; static polygone pl2; void point(float x,float y,float z) { glVertex3f(x,y,z); } void tangente(coord_3D *p,int n,matrice m,float t,float *tx,float *ty,float *tz) { int j,k; float tt[3],ttt[4],x,y,z; tt[0] = 3*t*t; tt[1] = 2*t; tt[2] = 1.0F; for ( j = 0 ; j < 4 ; j++ ) for ( k = 0,ttt[j] = 0 ; k < 3 ; 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; } float d =(float) pow((double) (x*x+y*y+z*z),0.5); *tx = x/d; *ty = y/d; *tz = z/d; } void morceauBezier(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 < 7 ; i++ ) glVertex3fv(&pts[i][0]); glEnd(); glPointSize(5.0); glBegin(GL_POINTS); for ( i = 0 ; i < 7 ; i++ ) { glColor4fv((i == pt) ? couleurRouge() : couleurJaune()); glVertex3fv(&pts[i][0]); } glEnd(); glPointSize(3.0); if ( ( mode == 0 ) || ( mode == 2 ) ) { glColor4fv(couleurCyan()); glBegin(GL_LINE_STRIP); morceauBezier(pl1.p,disc,mbezier); glEnd(); glBegin(GL_LINE_STRIP); morceauBezier(pl2.p,disc,mbezier); glEnd(); } if ( ( mode == 1 ) || ( mode == 2 ) ) { glColor4fv(couleurMagenta()); glBegin(GL_POINTS); morceauBezier(pl1.p,disc,mbezier); glEnd(); glBegin(GL_POINTS); morceauBezier(pl2.p,disc,mbezier); glEnd(); } glDisable(GL_DEPTH_TEST); for ( i = 0 ; i < 7 ; 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(); float xmin = getXmin(); float ymin = getYmin(); float ymax = getYmax(); float tpix = getTaillePixel(); setAntialiased(1); setBold(1); setEcartementCaracteres(25.0F); glPushMatrix(); glColor4fv(couleurBlanc()); strokeOutput(xmin+0.1F,ymax-0.7F,1.0F,"V1: %f %f %f",pts[3][0]-pts[2][0],pts[3][1]-pts[2][1],pts[3][2]-pts[2][2]); strokeOutput(xmin+0.1F,ymax-1.7F,1.0F,"V2: %f %f %f",pts[4][0]-pts[3][0],pts[4][1]-pts[3][1],pts[4][2]-pts[3][2]); float tx; float ty; float tz; tangente(pl1.p,disc,mbezier,1.0F,&tx,&ty,&tz); strokeOutput(xmin+0.1F,ymin+1.5F,1.0F,"T1: %f %f %f",tx,ty,tz); tangente(pl2.p,disc,mbezier,0.0F,&tx,&ty,&tz); strokeOutput(xmin+0.1F,ymin+0.5F,1.0F,"T2: %f %f %f",tx,ty,tz); glPopMatrix(); setAntialiased(0); setBold(0); setEcartementCaracteres(0.0F); 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 : pts[pt][0]-= 0.1F; glutPostRedisplay(); break; case GLUT_KEY_RIGHT : pts[pt][0] += 0.1F; glutPostRedisplay(); break; case GLUT_KEY_UP : pts[pt][1] += 0.1F; glutPostRedisplay(); break; case GLUT_KEY_DOWN : pts[pt][1] -= 0.1F; glutPostRedisplay(); break; case GLUT_KEY_PAGE_UP : pts[pt][2] -= 0.1F; glutPostRedisplay(); break; case GLUT_KEY_PAGE_DOWN : pts[pt][2] += 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 'a' : mode = (mode+1)%3; glutPostRedisplay(); break; case 32 : pt = (pt+1)%4; 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 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("Affichage",menu2); glutAddSubMenu("Discretisation",menu3); glutAddMenuEntry("Quitter",0); glutAttachMenu(GLUT_RIGHT_BUTTON); } int main(int argc,char **argv) { pl1.n = 4; pl1.p =(coord_3D *) &pts[0][0]; pl2.n = 4; pl2.p =(coord_3D *) &pts[3][0]; glutInit(&argc,argv); glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE); glutInitWindowSize(300,300); glutInitWindowPosition(50,50); glutCreateWindow("Assemblage de courbes de Bezier"); init(); creationMenu(); setParametresOrthoBasique(-8.0,8.0,-8.0,8.0,-100.0,100.0); setManipulateurDistance(1.0F); glutReshapeFunc(reshapeOrthoBasique); glutKeyboardFunc(key); glutSpecialFunc(special); glutMotionFunc(motionBasique); glutMouseFunc(sourisBasique); glutDisplayFunc(display); glutMainLoop(); return(0); }