/* Auteur: Nicolas JANEY */ /* nicolas.janey@univ-fcomte.fr */ /* Fevrier 2019 */ /* Calcul d'une surface parametrique */ /* bicubique */ #include #include #include #include #include #include "ModuleCouleurs.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; }; typedef struct coord_3D coord_3D; typedef float matrice[4][4]; typedef float vecteur[4]; static GLfloat pts[16][4] = { {-3.0F,-3.0F,-1.0F, 1.0F },{-1.0F,-3.0F, 1.0F, 1.0F }, { 1.0F,-3.0F, 2.0F, 1.0F },{ 3.0F,-3.0F,-1.0F, 1.0F }, {-3.0F,-1.0F, 3.0F, 1.0F },{-1.0F,-1.0F, 2.0F, 1.0F }, { 1.0F,-1.0F,-1.0F, 1.0F },{ 3.0F,-1.0F, 1.0F, 1.0F }, {-3.0F, 1.0F,-1.0F, 1.0F },{-1.0F, 1.0F,-1.0F, 1.0F }, { 1.0F, 1.0F, 1.0F, 1.0F },{ 3.0F, 1.0F,-1.0F, 1.0F }, {-3.0F, 3.0F,-2.0F, 1.0F },{-1.0F, 3.0F, 1.0F, 1.0F }, { 1.0F, 3.0F, 3.0F, 1.0F },{ 3.0F, 3.0F, 1.0F, 1.0F }}; static coord_3D *points =(coord_3D *) pts; static int aff = 0; static int pt = 0; static int maille = 40; static matrice nrubs = { -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 cr = { -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 bezier = { -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); } /* ATTENTION */ /* Les produits matrice-vecteur */ /* et matrice-matrice */ /* et la transposition implantes */ /* ci-dessous necessitent */ /* que les parametres resultats */ /* soient des tableaux differents */ /* des parametres passes en entree */ void transposition(matrice m,matrice t) { for ( int i = 0 ; i < 4 ; i++ ) for ( int j = 0 ; j < 4 ; j++ ) t[i][j] = m[j][i]; } void produitMatriceMatrice(matrice m1,matrice m2,matrice m) { for ( int i = 0 ; i < 4 ; i++ ) for ( int j = 0 ; j < 4 ; j++ ) { m[i][j] = 0; for ( int k = 0 ; k < 4 ; k++ ) m[i][j] += m1[i][k]*m2[k][j]; } } void produitMatriceVecteur(matrice m,vecteur v,vecteur r) { for ( int i = 0 ; i < 4 ; i++ ) { r[i] = 0; for ( int j = 0 ; j < 4 ; j++ ) r[i] += m[i][j]*v[j]; } } void produitVecteurMatrice(vecteur v,matrice m,vecteur r) { for ( int i = 0 ; i < 4 ; i++ ) { r[i] = 0; for ( int j = 0 ; j < 4 ; j++ ) r[i] += v[j]*m[j][i]; } } float produitVecteurVecteur(vecteur v1,vecteur v2) { float r = 0; for ( int i = 0 ; i < 4 ; i++ ) r += v1[i]*v2[i]; return(r); } void bicubiquePatch(int n,matrice m,matrice mprime,coord_3D *p) { matrice tx,a,aa; matrice ty,b,bb; matrice tz,c,cc; int i; for ( i = 0 ; i < 4 ; i++ ) for ( int j = 0 ; j < 4 ; j++ ) { a[i][j] = p[i*4+j].x; b[i][j] = p[i*4+j].y; c[i][j] = p[i*4+j].z; } matrice trans; transposition(mprime,trans); produitMatriceMatrice(m,a,aa); produitMatriceMatrice(m,b,bb); produitMatriceMatrice(m,c,cc); produitMatriceMatrice(aa,trans,tx); produitMatriceMatrice(bb,trans,ty); produitMatriceMatrice(cc,trans,tz); for ( i = 0 ; i < n ; i++ ) { for ( int j = 0 ; j < n ; j++ ) { float s =(float) i/(float) (n-1); float t =(float) j/(float) (n-1); vecteur S = { s*s*s,s*s,s,1.0F }; vecteur T = { t*t*t,t*t,t,1.0F }; vecteur d; produitVecteurMatrice(S,tx,d); float x = produitVecteurVecteur(d,T); produitVecteurMatrice(S,ty,d); float y = produitVecteurVecteur(d,T); produitVecteurMatrice(S,tz,d); float z = produitVecteurVecteur(d,T); point(x,y,z); } } } void display(void) { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glPushMatrix(); glEnable(GL_DEPTH_TEST); manipulateurSouris(); manipulateurClavier(); glPointSize(3.0); glBegin(GL_POINTS); for ( int i = 0 ; i < 16 ; i++ ) { if ( i != pt ) glColor4fv(couleurJaune()); else glColor4fv(couleurRouge()); glVertex3fv(&pts[i][0]); } glEnd(); glColor4fv(couleurCyan()); glPointSize(1.0); glBegin(GL_POINTS); switch ( aff ) { case 0 : bicubiquePatch(maille,bezier,bezier,points); break; case 1 : bicubiquePatch(maille,bezier,cr,points); break; case 2 : bicubiquePatch(maille,cr,bezier,points); break; case 3 : bicubiquePatch(maille,cr,cr,points); break; case 4 : bicubiquePatch(maille,nrubs,nrubs,points); break; case 5 : bicubiquePatch(maille,nrubs,cr,points); break; case 6 : bicubiquePatch(maille,cr,nrubs,points); break; case 7 : bicubiquePatch(maille,cr,cr,points); } glEnd(); glDisable(GL_DEPTH_TEST); glPopMatrix(); glFlush(); glutSwapBuffers(); } void init(void) { glClearColor(0.0,0.0,0.0,1.0); glEnable(GL_NORMALIZE); } void key(unsigned char key,int x,int y) { if ( keyManipulateur(key,x,y) ) glutPostRedisplay(); else switch ( key ) { case 45 : maille--; if ( maille < 5 ) maille = 5; glutPostRedisplay(); break; case 43 : maille++; glutPostRedisplay(); break; case 0x0D : aff++; if ( aff == 8 ) aff = 0; glutPostRedisplay(); break; case 32 : pt = pt+1; if ( pt == 16 ) pt = 0; glutPostRedisplay(); break; } } void special(int k, int x, int y) { switch (k) { case GLUT_KEY_LEFT : points[pt].x -= 0.1F; glutPostRedisplay(); break; case GLUT_KEY_RIGHT : points[pt].x += 0.1F; glutPostRedisplay(); break; case GLUT_KEY_UP : points[pt].y += 0.1F; glutPostRedisplay(); break; case GLUT_KEY_DOWN : points[pt].y -= 0.1F; glutPostRedisplay(); break; case GLUT_KEY_PAGE_UP : points[pt].z += 0.1F; glutPostRedisplay(); break; case GLUT_KEY_PAGE_DOWN : points[pt].z += 0.1F; 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("Surface bicubique"); 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); }