欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

de Casteljau交互Bezier

程序员文章站 2024-01-16 21:37:16
...
#include <GL/glut.h>
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
const GLfloat wh=600;
struct point {
	float x;
	float y;
};
vector<point>V; 
vector<point> V1, V2; int  model = 0; bool dragging = false;
vector<point>& de_Casteljau(int n) {
    V1.resize(V.size()); V2.resize(0);
	for (float t = 0; t <= 1;t=t+0.02) {
		for (int j = 1; j < n; j++) {
			for (int k = 0; k < n - j;k++) {
				if (j == 1) { 
					V1[k].x = (1 - t) * V[k].x + t * V[k + 1].x;
					V1[k].y = (1 - t) * V[k].y + t * V[k + 1].y;
					
				}
				else {
					V1[k].x = (1 - t) * V1[k].x + t * V1[k + 1].x;
					V1[k].y = (1 - t) * V1[k].y + t * V1[k + 1].y;
					
				}
			}

		}
		cout << V1[0].x << " " << V1[0].y << endl;
		V2.push_back(V1[0]);
	}
	return V2;
}

int findnearest(float x,float y ) {
	float min = 1000000; int re=0;
	for (int i = 0; i < V.size(); i++) {
		float d = (V[i].x - x) * (V[i].x - x) + (V[i].y - y) * (V[i].y - y);
		if (d < min) {
			re = i; min = d;
		}
	}
	return re;
}
void draw() {
	glClear(GL_COLOR_BUFFER_BIT);
	glBegin(GL_LINE_STRIP);
	for (int i = 0; i < V.size(); i++) {
		point p = V[i];
		glVertex2f(p.x, p.y);
	}
	glEnd();
	glFlush();
	vector<point>re = de_Casteljau(V.size()); re.push_back(V.back());
	glBegin(GL_LINE_STRIP);
	for (int i = 0; i < re.size(); i++) {
		point p = re[i];

		glVertex2f(p.x, p.y);
	}
	glEnd();
	glFlush();
}

int id = 0;
void  mymouse(int button, int state, int x, int y) {
	y = wh - y; 
	if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
		if (model == 0) {
			point p; p.x = x; p.y = y;
			V.push_back(p);
			glBegin(GL_POINTS);
			glVertex2f(p.x, p.y);
			glEnd();
			glFlush();
		}
		else if (model == 1) {
			 id= findnearest(x, y);
			V.erase(V.begin() + id);
			if (V.size() > 1)draw();
			else { cout << "点数必须>=2" << endl; }
		}
		else if (model == 2) {
			 id = findnearest(x, y);
			cout << "点号" << id << endl;
			dragging = true;
		}
		else if (model == 3) {
			point p; p.x = x; p.y = y;
			V.push_back(p);
			glBegin(GL_POINTS);
			glVertex2f(p.x, p.y);
			glEnd();
			glFlush();
			draw();
		}
	}
	if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) {
		if (dragging==true) {
			dragging = false;
			V[id].x = x; V[id].y = y;
			
			if (V.size() > 1)draw();
			return;
		}
	}
	
}
void keyboard(unsigned char key,int x,int y) {
	if (key == 32) {
		draw();
		 
	}
	
}
void Mymenu(int m) {
	model = m;
	if (model == 4) {
		exit(0);
	}
}
int main(int argc, char* argv[])
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RED);
	glutInitWindowPosition(50, 50);
	glutInitWindowSize(800, 600);
	glutCreateWindow("Bezier");
	cout << "。。。。" << endl;

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(0, 800, 0, 600);

	glClearColor(1, 1, 1, 1);
	glClear(GL_COLOR_BUFFER_BIT);

	glColor3f(160.0/255.0,82.0/255.0,45.0/255.0);
	glLineWidth(2.0f); glPointSize(5);


	glutMouseFunc(&mymouse);
	glutKeyboardFunc(&keyboard);

	glutCreateMenu(Mymenu);//注册菜单回调函数
	glutAddMenuEntry("Delete", 1);//添加菜单项
	glutAddMenuEntry("Move", 2);
	glutAddMenuEntry("Insert", 3);
	glutAddMenuEntry("Exit", 4);
	glutAttachMenu(GLUT_RIGHT_BUTTON);
	glutMainLoop();
	return 0;
}