Scientific Visualization and Animation using Bezier Curves
An Introduction |
Prof. David Bernstein |
Computer Science Department |
bernstdh@jmu.edu |
GL_MAP1_VERTEX_3
)glEnable()
(e.g., glEnable(GL_MAP1_VERTEX_3)
)umin
and umax
define the range
of the parameter (usually 0 and 1)stride
is the number of values of the parameter
between curve segmentsorder
is the order of the polynomial plus 1// // Create and draw the curves for every 4 points for (int i=0; (i+3)<numPoints; i+=3) { // The evaluator with a stride of 3 and an order of 4 glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &points[i][0]); // Draw the curve glBegin(GL_POINTS); // GL_LINE_STRIP fills the gaps { for (int i=0; i<100; i++) { glEvalCoord1f(((float)i)/100.0); } } glEnd(); }
/** * The mouse callback (i.e., the function that is called * each time a mouse button is pressed or released). * * @param button The button (e.g., GLUT_LEFT_BUTTON) * @param state The state (e.g., GLUT_UP or GLUT_DOWN) * @param x The x-position of the mouse * @param y The y-position of the mouse */ void onMouseClick(int button, int state, GLfloat x, GLfloat y) { if(button == SVA_LEFT_BUTTON) { if (state == SVA_DOWN) { points[numPoints][0] = x; points[numPoints][1] = y; points[numPoints][2] = 0.; numPoints++; svaRedisplay(); } } else if (button == SVA_RIGHT_BUTTON) { if (state == SVA_DOWN) { selectedPoint = closestPointTo(x, y, 0.0); } else { selectedPoint = -1; } svaRedisplay(); } }
/** * The mouse drag callback * * @param x The x-position of the mouse * @param y The y-position of the mouse */ void onMouseDrag(GLfloat x, GLfloat y) { if (selectedPoint >= 0) { points[selectedPoint][0] = x; points[selectedPoint][1] = y; svaRedisplay(); } }
/** * Display Callback */ void onDisplay() { // Clear the screen glClear(GL_COLOR_BUFFER_BIT); // Set the color glColor3f(1.0, 0.0, 0.0); // // Create and draw the curves for every 4 points for (int i=0; (i+3)<numPoints; i+=3) { // The evaluator with a stride of 3 and an order of 4 glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &points[i][0]); // Draw the curve glBegin(GL_POINTS); // GL_LINE_STRIP fills the gaps { for (int i=0; i<100; i++) { glEvalCoord1f(((float)i)/100.0); } } glEnd(); } // Instead of: // // glBegin(GL_POINTS); // { // for (int i=0; i<100; i++) // { // glEvalCoord1f(((float)i)/100.0); // } // } // glEnd(); // // we could use: // // glMapGrid1f(100, 0.0, 1.0 ); // glEvalMesh1(GL_POINT, 0, 100); // Show the points glPointSize(3.); glBegin(GL_POINTS); { for (int i = 0; i<numPoints; i++) { if (i == selectedPoint) { glColor3f(1.0, 0.0, 1.0); glVertex3f(points[i][0], points[i][1], points[i][2]); } else { glColor3f(0.0, 1.0, 0.0); glVertex3f(points[i][0], points[i][1], points[i][2]); } } glEnd(); } // Connect the points (using a piecewise linear curve) if (numPoints >= 2) { glColor3f(0.75, 0.75, 0.75); glBegin(GL_LINE_STRIP); { for (int i = 0; i < numPoints; i++) { glVertex3f(points[i][0], points[i][1], points[i][2]); } } glEnd(); } }