河南理工大学计算机科学与技术学院课程设计报告2008—2009学年第二学期课程名称计算机图形学设计题目小型绘图系统学生姓名任小明学号310609010217专业班级计算机06-2班指导教师徐文鹏2009年6月23日目录1、设计概述……………………………………………………………………………………11.1设计题目...………………………………………………………………………….......11.2设计要求……………………………………………………………………………..…11.3设计方案………………………………………………………………………..……....12、软件设计……………………………………………………....…………………………..22.2程序流程图…………………………………………………………………………….22.2算法流程图………………………………………………………………………….…33、程序………………………………………………………………………………………...53.2程序清单…………………………………………………………………………….....53.2程序运行结果………………………………………………………………………....144、程序运行结果分析…………………………………………………………………..…155、系统不足及改进方案…………………………………………………………………..15参考文献………………………………………………………...………………………….…161.设计概述1.1设计题目小型绘图系统1.2设计要求内容:(1)掌握橡皮筋技术绘制直线、圆;(2)掌握图形对象的拾取技术;功能要求:(1)实现橡皮筋技术绘制直线与圆;(2)设置两种状态:绘图与编辑。编辑状态下实现鼠标左键对直线与圆的拾取,按住鼠标左键可以拖动选择对象使其能平移;1.3设计方案在设计之前先了解掌握本课题所涉及的两种技术:橡皮筋(RubberBand)技术在平面上确定一条直线一般是先定下起点再定下终点,最后把起点和终点连成直线。如果要求这条直线能通过平面上某一点或和一已知圆相切,上述方法便不易做得很准确。所谓橡皮筋技术就是在起点确定后,光标移出去定终点时,在屏幕上始终显示一条连接起点和光标中心的直线,这条直线随着光标中心位置的变动而变动,它就像在起点和光标中心之间紧紧地拉着一根橡皮筋,有了这根橡皮筋便比较容易地找到通过一个点或和一个圆相切的直线的位置。橡皮筋技术除了可以用来画直线外,还可以用来画圆和矩形。橡皮筋技术实际上是简易动画的实现,它不断地进行:画-擦-画的过程。即:(1)从起点到光标中心点(x,y)处画图;(2)擦除起点到光标中心点(x,y)处图形;(3)光标移动到新的位置:x=x+△x,y=y+△y(4)转第(1)步,重复这个过程,直到按下确认键为止。拖动(Drag)技术拖动就是将形体在空间移动。选择拖动功能后,先在作图区用定位设备拾取某个要拖动的物体,再按住键移动光标,则这个被拾取的物体将随着光标的移动而移动,就像光标在拖动物体一样,放开键,物体就固定下来,再移动光标对这个物体就不起作用了。拖动也用到简易动画技术,拖动过程就是不断地进行画、擦、画的过程。通过对橡皮筋技术与拖动技术的掌握,然后开始设计整个流程。根据老师所给的设计要求,应该生成一个通过鼠标右键功能菜单可以画圆与直线,并且对圆与直线进行拖动操作的界面,所以主要步骤应为:(1)程序初始化(2)建立画线、画圆算法,定义鼠标右键功能,定义拖动功能(3)进行绘图操作测试(4)运行调试2.软件设计2.1程序流程框图程序开始初始化建立画线、画圆算法绘制图形定义鼠标右键功能定义拖动功能右键点拖动选择右键点画线右键点画圆对线拖动对圆拖动结束右键生成功能菜单2.2主要算法流程图:Bresenham_Circle算法流程图NYNYsl算法流程图:NYx++;intx,y,d;x=yCirPot(x0,y0,x,y);d0x++;d+=4*x+6d+=4*(x-y)+10;y--returntruereturnfalse(x(x0-10))&&(x(x0+10))&&(y(y0-10))&&(y(y0+10))mouse算法流程图:NYNYNYNNYNYNYNYNYLineCirclebutton==GLUT_LEFT_BUTTON&&state==GLUT_DOWNbutton==GLUT_LEFT_BUTTON&&state==GLUT_DOWNglEnable(GL_LOGIC_OP);edit&&bmglEnable(GL_LOGIC_OP);edit&&bmbm=sl(e,f,x,height-y);bm=sl(e,f,x,height-y);have_square==falsebutton==GLUT_LEFT_BUTTON&&state==GLUT_DOWNbutton==GLUT_LEFT_BUTTON&&state==GLUT_UPa1=a0=x;glutPostRedisplay();button==GLUT_LEFT_BUTTON&&state==GLUT_DOWNbutton==GLUT_LEFT_BUTTON&&state==GLUT_UPx2=x0=x;glBegin(GL_LINES);Y3、程序清单与运行结果3.1程序清单#includestdafx.h#includewindows.h#includeGL/gl.h#includeGL/glu.h#includeGL/glut.h#includeiostreamintx0,y0;intx2,y2;inta0,b0,a1,b1,a,b,c,d,e,f;intwidth;intheight=500;intfirst=500;boolhave_square=false;booledit=false,bm=false;boolLine=false,Circle=false;intr;//对称得到整个圆voiddisplay(void);voidCirPot(intx0,inty0,intx,inty){glBegin(GL_POINTS);glVertex2f(x0+x,y0+y);glVertex2f(x0+x,y0-y);glVertex2f(x0-x,y0+y);glVertex2f(x0-x,y0-y);glVertex2f(x0+y,y0+x);glVertex2f(x0+y,y0-x);glVertex2f(x0-y,y0+x);MultiplexMultiplexglVertex2f(x0-y,y0-x);glEnd();}//Bresenham法画圆voidBresenham_Circle(intx0,inty0,intradius){intx,y,d;x=0;y=int(radius);d=(int)3-2*radius;while(x=y){CirPot(x0,y0,x,y);if(d0)d+=4*x+6;else{d+=4*(x-y)+10;y--;}x++;}}boolsl(intx0,inty0,intx,inty){if((x(x0-10))&&(x(x0+10))&&(y(y0-10))&&(y(y0+10)))returntrue;elsereturnfalse;}voidmouse(intbutton,intstate,intx,inty)//定义鼠标功能{if(Line){if(button==GLUT_LEFT_BUTTON&&state==GLUT_DOWN){bm=sl(e,f,x,height-y);}glEnable(GL_LOGIC_OP);if(edit&&bm){if(button==GLUT_LEFT_BUTTON&&state==GLUT_DOWN){a1=a0=x;b1=b0=height-y;glColor3f(0.0,1.0,0.0);glLogicOp(GL_XOR);first=0;}if(button==GLUT_LEFT_BUTTON&&state==GLUT_UP){glutPostRedisplay();glFlush();glColor3f(0.0,0.0,1.0);glLogicOp(GL_COPY);glBegin(GL_LINES);glVertex2f(x0,y0);glVertex2f(x2,y2);e=e+a1-a0;f=f+b1-b0;glEnd();glFlush();bm=false;}}else{if(have_square==false){if(button==GLUT_LEFT_BUTTON&&state==GLUT_DOWN){x2=x0=x;y2=y0=height-y;glColor3f(0.0,1.0,0.0);glLogicOp(GL_XOR);first=0;}if(button==GLUT_LEFT_BUTTON&&state==GLUT_UP){glBegin(GL_LINES);glVertex2f(x0,y0);glVertex2f(x2,y2);glEnd();glFlush();x2=x;y2=height-y;glFlush();glColor3f(0.0,0.0,1.0);glLogicOp(GL_COPY);glBegin(GL_LINES);glVertex2f(x0,y0);glVertex2f(x2,y2);e=(x2+x0)/2;f=(y2+y0)/2;glEnd();glFlush();have_square=true;}}//elseif(button==GLUT_RIGHT_BUTTON&&state==GLUT_UP)//{//edit=true;//glutPostRedisplay();//first=0;}}}if(Circle){if(button==GLUT_LEFT_BUTTON&&state==GLUT_DOWN){bm=sl(e,f,x,height-y);}glEnable(GL_LOGIC_OP);if(edit&&bm){if(button==GLUT_LEFT_BUTTON&&state==GLUT_DOWN){a1=a0=x;b1=b0=height-y;glColor3f(0.0,1.0,0.0);glLogicOp(GL_XOR);first=0;}if(button==GLUT_LEFT_BUTTON&&state==GLUT_UP){glutPostRedisplay();glFlush();glColor3f(0.0,0.0,1.0);glLogicOp(GL_COPY);glBegin(GL_LINES);glVertex2f(x0,y0);glVertex2f(x2,y2);e=e+a1-a0;f=f+b1-b0;glEnd();glFlush();bm=false;}}else{if(have_square==false){if(button==GLUT_LEFT_BUTTON&&state==GLUT_DOWN){x2=x0=x;y2=y0=height-y;glColor3f(0.0,1.0,0.0);glLogicOp(GL_XOR);first=0;}if(button==GLUT_LEFT_BUTTON&&state==GLUT_UP){glBegin(GL_LINES);glVertex2f(x0,y0);glVertex2f(x2,y2);glEnd();glFlush();x2=x;y2=height-y;r=(x2-x0)*(x2-x0)+(y2-y0)*(y2-y0);for(inti=0;i=r;i++){if(i*i=r){r=i;i=i*i;}}glColor3f(0.0,0.0,1.0);glLogicOp(GL_COPY);Bresenham