1. 来源
三次贝塞尔曲线就是依据四个位置任意的点坐标绘制出的一条光滑曲线
2. 公式
3. 实现
1 #include <iostream> 2 #include <math.h> 3 #include <GL/gl.h> 4 #include <GL/glut.h> 5 #include <vector> 6 //#include <pair> 7 8 using namespace std; 9 10 //points保存四个点 11 vector<pair<GLfloat, GLfloat> > points; 12 //设置两个bool变量来记录是否已经画出四个点之间的直线,以及相关贝塞尔曲线 13 bool line = false; 14 bool curve = false; 15 16 //画直线 17 void drawLine() { 18 glColor3f(1.0f, 0, 0); 19 glPointSize(1.0); 20 for (int i = 0; i <= 2; i ++) { 21 glBegin(GL_LINES); 22 glVertex2f(points[i].first, points[i].second); 23 glVertex2f(points[i+1].first, points[i+1].second); 24 glEnd(); 25 } 26 } 27 28 //贝塞尔曲线 29 void drawCurve() { 30 glColor3f(0, 1.0f, 0); 31 glPointSize(1.0); 32 for (GLfloat t = 0; t <= 1.0; t += 0.001) { 33 GLfloat x = points[0].first*pow(1.0f-t, 3) + 3*points[1].first*t*pow(1.0f-t, 2) + 3*points[2].first*t*t*(1.0f-t) + points[3].first*pow(t, 3); 34 GLfloat y = points[0].second*pow(1.0f-t, 3) + 3*points[1].second*t*pow(1.0f-t, 2) + 3*points[2].second*t*t*(1.0f-t) + points[3].second*pow(t, 3); 35 glBegin(GL_POINTS); 36 glVertex2f(x, y); 37 glEnd(); 38 } 39 } 40 41 //初始化函数 42 void myInit() { 43 glClearColor(0, 0, 0, 0); 44 glColor3f(1.0f, 0, 0); 45 glPointSize(5.0); 46 glMatrixMode(GL_MODELVIEW); 47 glLoadIdentity(); 48 gluOrtho2D(0.0, 500, 0.0, 500); 49 } 50 51 void myDisplay() { 52 glClear(GL_COLOR_BUFFER_BIT); 53 glFlush(); 54 } 55 56 //对于鼠标点击的响应函数 57 void myMouse(int button, int state, int x, int y) 58 { 59 //按下鼠标左键 60 if(state==GLUT_DOWN) 61 { 62 //画4个点 63 if (points.size() < 4) { 64 glBegin(GL_POINTS); 65 glVertex2i(x, 500 - y); 66 glEnd(); 67 points.push_back(make_pair(GLfloat(x), GLfloat(500 - y))); 68 } 69 //若已经画好四个点,则开始画点连成的线段曲线 70 else if (points.size() == 4) { 71 //线段 72 if (line == false) { 73 drawLine(); 74 line = true; 75 } 76 //曲线 77 else if (line == true && curve == false) { 78 drawCurve(); 79 curve = true; 80 } 81 //清空 82 else if (line == true && curve == true) { 83 glClear(GL_COLOR_BUFFER_BIT); 84 glColor3f(1.0f, 0, 0); 85 glPointSize(5.0); 86 line = false; 87 curve = false; 88 while(!points.empty()) { 89 points.pop_back(); 90 } 91 } 92 } 93 glFlush(); 94 } 95 } 96 97 int main(int argc, char** argv) { 98 glutInit(&argc, argv); 99 glutInitDisplayMode(GLUT_RGB); 100 glutInitWindowPosition(0, 0); 101 glutInitWindowSize(500, 500); 102 glutCreateWindow("Bezier-curve"); 103 104 myInit(); 105 glutDisplayFunc (myDisplay); 106 glutMouseFunc(myMouse); 107 glutMainLoop(); 108 return 0; 109 }
4. 延伸
一次、二次、五次贝赛尔曲线以及贝塞尔曲线的升阶,具体:
https://zh.wikipedia.org/zh-cn/%E8%B2%9D%E8%8C%B2%E6%9B%B2%E7%B7%9A