/* Auteur: Nicolas JANEY */ /* nicolas.janey@univ-fcomte.fr */ /* Avril 2001 */ /* 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,y,z ; } ; typedef float matrice[4][4] ; typedef float vecteur[4] ; static GLfloat pts[16][3] = { {-3.0,-3.0,-1.0},{-1.0,-3.0, 1.0},{1.0,-3.0,2.0},{3.0,-3.0,-1.0}, {-3.0,-1.0, 3.0},{-1.0,-1.0, 2.0},{1.0,-1.0,-1.0},{3.0,-1.0, 1.0}, {-3.0, 1.0,-1.0},{-1.0, 1.0,-1.0},{1.0, 1.0, 1.0},{3.0, 1.0,-1.0}, {-3.0, 3.0,-2.0},{-1.0, 3.0, 1.0},{1.0, 3.0, 3.0},{3.0, 3.0, 1.0}} ; 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 pixel(float x,float y,float z) { glVertex3f(x,y,z); } 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) ; pixel(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 myinit(void) { glClearColor(0.0,0.0,0.0,1.0); glShadeModel(GL_FLAT); glDepthFunc(GL_LESS); glEnable(GL_AUTO_NORMAL); 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"); myinit(); 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); }