bezier曲线

开始:嗯。。。计图实验之一,这里分享一下我的思路。。。

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;
}



贴个结果:

在这里插入图片描述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值