
#define MAX_POLYGONS 80
#define MAX_VERTICES 100
typedef int Bool;
#define TRUE 1
#define FALSE 0
#include #include #include #include #include #include #include using namespace std; void myMouse(int ,int ,int ,int ); void myMotion(int,int); void myDisplay(); void myReshape(int ,int); void color_menu(int); void main_menu(int); int pick_polygon(int x,int y); void save(); void myinit(); typedef struct polygon { int color; bool used; int xmin,xmax,ymin,ymax;/*包围盒*/ float xc,yc;/*多边形的中心*/ int nvertices; /*顶点的数目*/ int x[MAX_VERTICES];//顶点 int y[MAX_VERTICES]; }polygon; bool picking=FALSE;//如果处于拾取状态,则为TRUE bool moving=FALSE; int lock;//////////// int in_polygon=-1; int present_color=0; GLsizei wh=500,ww=800;//初始窗口大小 int draw_mode=0; GLfloat colors[8][3]={{0.0,0.0,0.0},{1.0,0.0,0.0},{0.0,1.0,0.0},{0.0,0.0,1.0},{0.0,1.0,1.0},{1.0,0.0,1.0},{1.0,1.0,0.0},{1.0,1.0,1.0}}; polygon polygons[MAX_POLYGONS]; void myReshape(int w,int h) { glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0,(GLdouble)w,0,(GLdouble)h); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glViewport(0,0,w,h); ww=w; wh=h; } void myinit() { int i; //清屏颜色 glClearColor(1.0,1.0,1.0,1); fstream file; file.open("save.txt",ios_base::in|ios_base::out|ios_base::app); try { for(i=0;i } } catch (exception * ex) { // 捕获 exception*; for(i=0;i polygons[i].used=FALSE; } } file.close(); } void save(){ //添加写文件命令 int i; fstream file; file.open("save.txt",ios_base::in|ios_base::out|ios::binary); for(i=0;i } file.close(); } void myMouse(int btn,int state,int x,int y) { int i,j; y=wh-y; if(btn==GLUT_LEFT_BUTTON&&state==GLUT_DOWN&&!picking&&!moving) {//增加顶点 moving=FALSE; if(in_polygon>=0){ if(polygons[in_polygon].nvertices>=MAX_VERTICES) { printf("超出了最大承受点数,最大承受点数为%d\\n",MAX_VERTICES); exit(0); } i=polygons[in_polygon].nvertices; polygons[in_polygon].x[i]=x; polygons[in_polygon].y[i]=y; polygons[in_polygon].nvertices++; } glutPostRedisplay(); } if(btn==GLUT_LEFT_BUTTON&&state==GLUT_DOWN&&picking&&!moving) {//删除多边形 picking=FALSE; moving=FALSE; j=pick_polygon(x,y); if(j>=0) { polygons[j].used=FALSE; in_polygon=-1; glutPostRedisplay(); } } if(btn==GLUT_MIDDLE_BUTTON&&state==GLUT_DOWN){ moving=FALSE; if(in_polygon>=0) { polygons[in_polygon].xmax=polygons[in_polygon].xmin=polygons[in_polygon].x[0]; polygons[in_polygon].ymax=polygons[in_polygon].ymin=polygons[in_polygon].y[0]; polygons[in_polygon].xc=polygons[in_polygon].x[0]; polygons[in_polygon].yc=polygons[in_polygon].y[0]; for(i=1;i if(polygons[in_polygon].x[i] else if(polygons[in_polygon].x[i]>polygons[in_polygon].xmax) polygons[in_polygon].xmax=polygons[in_polygon].x[i]; if(polygons[in_polygon].y[i] else if(polygons[in_polygon].y[i]>polygons[in_polygon].ymax) polygons[in_polygon].ymax=polygons[in_polygon].y[i]; polygons[in_polygon].xc+=polygons[in_polygon].x[i]; polygons[in_polygon].yc+=polygons[in_polygon].y[i]; } polygons[in_polygon].xc=polygons[in_polygon].xc/polygons[in_polygon].nvertices; polygons[in_polygon].yc=polygons[in_polygon].yc/polygons[in_polygon].nvertices; } in_polygon=-1; glutPostRedisplay(); } if(btn==GLUT_LEFT_BUTTON&&state==GLUT_DOWN&&moving){ moving=false; if(in_polygon>=0) { polygons[in_polygon].xmax=polygons[in_polygon].xmin=polygons[in_polygon].x[0]; polygons[in_polygon].ymax=polygons[in_polygon].ymin=polygons[in_polygon].y[0]; polygons[in_polygon].xc=polygons[in_polygon].x[0]; polygons[in_polygon].yc=polygons[in_polygon].y[0]; for(i=1;i if(polygons[in_polygon].x[i] else if(polygons[in_polygon].x[i]>polygons[in_polygon].xmax) polygons[in_polygon].xmax=polygons[in_polygon].x[i]; if(polygons[in_polygon].y[i] else if(polygons[in_polygon].y[i]>polygons[in_polygon].ymax) polygons[in_polygon].ymax=polygons[in_polygon].y[i]; polygons[in_polygon].xc+=polygons[in_polygon].x[i]; polygons[in_polygon].yc+=polygons[in_polygon].y[i]; } polygons[in_polygon].xc=polygons[in_polygon].xc/polygons[in_polygon].nvertices; polygons[in_polygon].yc=polygons[in_polygon].yc/polygons[in_polygon].nvertices; } in_polygon=-1; glutPostRedisplay(); moving=true; glutPostRedisplay(); int j=pick_polygon(x,y); if(j>=0) { lock=j; } } } int pick_polygon(int x,int y) {//根据每个多边形的包围盒寻找第一个包含拾取位置的多边形 int i; for(i=0;i if(polygons[i].used) { if((x>=polygons[i].xmin)&&(x<=polygons[i].xmax)&& (y>=polygons[i].ymin)&&(y in_polygon=i; moving=TRUE; return(i); } } } printf("not in a polygon\\n"); return(-1); } void myMotion(int x,int y) {//判断是否位于多边形内部 float dx,dy; int i,j; if(moving) { y=wh-y; j=pick_polygon(x,y); if(j<0) { printf("not in a polygon\\n"); return; } if(lock==j){ //如果位于多边形内部,则移动多边形 dx=x-polygons[j].xc; dy=y-polygons[j].yc; for(i=0;i polygons[j].y[i]+=dy; } polygons[j].xc+=dx; polygons[j].yc+=dy; if(dx>0) polygons[j].xmax+=dx; else polygons[j].xmin+=dx; if(dy>0) polygons[j].ymax+=dy; else polygons[j].ymin+=dy; glutPostRedisplay(); } } } void color_menu(int index) { present_color=index; if(in_polygon>=0) polygons[in_polygon].color=index; } void main_menu(int index){ int i; switch(index) { case(1)://建立一个新的多边形 { moving=FALSE; for(i=0;i { printf("exceeeded maximum number of polygons\\n"); exit(0); } polygons[i].color=present_color; polygons[i].used=TRUE; polygons[i].nvertices=0; in_polygon=i; picking=FALSE; glutPostRedisplay(); break; } case(2)://结束多边形的定义并计算多边形包围盒和它的中心位置 { moving=FALSE; if(in_polygon>=0) { polygons[in_polygon].xmax=polygons[in_polygon].xmin=polygons[in_polygon].x[0]; polygons[in_polygon].ymax=polygons[in_polygon].ymin=polygons[in_polygon].y[0]; polygons[in_polygon].xc=polygons[in_polygon].x[0]; polygons[in_polygon].yc=polygons[in_polygon].y[0]; for(i=1;i if(polygons[in_polygon].x[i] else if(polygons[in_polygon].x[i]>polygons[in_polygon].xmax) polygons[in_polygon].xmax=polygons[in_polygon].x[i]; if(polygons[in_polygon].y[i] else if(polygons[in_polygon].y[i]>polygons[in_polygon].ymax) polygons[in_polygon].ymax=polygons[in_polygon].y[i]; polygons[in_polygon].xc+=polygons[in_polygon].x[i]; polygons[in_polygon].yc+=polygons[in_polygon].y[i]; } polygons[in_polygon].xc=polygons[in_polygon].xc/polygons[in_polygon].nvertices; polygons[in_polygon].yc=polygons[in_polygon].yc/polygons[in_polygon].nvertices; } in_polygon=-1; glutPostRedisplay(); break; } case(3)://设置拾取模式 { picking=TRUE; moving=FALSE; break; } case(4)://设置移动模式 { moving=TRUE; glutPostRedisplay(); break; } case(5)://退出 { exit(0); break; } case(6)://保存 { save(); break; } } } void myDisplay() {//显示所有的活动多边形 int i,j; glClear(GL_COLOR_BUFFER_BIT); for(i=0;i if(polygons[i].used) { glColor3fv(colors[polygons[i].color]); glBegin(GL_POLYGON); for(j=0;j glEnd(); } } /* printf("%d\\n",in_polygon); if(in_polygon>=0){ int k=in_polygon; glColor3fv(colors[polygons[k].color]); glBegin(GL_LINE_STRIP); int s; for(s=0;s glVertex2i(polygons[k].x[s],polygons[k].y[s]); } glEnd(); }*/ glFlush(); } void main(int argc,char ** argv) { int c_menu; glutInit(&argc,argv); glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); glutInitWindowSize(500,500); glutCreateWindow("polygon modeler"); glutDisplayFunc(myDisplay); myinit(); c_menu=glutCreateMenu(color_menu); glutAddMenuEntry("Black",0); glutAddMenuEntry("Red",1); glutAddMenuEntry("Green",2); glutAddMenuEntry("Blue",3); glutAddMenuEntry("Cyan",4); glutAddMenuEntry("Magenta",5); glutAddMenuEntry("Yellow",6); glutAddMenuEntry("White",7); glutCreateMenu(main_menu); glutAddMenuEntry("new polygon",1); glutAddMenuEntry("end polygon",2); glutAddMenuEntry("delete polygon",3); glutAddMenuEntry("move polygon",4); glutAddMenuEntry("quit",5); glutAddMenuEntry("save",6); glutAddSubMenu("Colors",c_menu); glutAttachMenu(GLUT_RIGHT_BUTTON); glutReshapeFunc(myReshape); glutMouseFunc(myMouse); glutMotionFunc(myMotion); glutMainLoop(); }
