




已阅读5页,还剩6页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
北京邮电大学信息与通信工程学院程序设计实践设计报告课题名称:实验一画图程序 1 课题概述 1.1课题目标和主要内容 1.1.1主要内容和目标: A. 基本功能界面中使用鼠标画点、圆、线等功能(使用菜单选择画什么即可)设置颜色(使用菜单设定几种颜色即可)保存,打开bmp文件选做功能保存,打开自定义格式文件图像二值化、平滑、连通域标记等 B.目标 对windows程序编程有一个初步的认识,对其消息处理体制有初步理解,掌握编程工具如vs的调试方法,熟练使用1.1.2编译环境:visual studio 2012 1.2系统的主要功能 功能列表或功能框图,以及功能的简要说明。2. 系统设计 2.1 系统总体框架 包括系统框架图或层次逻辑图,设计思想等 winmain.cpp:系统消息的获得与处理Graphicwindow.h:类的定义Graphicwindow.cpp:类中函数的定义fig.rc、resource.h:完成菜单的添加ccc_shap.h、ccc_shape.cpp完成图形类的定义test.h:实现画图函数的声明test.cpp:实现画图函数的声明 2.2 系统详细设计1 类关系图及描述 2 程序流程图及描述 winmain.cpp对接收到的消息进行处理,进而根据消息调用相应类函数,类函数中真正画图函数的实现在test.cpp中 3 存储结构、内存分配 定义了全局栈vector1,对鼠标移动中的坐标点进行记录 定义全局point 类型,对鼠标左键up和down时的坐标点进行记录 以下均为全局变量: int WIDTH=3,RORTR=1; /WIDTH方便改变线条粗细,RORTR判断是输出圆还是椭圆Point endot,bedot; /分别记录终点和起点,用于画直线、圆、椭圆、长方形COLORREF mmcolor=RGB(0,0,0); /线条颜色COLORREF ficolor=RGB(0,0,0); /填充颜色 2.3 关键算法分析 算法一: case WM_MOUSEMOVE: /记录鼠标移动过程的点int x=LOWORD(lParam);int y=HIWORD(lParam);if (wParam&MK_LBUTTON) /鼠标在移动过程中按着LBUTTON和SHIFT键logoutput(鼠标在移动过程中按着LBUTTON和SHIFT键);vector1.push_back(Point(x,y);InvalidateRect(hwnd,NULL,TRUE);break; 根据系统以及定义好的消息WM_MOUSEMOVE,每当鼠标移动变回收到这个消息,进而将鼠标轨迹中的点压入栈中 算法二: case WM_LBUTTONDOWN: /记录起点int x=LOWORD(lParam);int y=HIWORD(lParam);bedot=Point(x,y); 获得按下鼠标左键时的点,以便在画直线、圆、椭圆时应用 相似的可以利用WM_LBUTTONUP消息获得算法三:void mydot(GraphicWindow & cwin) /画点extern COLORREF mmcolor;for (int i=0;ivector1.size();i+)Point x =vector1i;Point x1(cwin.disp_to_user_x(x.get_x(),cwin.disp_to_user_y(x.get_y();x1.SetColor(mmcolor);cwin x1; 从栈中取点并画出,同时通过SetColor()来设置颜色。 时间复杂度:n 空间复杂度:n算法四:void myline(GraphicWindow & cwin) /画线extern int WIDTH;extern COLORREF mmcolor;for (int i=0;ivector1.size();i+) Point be =vector1i;Point x1(cwin.disp_to_user_x(be.get_x(),cwin.disp_to_user_y(be.get_y();if(i+1vector1.size()Point en=vector1i+1;Point x2(cwin.disp_to_user_x(en.get_x(),cwin.disp_to_user_y(en.get_y();Line A(x1,x2);A.SetColor(mmcolor);cwinA;将vector1中的点依次用直线连接,因为每两个点之间间隔非常小,所以最终达到画出曲线的效果时间复杂度:n 空间复杂度:n算法五: void mydline(GraphicWindow & cwin) /直线extern COLORREF mmcolor;extern Point endot;extern Point bedot; extern int WIDTH;Point be =bedot;Point x1(cwin.disp_to_user_x(be.get_x(),cwin.disp_to_user_y(be.get_y();Point en=endot;Point x2(cwin.disp_to_user_x(endot.get_x(),cwin.disp_to_user_y(endot.get_y();Line A(x1,x2);A.SetColor(mmcolor);A.b=WIDTH;cwinA;bedot和endot分别为鼠标左键按下和抬起时的点,用这两个点来为line对象初始化,作为起点和终点,通过setcolor()来设置线的颜色,WIDTH改变线的粗细。时间复杂度:1 空间复杂度:1算法六:void myrec(GraphicWindow & cwin) /画长方形extern COLORREF mmcolor;extern Point endot;extern Point bedot;Point be =bedot;Point x1(cwin.disp_to_user_x(be.get_x(),cwin.disp_to_user_y(be.get_y();Point en=endot;Point x2(cwin.disp_to_user_x(endot.get_x(),cwin.disp_to_user_y(endot.get_y();Rectan A(x1,x2);A.SetColor(mmcolor);cwinA;完成画长方形的工作首先要定义长方形类:Rectan(具体定义参见test.h和test.cpp),同时也要进行运算符重载(具体参见GraphicWindow.cpp);此处是完成对象初始化工作。bedot 和endot 分别为长方形的左上角和右下角,以此完成对象初始化,可以获得长方形的左上右下坐标。时间复杂度:1 空间复杂度:1算法七:void myround(GraphicWindow & cwin) /画圆或椭圆extern COLORREF mmcolor;extern Point bedot,endot;extern int RORTR;Point x1(cwin.disp_to_user_x(bedot.get_x(),cwin.disp_to_user_y(bedot.get_y(); Point x2(cwin.disp_to_user_x(endot.get_x(),cwin.disp_to_user_y(endot.get_y();double a=x1.get_x()-x2.get_x(),b=x1.get_y()-x2.get_y();double c=pow(a,2)+pow(b,2);double r=sqrt(c);TCircle tcir(x1 ,r);Circle cir(x1,r);cir.SetColor(mmcolor);if(RORTR=1)cwincir;elsecwintcir;bedot为圆心,endot为边界点,通过两者获得半径,然后对Circle或者Tcircle对象进行初始化此处通过全局变量RORTR来判断输出圆还是椭圆,而RORTR是在消息处理时会进行赋值操作。时间复杂度:1 空间复杂度:1算法八:case ID_LINE: /画最细自由线消息bedot=Point(NULL ,NULL); endot=Point(NULL,NULL);menuId=ID_LINE;InvalidateRect(hwnd,NULL,TRUE);break;此处要对bedot=Point(NULL ,NULL); endot=Point(NULL,NULL);,以避免再画其他图形时将之前的bedot和endot连接起来。相似的在画圆、椭圆时也要做类似处理。时间复杂度:1 空间复杂度:1 2.4 其它 在定义画图形状类时,运用了类的继承,使类的定义代码更为简化。 运算符重载是画图主体实现代码更为简洁,也便于编写。 3. 程序运行结果分析 3.1输出显示方式:窗口3.2主要界面:3.3操作流程:点击以上菜单中选项,然后在窗口中进行操作3.4运行效果: 。4. 总结 4.1课题的难点和关键点 关键点:理解windows编程,特别是消息处理方式,因为对此没有认识导致前两次课一直在看ppt,向老师、同学请教。 难点:a).调试方法:因为windows并行处理,不同与之前编程的逐步进行,给调试带来一定难度,我所采用的方式是设置较多断点,加入判别变量,但到现在仍未很好掌握调试方法。b).画圆:所希望的效果是:圆随着鼠标的移动,大小也随之变化并显示在屏幕上,并且可以画多个圆。起初想到两种实现方式:vector来实现能达到动态显示,但是一个缺点是不能使圆有大变小。如果刷屏则其他图形也会消失,显然这并不是我们所期望的。通过全局变量point来实现,可以实现画多个圆,但是却不能动态显示。和同学交流,但最终也没有找到好的解决方案,权衡之下选择了第二种方案。c).因为在左键按下和抬起时会记录下点,这样将会对下次绘图产生影响,起初是用全局int类型变量i来进行判断是否要记录,但这样的话只有选用多个int型变量才能达到效果。优化:放弃上一种方式,而是在画图消息传过来是将全局point初始化为(NULL,NULL),更为简洁,同时也减小了逻辑错误产生的可能性。4.2 本课题的评价该课题难度不大,但是对于windows编程入门的我们来说难度是适中的,对于学生理解windows编程的基础知识提供很大帮助,从较简单的入手一方面便于理解同时也更容易为学生培养信心。对于自身,现对windows变成有了初步了解,尤其是消息处理机制等,但是对于细节仍然有不熟悉
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论