Bezier

#pragma comment( linker, "/subsystem:windows /entry:mainCRTStartup" )//去除控制台窗口
#include <iostream>
#include <gl/GLUT.h>
#include <map>
#include <vector>
#include<cmath>
#include <list>
#include <algorithm>
using namespace std;

struct Point {
	float x, y;
	Point(float _x, float _y) :x(_x), y(_y) {}
	Point() {}
	void operator =(Point& r) {
		x = r.x; y = r.y;
	}
	Point operator+(Point p)
	{
		return Point(this->x + p.x, this-> y + p.y);
	}
};

Point P[1000];
vector<Point> v;
int choice_id = -1;
int window_size = 800;
float XL=200, XR=600, YB=200, YT=600;

//void green_line(Point a, Point b);
void control_polygon();
void draw_rp(float x, float y);
void OnMouse(int button, int state, int x, int y);
void InitEnvironment();
void myMotion(int x, int y);
void deCasteljau();

int main(int argc, char* argv[]) {
	glutInit(&argc, argv);   //初始化GLUT
	glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
	glutInitWindowPosition(300, 100);
	glutInitWindowSize(window_size, window_size);
	glutCreateWindow("Bezier");
	InitEnvironment();   //初始化
	glutMotionFunc(&myMotion);   //回调函数
	glutMouseFunc(&OnMouse);  //注册鼠标事件
	glutMainLoop();    //持续显示,当窗口改变会重新绘制图形

	return 0;
}

void InitEnvironment() {
	glClearColor(0.0, 0.0, 0.0, 1);
	glClear(GL_COLOR_BUFFER_BIT);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glPointSize(6);
	glLineWidth(3);
	gluOrtho2D(0, window_size, 0, window_size);
	
}

void myMotion(int x, int y) {
	if (choice_id != -1) {
		v[choice_id].x = float(x);
		v[choice_id].y = float(y);
		deCasteljau();
	}
}

void draw_rp(float x, float y) {
	glBegin(GL_POINTS);
	glColor3f(1, 0, 0);
	glVertex2f(x, window_size - y);
	glEnd();
	glFlush();
}
void OnMouse(int button, int state, int x, int y)
//OnMouse坐标系x从左向右,y从上到下
{
	if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
		choice_id = -1;
		int t = v.size();
		draw_rp(x, y);
		for (int i = 0; i < t; i++) {
			if (abs(x - v[i].x) < 8 && abs(y - v[i].y) < 8) {//选中一个点
				choice_id = i; return;
			}
		}
		v.push_back(Point(x, y));
		deCasteljau();

	}
	else if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN )
	{   //点击右键,选择顶点删除
		int t = v.size();
		for (int i = 0; i < t; i++) {
			if (abs(x - v[i].x) < 8 && abs(y - v[i].y) < 8) {//选中一个点
				for(int j = i; j < v.size()-1; j++)v[j] = v[j + 1];
				v.pop_back();
				deCasteljau();
				break;
			}
		}
		
	}
}

void deCasteljau() {
	glClear(GL_COLOR_BUFFER_BIT);
	vector<Point>res;
	int n = v.size() - 1;
	for (int i = 0; i <=n; i++) {P[i] = v[i];}
	for(float t=0.0;t<=1;t=t+0.01){
		for (int i = n-1; i >= 0;i--) {
			for (int j = 0; j <= i; j++) {
				P[j].x = (1 - t) * P[j].x + t * P[j + 1].x;
				P[j].y = (1 - t) * P[j].y + t * P[j + 1].y;
			}
		}
		res.push_back(P[0]);
	}

	glBegin(GL_LINES);//多次调用画图的话,容易闪烁,这里开头调用一遍就够了
	glColor3f(0, 1, 0);
	for (int i = 0; i < res.size()-1; i++){
		glVertex2f(res[i].x, window_size - res[i].y);
		glVertex2f(res[i+1].x, window_size - res[i + 1].y);
	}
	glEnd();
	glFlush();

	control_polygon();
}

void control_polygon() {
	int n = v.size()-1;
	
	glBegin(GL_LINES);
	for (int i = 0; i <=n-1; i++) {
		glColor3f(0, 0, 1);
		glVertex2f(v[i].x, window_size - v[i].y);
		glVertex2f(v[i + 1].x, window_size - v[i + 1].y);
		/*if (i <=n-2) {
			glColor3f(0.5, 0.5, 0.5);
			glVertex2f(v[i].x, window_size - v[i].y);
			glVertex2f(v[i + 2].x, window_size - v[i + 2].y);
		}*/
	}
	glEnd();
	glFlush();
	for (int i = 0; i <= n; i++) {//点和线不能交叉使用
		draw_rp(v[i].x, v[i].y);
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Bezier曲线是一种数学曲线,它可以用来创建光滑的曲线。Bezier曲线算法是通过一系列控制点来定义曲线的形状。以下是Bezier曲线算法的基本步骤: 1.定义控制点:定义一组控制点,这些点将决定曲线的形状。 2.计算Bezier曲线上的点:通过递归地计算相邻线段的同等比例点处的连线,再取同等比例的点再连线,一直取到最后那条线段的同等比例处,该点就是Bezier曲线上的点。 3.绘制Bezier曲线:将计算出的Bezier曲线上的点连接起来,就可以绘制出Bezier曲线。 下面是一个使用Python实现的例子: ```python import matplotlib.pyplot as plt import numpy as np def bezier_curve(control_points, num=1000): t = np.linspace(0, 1, num=num) n = len(control_points) result = [] for i in range(num): point = np.zeros((2,)) for j in range(n): point += control_points[j] * bernstein_poly(j, n-1, t[i]) result.append(point) return result def bernstein_poly(i, n, t): return comb(n, i) * t**i * (1-t)**(n-i) def comb(n, i): return np.math.factorial(n) / (np.math.factorial(i) * np.math.factorial(n-i)) control_points = np.array([[0, 0], [1, 2], [3, 1], [4, 3]]) curve_points = bezier_curve(control_points) plt.plot(control_points[:,0], control_points[:,1], 'ro--') plt.plot([p[0] for p in curve_points], [p[1] for p in curve_points], 'b-') plt.show() ``` 该例子中,我们定义了四个控制点,然后使用`bezier_curve`函数计算出Bezier曲线上的点,最后使用Matplotlib库绘制出Bezier曲线。你可以根据自己的需要修改控制点的坐标来创建不同形状的Bezier曲线。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值