#include #include #include /* * interp.c: cubic interpolating polynomial curve * * Of necessity, this is 2D. * * All calcs are 3d, though. * * 3/31/03 pjf * */ GLfloat p[4][3] = { { -0.5, 0.0, 0.0 }, {-0.15, -0.5, 0.0 }, { 0.15, 0.5, 0.0 }, { 0.5, 0.0, 0.0 }}; int ww,hh; float b0(float u) { return -4.5 * (u-0.333) * (u - 0.666) * (u-1.0); } float b1(float u) { return 13.5 * u * (u-0.666) * (u-1.0); } float b2(float u) { return -13.5 * u * (u-0.333) * (u-1.0); } float b3(float u) { return 4.5 * u * (u-0.333) * (u-0.666); } /* display callback */ void display() { float u; int i; glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0,1.0,1.0); glBegin(GL_LINE_STRIP); for (u=0.0;u<=1.0;u+=0.001) { GLfloat x = b0(u)*p[0][0] + b1(u)*p[1][0] + b2(u)*p[2][0] + b3(u)*p[3][0]; GLfloat y = b0(u)*p[0][1] + b1(u)*p[1][1] + b2(u)*p[2][1] + b3(u)*p[3][1]; GLfloat z = b0(u)*p[0][2] + b1(u)*p[1][2] + b2(u)*p[2][2] + b3(u)*p[3][2]; glVertex3f(x,y,z); } glEnd(); // now draw boxes around control points glColor3f(1.0,0.3,0.3); for (i=0;i<4;i++) { GLfloat x = p[i][0] - 0.02; GLfloat y = p[i][1] - 0.02; GLfloat z = p[i][2]; glBegin(GL_LINE_LOOP); glVertex3f(x,y,z); glVertex3f(x+0.04,y,z); glVertex3f(x+0.04,y+0.04,z); glVertex3f(x,y+0.04,z); glEnd(); } glFlush(); } int curcp = -1; /* mouse: called when a mouse button is pressed or released. btn identifies which button; state identifies "press" or "release" */ void mouse(int btn, int state, int x, int y) { //fprintf(stderr,"mouse: btn %d, state %d, location (%d,%d).\n",btn,state,x,y); if (state==GLUT_UP) { // up curcp = -1; } else { int i; float xmouse=2.0*x/ww - 1.0; float ymouse=2.0*(hh-y)/hh - 1.0; float zmouse=0.0; //fprintf(stderr,"Mousedown @ %f %f\n",xmouse,ymouse); float d; for(i=0;i<4;i++) { float d=(xmouse-p[i][0])*(xmouse-p[i][0]) + (ymouse-p[i][1])*(ymouse-p[i][1]) + (zmouse-p[i][2])*(zmouse-p[i][2]); if (d<0.007) break; }; if (i<4) { // valid hit curcp = i; }; } } /* called initially (before first call to display()) and whenever the window is resized */ void reshape(int w, int h) { fprintf(stderr,"reshape: new size %d x %d.\n",w,h); // must update viewport and clipping planes glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); ww=w; hh=h; } void motion(int x, int y) { float xmouse=2.0*x/ww - 1.0; float ymouse=2.0*(hh-y)/hh - 1.0; float zmouse = 0.0; //fprintf(stderr,"Motion: loc (%d %d).\n",x,y); //fprintf(stderr,"Motion @ %f %f\n",xmouse,ymouse); if (curcp == -1) return; p[curcp][0] = xmouse; p[curcp][1] = ymouse; p[curcp][2] = zmouse; glutPostRedisplay(); } void init(void) { /* nothing to do! */ } int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB); glutInitWindowSize(500, 500); glutCreateWindow(argv[0]); glutReshapeFunc(reshape); glutDisplayFunc(display); glutMouseFunc(mouse); glutMotionFunc(motion); init(); glutMainLoop(); return 0; }