#include #include #include using namespace std; /*******************************************************/ /* */ /* In this demo a catmul-rom spline is drawn. */ /* */ /* Run the program and type 'h' to see instructions */ /* on user interface. */ /********************************************************/ // function prototypes void display(void); void reshape(int width, int height); void mouse(int button, int state, int x, int y); void keyboard(unsigned char key, int x, int y); void motion(int x, int y); void init(void); void drawControlPoints(); void drawControlLine(); void drawSpline(); int height=500; int width=500; const float samples=50; float theta=0; float sx=1; float sy=1; float catmullRom[16]={-1,2,-1,0,3,-5,0,2,-3,4,1,0,1,-1,0,0}; // column major float xVal[30]; float yVal[30]; int editPoint=3; int numControlPoints=4; enum {pointEntry, pointEdit, rotate, scale, translate}; int currState=pointEdit; inline double deg2rad(float theta) {return 3.14159*(double) theta/180.0;} main(int argc, char **argv) { // set up window glutInitWindowSize(400, 400); glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutCreateWindow("Hermitian Curves"); // register callback functions glutDisplayFunc(display); glutReshapeFunc(reshape); glutMouseFunc(mouse); glutKeyboardFunc(keyboard); // initalize opengl parameters init(); keyboard('i',0,0); keyboard('h',0,0); // loop until something happens glutMainLoop(); return 0; } void init() { // initialize viewing system glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(-width/2,width/2,-height/2,height/2) ; glMatrixMode(GL_MODELVIEW); // shading model glEnable(GL_SMOOTH); // initialize background color to black glClearColor(0.0,0.0,0.0,0.0); // start with some control points for (int i=0;i<4;i++) { xVal[i]=i*10; yVal[i]=20*i; } // set point size glPointSize(5); } void reshape(int newWidth, int newHeight) { width=newWidth; height=newHeight; // preserve aspect ratio if (newWidth < newHeight) glViewport(0,0,newWidth,newWidth); else glViewport(0,0,newHeight,newHeight); } void display() { // clear buffers glClear(GL_COLOR_BUFFER_BIT ); // clear modelview matrix glLoadIdentity(); // draw axis glColor3f(1,1,1); glBegin(GL_LINES); glVertex2f(-width,0); glVertex2f(width,0); glVertex2f(0,height); glVertex2f(0,-height); glEnd(); // draw line connecting control points drawControlLine(); drawSpline(); // draw control points drawControlPoints(); glPopMatrix(); // draw to screen glutSwapBuffers(); } void drawControlLine() { // draw line connecting control points glColor3f(0.5,0.5,0.5); glBegin(GL_LINE_STRIP); for (int i=0; i4) { numControlPoints--; if (editPoint == numControlPoints) editPoint--; glutPostRedisplay(); } break; case 'h': case 'H': cout << "Right click to add new control point." << endl; cout << "Left click and drag to move an existing control point." << endl; cout << "Enter 'd' to delete the last control point added." << endl; break; case 'i': case 'I': cout << "This program lets you builds a catmull-rom spline." << endl; break; default: break; } } void mouse(int button, int state, int x, int y) { int i; float fx, fy; double d, dx, dy; double distance; fx=(float)(x*500.0)/(float) width -250.0; fy=(float) (height-y)*500.0/(float) height -250.0; // entering new points if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) { xVal[numControlPoints]=fx; yVal[numControlPoints]=fy; editPoint = numControlPoints; numControlPoints++; glutPostRedisplay(); return; } // choose new point to edit if (button==GLUT_LEFT_BUTTON && state==GLUT_DOWN) { // find control point to move d=(double) 2*(width+height); editPoint=-1; for (i=0;i distance) { d=distance; editPoint=i; } } glutPostRedisplay(); glutMotionFunc(motion); } // turn off editing if (button==GLUT_LEFT_BUTTON && state==GLUT_UP) { glutMotionFunc(NULL); } return; } void motion(int x, int y) { float fx, fy; fx=(float)(x*500.0)/(float) width -250.0; fy=(float) (height-y)*500.0/(float) height -250.0; xVal[editPoint]=fx; yVal[editPoint]=fy; glutPostRedisplay(); }