#include#include int detection(int x, int y); void myMovedMouse(int x, int y); double p_t(int n, int x, GLdouble t); const int screenWidth = 600; const int screenHeight = 480; //顶点个数 static int length = 0; //被检测到的顶点的位置 static int point_n = 0; //--------------------数据结构部分--------------------- class Points; //顶点类 class Point { friend class Points; public: Point() { this->x = NULL; this->y = NULL; this->next = NULL; } Point(GLfloat x, GLfloat y) { this->x = x; this->y = y; this->next = NULL; } private: GLfloat x; GLfloat y; Point* next; }; //单链表类 class Points { public: Points() { this->first = NULL; } void Add(GLfloat x, GLfloat y); float Traverse(int n, int z); void Alter(GLfloat x, GLfloat y, int n); private: Point* first; }; //添加顶点 void Points::Add(GLfloat x, GLfloat y) { Point* newPoint = new Point(x, y); if (length == 0 || first == NULL) { first = newPoint; length++; } else { Point* q = first; for (int i = 1; i < length; i++) { q = q->next; } newPoint->next = q->next; q->next = newPoint; length++; } } //遍历顶点 float Points::Traverse(int n, int z) { if (n != 0) { Point* q = first; for (int i = 1; i < n; i++) { q = q->next; } if (z == 0) { //z=0时返回X return q->x; } else { //z!=0时返回Y return q->y; } } } //修改顶点 void Points::Alter(GLfloat x, GLfloat y, int n) { if (n != 0) { Point* q = first; for (int i = 1; i < n; i++) { q = q->next; } q->x = x; q->y = y; } } //-----------------------OpenGL部分-------------------------- static Points points; //初始化 void SetupRC() { glClearColor(0.0, 0.0, 0.0, 0.0); glPointSize(3.0); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(-(GLdouble)screenWidth / 2, (GLdouble)screenWidth / 2, -(GLdouble)screenHeight / 2, (GLdouble)screenHeight / 2); } //绘制曲线和顶点 void draw() { glColor3f(1.0f, 1.0f, 0.f); glBegin(GL_LINE_STRIP); for (int i = 1; i <= length; i++) { GLfloat x = points.Traverse(i, 0); GLfloat y = points.Traverse(i, 1); glVertex2i(x, y); } glEnd(); glColor3f(1.0f, 0.0f, 0.0f); glBegin(GL_POINTS); for (int i = 1; i <= length; i++) { GLfloat x = points.Traverse(i, 0); GLfloat y = points.Traverse(i, 1); glVertex2i(x, y); } glEnd(); glColor3f(0.0f, 1.0f, 1.0f); glBegin(GL_LINE_STRIP); for (GLdouble t = 0; t < 1; t = t + 0.01) { float x = p_t(length, 0, t); float y = p_t(length, 1, t); glVertex2i(x, y); } glEnd(); } //渲染 void RenderScene() { glClear(GL_COLOR_BUFFER_BIT); draw(); glFlush(); } //鼠标交互 void myMouse(int button, int state, int x, int y) { if (state == GLUT_DOWN) { if (button == GLUT_LEFT_BUTTON) { if (point_n = detection(x - (GLdouble)screenWidth / 2, screenHeight / 2 - y)) { std::cout << "检测到顶点:" << point_n << std::endl; glutMotionFunc(myMovedMouse); } else if (!detection(x - (GLdouble)screenWidth / 2, screenHeight / 2 - y)) { points.Add(x - (GLdouble)screenWidth / 2, screenHeight / 2 - y); RenderScene(); } } } } //拖拽顶点 void myMovedMouse(int x, int y) { points.Alter(x - (GLdouble)screenWidth / 2, screenHeight / 2 - y, point_n); RenderScene(); } //检测顶点 int detection(int x, int y) { for (int i = 1; i <= length; i++) { GLfloat p_x = points.Traverse(i, 0); GLfloat p_y = points.Traverse(i, 1); if (x - 10 < p_x && p_x < x + 10) { if (y - 10 < p_y && p_y < y + 10) { return i; } } } return 0; } //De Casteljau算法 double p_t(int n, int z, GLdouble t) { double p[100][100]; for (int i = 0; i <= n - 1; i++) { p[0][i] = points.Traverse(i + 1, z); } for (int r = 1; r <= n - 1; r++) { for (int i = n - 1; i >= r; i--) { p[r][i] = (1 - t) * p[r - 1][i - 1] + t * p[r - 1][i]; } } return p[n - 1][n - 1]; } int main(int argc, char** argv) { glutInit(&argc, argv); points.Add(0 * 20, 0 * 20); points.Add(2 * 20, 2 * 20); points.Add(2 * 20, -1 * 20); points.Add(4 * 20, 0 * 20); glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE); //设置初始窗口的位置(窗口左上角相对于桌面坐标(x, y)) glutInitWindowPosition(100, 100); //设置初始窗口的大小 glutInitWindowSize(screenWidth, screenHeight); glutCreateWindow("Mouse Sierpinski"); glutMouseFunc(myMouse); glutDisplayFunc(RenderScene); SetupRC(); glutMainLoop(); return 0; }
如有疑问+QQ:307647252



