计算机图形学实验五:Bezier曲线

最初版(逐像素画)

#include<gl/glut.h>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
const int window_size = 600;
int last_x = -1, last_y = -1,n,choosenpoint=-1,button_down;
struct point {
	double x, y;
};
vector<point> Vertex;
vector<point> controlpoint;
void drawapoint(int x, int y) {
	glPointSize(1);
	glColor3ub(25, 160, 95);
	glBegin(GL_POINTS);
	glVertex2d(x, y);
	glEnd();
	glFlush();
}
void deCasteljau(){
	controlpoint = Vertex;
	int len = controlpoint.size();
	for (double t = 0; t <= 1.0; t += 0.003/n) {
		for (int i = 1; i < len; i++) {
			for (int j = 0; j < len-i; j++) {
				if (i == 1) {
					controlpoint[j].x = (1 - t) * Vertex[j].x + t * Vertex[j + 1].x;
					controlpoint[j].y = (1 - t) * Vertex[j].y + t * Vertex[j + 1].y;
				}
				else {
					controlpoint[j].x = (1 - t) * controlpoint[j].x + t * controlpoint[j + 1].x;
					controlpoint[j].y = (1 - t) * controlpoint[j].y + t * controlpoint[j + 1].y;
				}
			}
		}
		drawapoint(controlpoint[0].x, controlpoint[0].y);
	}
}
void init() {
	glClearColor(1, 1, 1, 0);
	glClear(GL_COLOR_BUFFER_BIT);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluOrtho2D(0, window_size, window_size, 0);
}
void mydisplay() {
	cout << "调用了一次回调函数" << endl;
}
void drawpolygon();
void mymouse(int button, int state, int x, int y) {
	if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
		cout << "鼠标按下的坐标是" << x << " , " << y << endl;
		button_down = 1;
		//1、判断是否选中已输入的点
		for (int i = 0; i < Vertex.size(); i++) {
			if ((abs(x - Vertex[i].x) <= 10 && abs(y - Vertex[i].y) <= 10)) {
				choosenpoint = i;
				break;
			}
			else choosenpoint = -1;
		}
		if (choosenpoint >= 0) {
			cout << "选中了第" << choosenpoint << "个点" << endl;
		}
		else {//2、新的顶点
			glPointSize(7);
			glColor3ub(220, 80, 70);
			glBegin(GL_POINTS);
			glVertex2i(x, y);
			Vertex.push_back({ x + 0.0,y + 0.0 });
			n = Vertex.size();
			glEnd();
			glFlush();
			if (last_x > 0 && last_y > 0) {
				glLineWidth(2);
				glColor3ub(75, 140, 245);
				glBegin(GL_LINES);
				glVertex2i(last_x, last_y);
				glVertex2i(x, y);
				glEnd();
				glFlush();
			}
			last_x =Vertex.back().x; last_y = Vertex.back().y;
		}		
	}
	if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) {
		glClear(GL_COLOR_BUFFER_BIT);
		drawpolygon();
		deCasteljau();
		button_down = 2;
	}

}
void drawpolygon() {
	glPointSize(7);
	glColor3ub(220, 80, 70);
	//cout << "当前有" << Vertex.size() << "个控制顶点" << endl;
	for (int i = 0; i < Vertex.size(); i++) {
		glBegin(GL_POINTS);
		glVertex2i(Vertex[i].x, Vertex[i].y);
		glEnd();
		glFlush();
	}	
	glLineWidth(2);
	glColor3ub(75, 140, 245);
	for(int i=1;i<Vertex.size();i++){		
		glBegin(GL_LINES);
		glVertex2i(Vertex[i-1].x,Vertex[i-1].y);
		glVertex2i(Vertex[i].x, Vertex[i].y);
		glEnd();
		glFlush();
	}
}
void dragmouse(int x,int y) {
	if (choosenpoint >= 0&&button_down==1) {
		glClear(GL_COLOR_BUFFER_BIT);
		Vertex[choosenpoint].x = x;
		Vertex[choosenpoint].y = y;
		if (choosenpoint == Vertex.size() - 1) {
			last_x = x, last_y = y;
		}
		drawpolygon();
	}	
}
void mykeyBoard(unsigned char key, int x, int y) {
	if (key == 'd' && choosenpoint >= 0) {
		cout << "按下了d,删除第" <<choosenpoint<<"个点 "<< endl;
		Vertex.erase(Vertex.begin()+choosenpoint);
		choosenpoint = -1;
		if (Vertex.size()) {
			last_x = Vertex.back().x; last_y = Vertex.back().y;
		}
		else {
			last_x = -1, last_y = -1;
		}
		glClear(GL_COLOR_BUFFER_BIT);

		drawpolygon();
	}
	if (key == 'i' && choosenpoint >= 0) {
		Vertex.insert(Vertex.begin() + choosenpoint+1, { x+0.0,y+0.0 });
		choosenpoint = -1;
		if (Vertex.size()) {
			last_x = Vertex.back().x; last_y = Vertex.back().y;
		}
		glClear(GL_COLOR_BUFFER_BIT);
		drawpolygon();
	}
	if (key == 'c') {
		cout << "按下了c" << endl;
		glClear(GL_COLOR_BUFFER_BIT);
		last_x = -1, last_y = -1, n=0, choosenpoint = -1, button_down = 0;
		Vertex.clear();
		controlpoint.clear();
	}
}

