?? curves.c
字號:
/* curves.c */
/* E. Angel, Interactive Computer Graphics */
/* A Top-Down Approach with OpenGL, Third Edition */
/* Addison-Wesley Longman, 2003 */
/***** Simple interactive curve drawing program.**** The following keyboard commands are used to control the** program:**** q - Quit the program** c - Clear the screen** e - Erase the curves** b - Draw Bezier curves** i - Draw interpolating curves** s - Draw B-spline curves***/
/* All control points are converted to Bezier
control point to allow use of OpenGL evaluators */
#include <GL/glut.h>typedef enum{ BEZIER, INTERPOLATED, BSPLINE} curveType;void keyboard(unsigned char key, int x, int y);void computeMatrix(curveType type, float m[4][4]);void vmult(float m[4][4], float v[4][3], float r[4][3]);/* Colors to draw them in */GLfloat colors[][3] ={ { 1.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }, { 0.0, 0.0, 1.0 }};#define MAX_CPTS 25 /* Fixed maximum number of control points */GLfloat cpts[MAX_CPTS][3];int ncpts = 0;static int width = 500, height = 500; /* Window width and height *//* Matrix stuff *//* This routine multiplies two 4 x 4 matrices. *//* This routine multiplies a 4 x 4 matrix with a vector of 4 points. */void vmult(float m[4][4], float v[4][3], float r[4][3]){ int i, j, k; for (i = 0; i < 4; i++) for (j = 0; j < 3; j++) for (k = 0, r[i][j] = 0.0; k < 4; k++) r[i][j] += m[i][k] * v[k][j];}/* Interpolating to Bezier matrix */static float minterp[4][4] = { { 1.0, 0.0, 0.0, 0.0 }, { -5.0/6.0, 3.0, -3.0/2.0, 1.0/3.0 }, { 1.0/3.0, -3.0/2.0, 3.0, -5.0/6.0 }, { 0.0, 0.0, 0.0, 1.0 }, };/* B-spline to Bezier matrix */static float mbspline[4][4] = { { 1.0/6.0, 4.0/6.0, 1.0/6.0, 0.0 }, { 0.0, 4.0/6.0, 2.0/6.0, 0.0 }, { 0.0, 2.0/6.0, 4.0/6.0, 0.0 }, { 0.0, 1.0/6.0, 4.0/6.0, 1.0/6.0 },};static float midentity[4][4] ={ { 1.0, 0.0, 0.0, 0.0}, { 0.0, 1.0, 0.0, 0.0}, { 0.0, 0.0, 1.0, 0.0}, { 0.0, 0.0, 0.0, 1.0}};/* Calculate the matrix used to transform the control points */void computeMatrix(curveType type, float m[4][4]){ int i, j; switch (type) { case BEZIER: /* Identity matrix */ for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) m[i][j] = midentity[i][j]; break; case INTERPOLATED: for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) m[i][j] = minterp[i][j]; break; case BSPLINE: for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) m[i][j] = mbspline[i][j]; break; }}/* Draw the indicated curves using the current control points. */static void drawCurves(curveType type){ int i; int step; GLfloat newcpts[4][3]; float m[4][4]; /* Set the control point computation matrix and the step size. */ computeMatrix(type, m); if(type == BSPLINE) step = 1; else step = 3; glColor3fv(colors[type]); /* Draw the curves */ i = 0; while (i + 3 < ncpts) { /* Calculate the appropriate control points */ vmult(m, &cpts[i], newcpts); /* Draw the curve using OpenGL evaluators */ glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &newcpts[0][0]); glMapGrid1f(30, 0.0, 1.0); glEvalMesh1(GL_LINE, 0, 30); /* Advance to the next segment */ i += step; } glFlush();}/* This routine displays the control points */static void display(void){ int i; glClear(GL_COLOR_BUFFER_BIT); glColor3f(0.0, 0.0, 0.0); glPointSize(5.0); glBegin(GL_POINTS); for (i = 0; i < ncpts; i++) glVertex3fv(cpts[i]); glEnd(); glFlush();}/* This routine inputs new control points */static void mouse(int button, int state, int x, int y){ float wx, wy; /* We are only interested in left clicks */ if (button != GLUT_LEFT_BUTTON || state != GLUT_DOWN) return; /* Translate back to our coordinate system */ wx = (2.0 * x) / (float)(width - 1) - 1.0; wy = (2.0 * (height - 1 - y)) / (float)(height - 1) - 1.0; /* See if we have room for any more control points */ if (ncpts == MAX_CPTS) return; /* Save the point */ cpts[ncpts][0] = wx; cpts[ncpts][1] = wy; cpts[ncpts][2] = 0.0; ncpts++; /* Draw the point */ glColor3f(0.0, 0.0, 0.0); glPointSize(5.0); glBegin(GL_POINTS); glVertex3f(wx, wy, 0.0); glEnd(); glFlush();}/* This routine handles keystroke commands */void keyboard(unsigned char key, int x, int y){ static curveType lasttype = BEZIER; switch (key) { case 'q': case 'Q': exit(0); break; case 'c': case 'C': ncpts = 0; glutPostRedisplay(); break; case 'e': case 'E': glutPostRedisplay(); break; case 'b': case 'B': drawCurves(BEZIER); lasttype = BEZIER; break; case 'i': case 'I': drawCurves(INTERPOLATED); lasttype = INTERPOLATED; break; case 's': case 'S': drawCurves(BSPLINE); lasttype = BSPLINE; break; }}/* This routine handles window resizes */void reshape(int w, int h){ width = w; height = h; /* Set the transformations */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); glMatrixMode(GL_MODELVIEW); glViewport(0, 0, w, h);}main(int argc, char **argv){ /* Intialize the program */ glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB); glutInitWindowSize(width, height); glutCreateWindow("curves"); /* Register the callbacks */ glutDisplayFunc(display); glutMouseFunc(mouse); glutKeyboardFunc(keyboard); glutReshapeFunc(reshape); glClearColor(1.0, 1.0, 1.0, 1.0); glEnable(GL_MAP1_VERTEX_3); glutMainLoop();}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -