#include <gl/glut.h>
#include<math.h>
#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")
int SCREEN_HEIGHT = 600;
int NUMPOINTS = 0;
class Point
{
public:
float x, y;
void setxy(float x2, float y2)
{
x = x2;
y = y2;
}
};
Point abc[4];
Point bef[3];
Point mid[2];
Point link[1000];
void myInit()
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glColor3f(1.0f, 0.0, 0.0);
glPointSize(4.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, 640, 0.0, 480.0);
}
void drawDot(Point pt)
{
glBegin(GL_POINTS);
glVertex2f(pt.x, pt.y);
glEnd();
glFlush();
}
void drawLine(Point p1, Point p2)
{
glBegin(GL_LINES);
glVertex2f(p1.x, p1.y);
glVertex2f(p2.x, p2.y);
glEnd();
glFlush();
}
//四个控制点的贝塞尔曲线 即三次Bezier曲线
void drawBezier(Point A, Point B, Point C, Point D)
{
for (double t = 0.0; t <= 1.0; t += 0.001)
{
bef[0].setxy((1 - t)*A.x + t*B.x, (1 - t)*A.y + t*B.y);
bef[1].setxy((1 - t)*B.x + t*C.x, (1 - t)*B.y + t*C.y);
bef[2].setxy((1 - t)*C.x + t*D.x, (1 - t)*C.y + t*D.y);
mid[0].setxy((1 - t)*bef[0].x + t*bef[1].x, (1 - t)*bef[0].y + t*bef[1].y);
mid[1].setxy((1 - t)*bef[1].x + t*bef[2].x, (1 - t)*bef[1].y + t*bef[2].y);
link[0].setxy((1 - t)*mid[0].x + t*mid[1].x, (1 - t)*mid[0].y + t*mid[1].y);
glColor3f(1.0f, 1.0f, 0.0f);
drawLine(bef[0], bef[1]);
glColor3f(1.0f, 1.0f, 0.0f);
drawLine(bef[1], bef[2]);
glColor3f(1.0f, 1.0f, 0.0f);
drawLine(mid[0], mid[1]);
glColor3f(1.0f, 0.0f, 0.0f);
drawDot(link[0]);
glColor3f(0.0f, 0.0f, 0.0f);
drawLine(bef[0], bef[1]);
glColor3f(0.0f, 0.0f, 0.0f);
drawLine(bef[1], bef[2]);
glColor3f(0.0f, 0.0f, 0.0f);
drawLine(mid[0], mid[1]);
glColor3f(0.0, 1.0, 0.0);
drawLine(abc[0], abc[1]);
glColor3f(0.0, 1.0, 0.0);
drawLine(abc[1], abc[2]);
glColor3f(0.0, 1.0, 0.0);
drawLine(abc[2], abc[3]);
}
}
void myDisplay()
{
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
}
void ChangeSize(GLsizei width, GLsizei height)
{
GLfloat aspect_init, aspect;
glViewport(0, 0, width, height);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
aspect_init = 4.0 / 3.0;
aspect = 1.0*width / height;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//Keep Aspect of Current Window
if (aspect <= aspect_init)
glViewport(0, (height - width / aspect) / 2, width, width / aspect_init);
else
glViewport((width - height*aspect_init) / 2, 0, height*aspect_init, height);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glOrtho(-2, 2, -2, 2, -2, 2);
}
void myMouse(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
abc[NUMPOINTS].setxy((float)x, (float)(SCREEN_HEIGHT - y));
NUMPOINTS++;
if (NUMPOINTS == 4)
{
glColor3f(1.0, 0.0, 1.0);
drawDot(abc[0]);
glColor3f(1.0, 0.0, 1.0);
drawDot(abc[1]);
glColor3f(1.0, 0.0, 1.0);
drawDot(abc[2]);
glColor3f(1.0, 0.0, 1.0);
drawDot(abc[3]);
glColor3f(0.0, 1.0, 0.0);
drawLine(abc[0], abc[1]);
glColor3f(0.0, 1.0, 0.0);
drawLine(abc[1], abc[2]);
glColor3f(0.0, 1.0, 0.0);
drawLine(abc[2], abc[3]);
//Point POld = abc[0];
drawBezier(abc[0], abc[1], abc[2], abc[3]);
glColor3f(1.0, 0.0, 1.0);
drawDot(abc[0]);
glColor3f(0.0, 1.0, 0.0);
drawLine(abc[0], abc[1]);
glColor3f(0.0, 1.0, 0.0);
drawLine(abc[1], abc[2]);
glColor3f(0.0, 1.0, 0.0);
drawLine(abc[2], abc[3]);
glColor3f(1.0, 0.0, 0.0);
NUMPOINTS = 0;
}
}
}
void main(int argc, char **argv)
{
glutInit(&argc, argv);
// 在这里设置双缓冲区。
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(0, 0);
glutInitWindowSize(800, 600);
glutCreateWindow("bezier");
glutMouseFunc(myMouse);
myInit();
//glutIdleFunc(RenderScene);
glutDisplayFunc(myDisplay);
glutMainLoop();
}