logo资料库

OpenGL B样条曲线.doc

第1页 / 共14页
第2页 / 共14页
第3页 / 共14页
第4页 / 共14页
第5页 / 共14页
第6页 / 共14页
第7页 / 共14页
第8页 / 共14页
资料共14页,剩余部分请下载后查看
实验八 曲线绘制 一、实验目的 1、掌握 Bezier 曲线的绘制; 2、掌握 B 样条曲线的绘制。 二、实验要求 1、通过菜单完成两种曲线的绘制: 1. Bezier 曲线(三次或四次) 2. B 样条曲线(二次或三次) 3. 退出 2、任意绘制带有曲线的二维图形或三维图形。 三、实验代码 Bezier #include #include #include static GLfloat v[4][2]; static GLfloat width = 600, height = 600; static GLfloat mousex; static GLfloat mousey; static int count = 0; void Init(){ glClearColor(1.0f, 1.0f, 1.0f, 0.0f); //设置背景颜色 } void Reshape(GLsizei w, GLsizei h){ glViewport(0, 0, w, h); width = w; height = h; glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, w, 0, h, -1.0, 1.0);
glutPostRedisplay(); } void bezier(GLfloat vv[4][2], int i){ if (i == 0){ glColor3f(0.0, 0.0, 0.0); glBegin(GL_LINE_STRIP); glVertex2i(vv[0][0], vv[0][1]); glVertex2i(vv[1][0], vv[1][1]); glVertex2i(vv[2][0], vv[2][1]); glVertex2i(vv[3][0], vv[3][1]); glEnd(); } else{ i--; int j; GLfloat l[4][2]; GLfloat r[4][2]; for (j = 0;j<2;j++){ l[0][j] = vv[0][j]; r[3][j] = vv[3][j]; l[1][j] = (vv[0][j] + vv[1][j]) / 2; r[2][j] = (vv[2][j] + vv[3][j]) / 2; l[2][j] = (l[1][j] + (vv[1][j] + vv[2][j]) / 2) / 2; r[1][j] = (r[2][j] + (vv[1][j] + vv[2][j]) / 2) / 2; l[3][j] = (l[2][j] + r[1][j]) / 2; r[0][j] = l[3][j]; } bezier(l, i); bezier(r, i); } } void mydisplay(){ glClearColor(1.0, 1.0, 1.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); if (count>1){ glBegin(GL_LINES); glColor3f(0.0, 1.0, 0.0); glVertex2f(v[0][0], v[0][1]); glColor3f(0.0, 0.0, 1.0); glVertex2f(v[1][0], v[1][1]); glEnd();
} if (count>2){ glBegin(GL_LINES); glColor3f(1.0, 1.0, 0.0); glVertex2f(v[1][0], v[1][1]); glColor3f(0.0, 0.0, 1.0); glVertex2f(v[2][0], v[2][1]); glEnd(); } if (count>3){ glBegin(GL_LINES); glColor3f(1.0, 0.0, 1.0); glVertex2f(v[2][0], v[2][1]); glColor3f(0.0, 0.0, 1.0); glVertex2f(v[3][0], v[3][1]); glEnd(); } if ((count>0) && (count<4)){ glBegin(GL_LINES); glColor3f(0.6, 0.4, 0.7); glVertex2f(v[count - 1][0], v[count - 1][1]); glColor3f(0.0, 0.0, 1.0); glVertex2f(mousex, mousey); glEnd(); } else if (count == 4){ GLint vv[4][2]; for (int i = 0;i<4;i++){ vv[i][0] = v[i][0]; vv[i][1] = v[i][1]; } bezier(v, 5); } glutSwapBuffers(); glFlush(); } void mymouse(int button, int state, int xx, int yy) { if ((button == GLUT_LEFT_BUTTON) && (state == GLUT_DOWN)) { if (count<4) {
v[count][0] = xx; v[count][1] = height - yy; glutPostRedisplay(); count++; } } if ((button == GLUT_RIGHT_BUTTON) && (state == GLUT_DOWN)) count = 0; glutPostRedisplay(); { } } void mypassive(int xx, int yy) { } mousex = xx; mousey = height - yy; if ((count>0) && (count<4)) glutPostRedisplay(); int main(int argc, char** argv) { } glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE); glutInitWindowSize(680, 680); glutInitWindowPosition(340,-340); glutInit(&argc, argv); glutCreateWindow("Bezier"); glutDisplayFunc(mydisplay); glutReshapeFunc(Reshape); glutMouseFunc(mymouse); glutPassiveMotionFunc(mypassive); glutMainLoop(); return 0; B 样条曲线 #include #include #include #include
#include using namespace std; bool mouseRightIsDown = false; void Init() { glClearColor(1.0f, 1.0f, 1.0f, 0.0f); //设置背景颜色 } void Reshape(int w, int h) //两个参数:窗口被移动后大小 { } glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0, w, h, 0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); struct Point { int x, y; Point() {}; Point(int tx, int ty) { } x = tx; y = ty; }; vector p; double getRatio(double t, double a, double b, double c, double d) { } return a * pow(t, 3) + b * pow(t, 2) + c * t + d; double caculateSquarDistance(Point a, Point b) { } return (a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y); int getIndexNearByMouse(int x, int y) { double precision = 200; int index = -1; double Min;
for (int i = 0; i < p.size(); i++) { double dis = caculateSquarDistance(p[i], Point(x, y)); if (dis < precision) { if (index == -1) { } index = i; Min = dis; else if (dis < Min) { } index = i; Min = dis; } } return index; } void Blines(Point a, Point b, Point c, Point d) { int n = 500; double derta = 1.0 / n; glPointSize(2); glColor3f(0.0, 1.0, 0.0); glBegin(GL_LINE_STRIP); for (int i = 0; i <= n; i++) { double t = derta * i; double ratio[4]; ratio[0] = getRatio(t, -1, 3, -3, 1); ratio[1] = getRatio(t, 3, -6, 0, 4); ratio[2] = getRatio(t, -3, 3, 3, 1); ratio[3] = getRatio(t, 1, 0, 0, 0); double x = 0, y = 0; x += ratio[0] * a.x + ratio[1] * b.x + ratio[2] * c.x + ratio[3] * d.x; y += ratio[0] * a.y + ratio[1] * b.y + ratio[2] * c.y + ratio[3] * d.y; x /= 6.0; y /= 6.0; glVertex2d(x, y); } glEnd(); } void myDisplay()
{ glClear(GL_COLOR_BUFFER_BIT); glPointSize(5); glColor3f(0.0, 0.0, 1.0); glBegin(GL_POINTS); for (int i = 0; i < p.size(); i++) glVertex2d(p[i].x, p[i].y); glEnd(); //画线 glLineWidth(2); glColor3f(1.0, 1.0, 0.0); glBegin(GL_LINE_STRIP); for (int i = 0; i < p.size(); i++) glVertex2d(p[i].x, p[i].y); glEnd(); if (p.size() >= 4) for (int i = 0; i < p.size() - 3; i++) Blines(p[i], p[i + 1], p[i + 2], p[i + 3]); glFlush(); } void keyboard(unsigned char key, int x, int y) { } if (key == GLUT_KEY_LEFT) exit(0); if (key == GLUT_KEY_RIGHT) //退格键 { } int index = getIndexNearByMouse(x, y); if (index == -1) return; p.erase(p.begin() + index); glutPostRedisplay(); void mouse(int button, int state, int x, int y) { if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { } Point t(x, y); p.push_back(t); glutPostRedisplay();
if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) mouseRightIsDown = true; if (button == GLUT_RIGHT_BUTTON && state == GLUT_UP) mouseRightIsDown = false; } void motion(int x, int y) { } if (mouseRightIsDown) { } int index = getIndexNearByMouse(x, y); if (index == -1) return; p[index].x = x; p[index].y = y; glutPostRedisplay(); int main(int argc, char *argv[]) { glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE); glutInitWindowSize(680, 680); glutInitWindowPosition(340, -340); glutInit(&argc, argv); glutCreateWindow("B"); Init(); glutDisplayFunc(myDisplay); glutReshapeFunc(Reshape); glutMouseFunc(mouse); glutMotionFunc(motion); glutKeyboardFunc(keyboard); glutMainLoop(); return 0; } 曲线图: #include #include #include #include #include
分享到:
收藏