您好,欢迎来到抵帆知识网。
搜索
您的当前位置:首页北邮程序设计实践——画图

北邮程序设计实践——画图

来源:抵帆知识网
北京邮电大学信息与通信工程学院

程序设计实践

设 计 报 告

课题名称:实验一画图程序

第1页

北京邮电大学信息与通信工程学院

1. 课题概述

1.1课题目标和主要内容

1.1.1主要内容和目标:

A. 基本功能

界面中使用鼠标画点、圆、线等功能(使用菜单选择画什么即可)

设置颜色(使用菜单设定几种颜色即可)

保存,打开bmp文件

选做功能

保存,打开自定义格式文件

图像二值化、平滑、连通域标记等

B.目标

对windows程序编程有一个初步的认识,对其消息处理有初步理解,掌握编程工具如vs的调试方法,熟练使用

1.1.2编译环境:visual studio 2012

第2页

北京邮电大学信息与通信工程学院

1.2系统的主要功能

功能列表或功能框图,以及功能的简要说明。

2. 系统设计 2.1 系统总体框架

包括系统框架图或层次逻辑图,设计思想等

winmain.cpp:系统消息的获得与处理

Graphicwindow.h:类的定义

第3页

北京邮电大学信息与通信工程学院

Graphicwindow.cpp:类中函数的定义

fig.rc、resource.h:完成菜单的添加

ccc_shap.h、ccc_shape.cpp完成图形类的定义

test.h:实现画图函数的声明

test.cpp:实现画图函数的声明

2.2 系统详细设计

[1] 类关系图及描述

第4页

北京邮电大学信息与通信工程学院

[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); //填充颜色

第5页

北京邮电大学信息与通信工程学院

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);

第6页

北京邮电大学信息与通信工程学院

break;

根据系统以及定义好的消息—WM_MOUSEMOVE,每当鼠标移动变回收到这个消息,进而将鼠标轨迹中的点压入栈中

算法二:

case WM_LBUTTONDOWN: //记录起点

{

int x=LOWORD(lParam);

int y=HIWORD(lParam);

bedot=Point(x,y);

}

获得按下鼠标左键时的点,以便在画直线、圆、椭圆时应用

相似的可以利用WM_LBUTTONUP消息获得

算法三:

void mydot(GraphicWindow & cwin) //画点

第7页

北京邮电大学信息与通信工程学院

{

extern COLORREF mmcolor;

for (int i=0;i{

Point x =vector1[i];

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

算法四:

第8页

北京邮电大学信息与通信工程学院

void myline(GraphicWindow & cwin) //画线

{

extern int WIDTH;

extern COLORREF mmcolor;

for (int i=0;i{

Point be =vector1[i];

Point x1(cwin.disp_to_user_x(be.get_x()),cwin.disp_to_user_y(be.get_y()));

if(i+1{Point en=vector1[i+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);

第9页

北京邮电大学信息与通信工程学院

cwin<}

将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()));

第10页

北京邮电大学信息与通信工程学院

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;

cwin<}

bedot和endot分别为鼠标左键按下和抬起时的点,用这两个点来为line对象初始化,作为起点和终点,通过setcolor()来设置线的颜色,WIDTH改变线的粗细。

时间复杂度:1 空间复杂度:1

算法六:

void myrec(GraphicWindow & cwin) //画长方形

{

第11页

北京邮电大学信息与通信工程学院

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);

cwin<}

完成画长方形的工作首先要定义长方形类:Rectan(具体定义参见test.h和test.cpp),同时也要进行运算符重载(具体参见GraphicWindow.cpp);此处是完成对象初始化工作。

第12页

北京邮电大学信息与通信工程学院

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);

第13页

北京邮电大学信息与通信工程学院

double r=sqrt(c);

TCircle tcir(x1 ,r);

Circle cir(x1,r);

cir.SetColor(mmcolor);

if(RORTR==1)

cwin<else

cwin<}

bedot为圆心,endot为边界点,通过两者获得半径,然后对Circle或者Tcircle对象进行初始化

此处通过全局变量RORTR来判断输出圆还是椭圆,而RORTR是在消息处理时会进行赋值操作。

时间复杂度:1 空间复杂度:1

第14页

北京邮电大学信息与通信工程学院

算法八:

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. 程序运行结果分析

第15页

北京邮电大学信息与通信工程学院

3.1输出显示方式:窗口

3.2主要界面:

3.3操作流程:点击以上菜单中选项,然后在窗口中进行操作

第16页

北京邮电大学信息与通信工程学院

3.4运行效果: 。

4. 总结

4.1课题的难点和关键点

关键点:理解windows编程,特别是消息处理方式,因为对此没有认识导致前两次课一直在看ppt,向老师、同学请教。

难点:

a).调试方法:因为windows并行处理,不同与之前编程的逐步进行,给调试带来一

第17页

北京邮电大学信息与通信工程学院

定难度,我所采用的方式是设置较多断点,加入判别变量,但到现在仍未很好掌握调试方法。

b).画圆:所希望的效果是:圆随着鼠标的移动,大小也随之变化并显示在屏幕上,并且可以画多个圆。

起初想到两种实现方式:①vector来实现能达到动态显示,但是一个缺点是不能使圆有大变小。如果刷屏则其他图形也会消失,显然这并不是我们所期望的。②通过全局变量point来实现,可以实现画多个圆,但是却不能动态显示。

和同学交流,但最终也没有找到好的解决方案,权衡之下选择了第二种方案。

c).因为在左键按下和抬起时会记录下点,这样将会对下次绘图产生影响,起初是用全局int类型变量i来进行判断是否要记录,但这样的话只有选用多个int型变量才能达到效果。

优化:放弃上一种方式,而是在画图消息传过来是将全局point初始化为(NULL,NULL),更为简洁,同时也减小了逻辑错误产生的可能性。

4.2 本课题的评价

该课题难度不大,但是对于windows编程入门的我们来说难度是适中的,对于学生理解windows编程的基础知识提供很大帮助,从较简单的入手一方面便于理解同时也更容易为学生培养信心。

对于自身,现对windows变成有了初步了解,尤其是消息处理机制等,但是对于细节仍然有不熟悉的地方,需要之后进行深入学习,争取全面理解。

第18页

北京邮电大学信息与通信工程学院

4.3心得体会

通过本次画图程序实验,对Windows编程有了更多的了解,提升了自己调试程序的能力。当面临一种新的内容时,不可避免会产生不解。但是只要耐心一点一点找到头绪便不难弄懂。在具体编程中遇到一些问题比如画圆的实现,以及线条粗细等,通过查阅资料和同学讨论最终迎刃而解,那种感觉是美妙的。但程序中仍存在一些不足的地方需要后续改进。

5. 参考文献

[1]徐惠民等编著,《C++高级语言程序设计》,[TP]人民邮电出版社,2011版

第19页

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- dfix.cn 版权所有 湘ICP备2024080961号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务