int main(int argc, char* argv[]) {
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
	glutInitWindowPosition(600, 200);
	glutInitWindowSize(window_size, window_size);
	glutCreateWindow("Bezier");
	init();
	glutMouseFunc(mymouse);
	glutKeyboardFunc(mykeyBoard);
	glutMotionFunc(dragmouse);
	glutDisplayFunc(mydisplay);
	glutMainLoop();
	return 0;
}

10.10第二版

#include<gl/glut.h>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
const int window_size = 600;
int last_x = -1, last_y = -1,n,choosenpoint=-1,button_down;
struct point {
	double x, y;
};
vector<point> Vertex;
vector<point> controlpoint;
vector<point>Bezier;
void deCasteljau(){
	controlpoint = Vertex;
	int len = controlpoint.size();
	for (double t = 0; t <= 1.0; t += 0.005/n) {
		for (int i = 1; i < len; i++) {
			for (int j = 0; j < len-i; j++) {
				if (i == 1) {
					controlpoint[j].x = (1 - t) * Vertex[j].x + t * Vertex[j + 1].x;
					controlpoint[j].y = (1 - t) * Vertex[j].y + t * Vertex[j + 1].y;
				}
				else {
					controlpoint[j].x = (1 - t) * controlpoint[j].x + t * controlpoint[j + 1].x;
					controlpoint[j].y = (1 - t) * controlpoint[j].y + t * controlpoint[j + 1].y;
				}
			}
		}
		Bezier.push_back({ controlpoint[0].x, controlpoint[0].y });
		
	}
	//画出bezier曲线
	glLineWidth(3);
	glColor3ub(25, 160, 95);
	glBegin(GL_LINE_STRIP);
	for (int i = 0; i < Bezier.size(); i++) {
		glVertex2d(Bezier[i].x, Bezier[i].y);
	}
	glEnd();
	glFlush();
	Bezier.clear();
}
void init() {
	glClearColor(1, 1, 1, 0);
	glClear(GL_COLOR_BUFFER_BIT);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluOrtho2D(0, window_size, window_size, 0);
}
void mydisplay() {
	cout << "调用了一次回调函数" << endl;
}
void drawpolygon();
void mymouse(int button, int state, int x, int y) {
	if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
		cout << "鼠标按下的坐标是" << x << " , " << y << endl;
		button_down = 1;
		//1、判断是否选中已输入的点
		for (int i = 0; i < Vertex.size(); i++) {
			if ((abs(x - Vertex[i].x) <= 10 && abs(y - Vertex[i].y) <= 10)) {
				choosenpoint = i;
				break;
			}
			else choosenpoint = -1;
		}
		if (choosenpoint >= 0) {
			cout << "选中了第" << choosenpoint << "个点" << endl;
		}
		else {//2、新的顶点
			glPointSize(7);
			glColor3ub(220, 80, 70);
			glBegin(GL_POINTS);
			glVertex2i(x, y);
			Vertex.push_back({ x + 0.0,y + 0.0 });
			n = Vertex.size();
			glEnd();
			glFlush();
			if (last_x > 0 && last_y > 0) {
				glLineWidth(2);
				glColor3ub(75, 140, 245);
				glBegin(GL_LINES);
				glVertex2i(last_x, last_y);
				glVertex2i(x, y);
				glEnd();
				glFlush();
			}
			last_x =Vertex.back().x; last_y = Vertex.back().y;
		}		
	}
	if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) {
		glClear(GL_COLOR_BUFFER_BIT);
		drawpolygon();
		deCasteljau();
		button_down = 2;
	}

}
void drawpolygon() {
	glPointSize(7);
	glColor3ub(220, 80, 70);
	//cout << "当前有" << Vertex.size() << "个控制顶点" << endl;
	for (int i = 0; i < Vertex.size(); i++) {
		glBegin(GL_POINTS);
		glVertex2i(Vertex[i].x, Vertex[i].y);
		glEnd();
		glFlush();
	}	
	glLineWidth(2);
	glColor3ub(75, 140, 245);
	for(int i=1;i<Vertex.size();i++){		
		glBegin(GL_LINES);
		glVertex2i(Vertex[i-1].x,Vertex[i-1].y);
		glVertex2i(Vertex[i].x, Vertex[i].y);
		glEnd();
		glFlush();
	}
}
void dragmouse(int x,int y) {
	if (choosenpoint >= 0&&button_down==1) {
		glClear(GL_COLOR_BUFFER_BIT);
		Vertex[choosenpoint].x = x;
		Vertex[choosenpoint].y = y;
		if (choosenpoint == Vertex.size() - 1) {
			last_x = x, last_y = y;
		}
		drawpolygon();
		//画曲线
		deCasteljau();
	}	
}
void mykeyBoard(unsigned char key, int x, int y) {
	if (key == 'd' && choosenpoint >= 0) {
		cout << "按下了d,删除第" <<choosenpoint<<"个点 "<< endl;
		Vertex.erase(Vertex.begin()+choosenpoint);
		n = Vertex.size();
		choosenpoint = -1;
		glClear(GL_COLOR_BUFFER_BIT);
		drawpolygon();
		if (Vertex.size()) {
			last_x = Vertex.back().x; last_y = Vertex.back().y;
			//画曲线
			deCasteljau();
		}
		else {
			last_x = -1, last_y = -1;
		}
	}
	if (key == 'i' && choosenpoint >= 0) {
		Vertex.insert(Vertex.begin() + choosenpoint+1, { x+0.0,y+0.0 });
		n = Vertex.size();
		choosenpoint = -1;
		if (Vertex.size()) {
			last_x = Vertex.back().x; last_y = Vertex.back().y;
		}
		glClear(GL_COLOR_BUFFER_BIT);
		drawpolygon();
		//画曲线
		deCasteljau();
	}
	if (key == 'c') {
		cout << "按下了c" << endl;
		glClear(GL_COLOR_BUFFER_BIT);
		last_x = -1, last_y = -1, n=0, choosenpoint = -1, button_down = 0;
		Vertex.clear();
		controlpoint.clear();
	}
}

int main(int argc, char* argv[]) {
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
	glutInitWindowPosition(600, 200);
	glutInitWindowSize(window_size, window_size);
	glutCreateWindow("Bezier");
	init();
	glutMouseFunc(mymouse);
	glutKeyboardFunc(mykeyBoard);
	glutMotionFunc(dragmouse);
	glutDisplayFunc(mydisplay);
	glutMainLoop();
	return 0;
}
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值