最初版(逐像素画)
#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;
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 {
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);
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 });
}
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;
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 {
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);
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;
}