开始:嗯。。。计图实验之一,这里分享一下我的思路。。。
Bezier曲线有暴力和递推两种方法,但是暴力太不雅观而且组合复杂度太高,于是采用了递推这个方法。首先是可以利用算子的方法证明出来p(t)=
(1-t)*Σ(i=0,n-1)C(n-1,i) t^i (1-t)^(n-1-i)p(i)+ tΣ(i=1,n)C(n,i)t^i (1-t)^(n-i)p(i)然后利用这个东西就可以实现递推(c++代码加上glut实现)。
贴代码:
#include<GL/glut.h>
#include<math.h>
#include<fstream>
#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
int opt;
vector<pair<float, float> > cl_point;
void display()
{
}
void hz()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
glPointSize(4);
glBegin(GL_POINTS);
for (int i = 0;i < cl_point.size();i++)
{
glVertex2f(cl_point[i].first, cl_point[i].second);
}
glEnd();
glFlush();
glColor3f(1.0, 0.0, 0.0);
glPointSize(4);
glBegin(GL_LINE_STRIP);
for (int i = 0;i < cl_point.size();i++)
{
glVertex2f(cl_point[i].first, cl_point[i].second);
}
glEnd();
glFlush();
vector<pair<float, float> > clpoint;
vector<pair<float, float> > point;
for (float t = 0;t <= 1;t += 0.001/cl_point.size())
{
point = cl_point;
for (int i = 0;i < cl_point.size()-1;i++)
{
for (int j = 0;j < point.size()-1;j++)
{
point[j].first = (1 - t) * point[j].first + t * point[j + 1].first;
point[j].second = (1 - t) *point[j].second + t * point[j + 1].second;
}//就是这个,递推式子,每次循环次数减去1就行了
point.pop_back();
}
clpoint.push_back(point[0]);
}
glColor3f(1.0, 0.0, 0.0);
glPointSize(4);
glBegin(GL_POINTS);
for (int i = 0;i < clpoint.size();i++)
{
glVertex2f(clpoint[i].first, clpoint[i].second);
}
glEnd();
glFlush();
}
void mykeybord(unsigned char key, int x, int y)
{
if (key == '1')
{
cout << "鼠标左键插入点,右键删除点\n";
opt = 1;
}
else
{
cout << "鼠标左键拖动点\n";
opt = 2;
}
}
bool cmp(pair<float, float> a, pair<float, float> b)
{
if (a.first != b.first)
{
return a.first < b.first;
}
else
{
return a.second < b.second;
}
}
void mouse(int button, int state,int x, int y)
{
if (opt==1)
{
if (button == GLUT_LEFT_BUTTON)
{
if (state == GLUT_DOWN)
{
y = 480 - y;
if (opt == 1)
{
cl_point.push_back(make_pair(float(x), float(y)));
cout << x << " " << y <<" "<<cl_point.size()<< endl;
sort(cl_point.begin(), cl_point.end(),cmp);
hz();//绘制beizer曲线
}
}
}
else if (button == GLUT_RIGHT_BUTTON)
{
if (state == GLUT_DOWN)
{
y = 480 - y;
cout << x << " " << y << "zuo biao" << endl;
float min = 1000000000;
int cnt;
for (int i = 0;i < cl_point.size();i++)
{
float num = (cl_point[i].first - x) * (cl_point[i].first - x) + (cl_point[i].second - y) * (cl_point[i].second - y);
if (min > num)
{
min = num;
cnt = i;
}
}
cl_point.erase(cl_point.begin() + cnt);
hz();
}
}
}
else if (opt == 2)
{
if (button == GLUT_LEFT_BUTTON)
{
if (state == GLUT_DOWN)
{
y = 480 - y;
int min = 1000000000, cnt;
for (int i = 0;i < cl_point.size();i++)
{
int num = (cl_point[i].first - x) * (cl_point[i].first - x) + (cl_point[i].second - y) * (cl_point[i].second - y);
if (min > num)
{
min = num;
cnt = i;
}
}
cl_point[cnt].first = x, cl_point[cnt].second = y;
sort(cl_point.begin(), cl_point.end());
hz();
}
}
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(400, 400);
glutInitWindowSize(600, 480);
glutCreateWindow("Paint1");
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
gluOrtho2D(0, 600, 0, 480);
glClear(GL_COLOR_BUFFER_BIT);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutKeyboardFunc(mykeybord);
glutMainLoop();
return 0;
}
贴个结果: