用MFC绘制各种数学图形,如sin,cos等_第1页
用MFC绘制各种数学图形,如sin,cos等_第2页
用MFC绘制各种数学图形,如sin,cos等_第3页
用MFC绘制各种数学图形,如sin,cos等_第4页
用MFC绘制各种数学图形,如sin,cos等_第5页
已阅读5页,还剩20页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、*理工大学C+面向对象课程设计报告院(系): 计算机工程学院 专业: 计算机科学与技术 学生姓名: * 班级 计算111 学号: 2011070* 题目: 设计绘制各种数学图形程序 起迄日期: 2013.6.232013.7.5 设计地点: 计算机学院机房 指 导 教 师: * 完成日期: 2013 年7月 5 日目录一、需求分析1 选做此课题的目的.32 程序所实现的功能.3二、 设计内容1 模块图.32 主程序及其主要模块的流程图.33 类图.4 3.1表达式.4 3.2 储存运算符的栈.5 3.3储存运算数的栈.5 3.4 圆.5 3.5 椭圆.6 3.6 三叶玫瑰线.6 3.7 四叶玫

2、瑰线.7 3.8 阿基米德螺线.7 3.9 心形线.74 函数关系图.85 编写程序代码.9三、 调试分析1 实际完成的情况说明.122 程序的性能分析.123 上机过程中出现的问题及其解决方案.124 程序中可以改进的地方说明.13四、 用户手册.13五、 设计总结.15六、 参考文献.15七、 附录.151、 需求分析1. 选作此课题的目的在日常生活中我们常常需要解决一些复杂的数学问题,而这些数学问题的解答往往可以从它的函数图形上很直观、明了的表现出来,这时快捷方便的绘制出该数学函数的图形就显得尤为重要。所以我们使用Microsoft提供的MFC类库来实现数学函数图形的绘制。2 .程序所实

3、现的功能本程序支持用户输入一般表达式,然后输出其对应的函数图形,例如:一次(二次)函数,三角函数,双曲余弦,双曲正弦,双曲正切,幂函数,指数函数(以10为底,以e为底)。另外,还支持一些供选择的数学图形,例如:圆,椭圆,三叶玫瑰线,四叶玫瑰线,阿基米德螺线,心形线。2、 设计内容1. 模块图主界面表达式特殊数学图形阿基米德螺线三叶玫瑰线圆心形线四叶玫瑰线椭圆2. 主程序及主要模块的流程图开始选择图形类型No确定Yes输入表达式或参数图形结束3.类图3.1 表达式CGraphDlgpublic:double Pow(double ,double ); /幂函数求值double Operate(d

4、ouble ,char ,double ); /表达式求值char Precede(char ,char); /判断操作符优先级int In(char ); /判断运算数和运算符void Coordinate(); /求点的集合double Calculate(CString ,double);CGraphDlg(CWnd* pParent = NULL);enum IDD = IDD_GRAPH_DIALOG ;protected:Virtual void DoDataExchange(CDataExchange* pDX);private: ICON m_hIcon;UINT m_num;

5、 /点的数量char *m_stop;CPtrArray m_ptrarray; /点的集合变量CComboBoxm_type; /图形类型CString m_expression; /表达式3.2存储运算符的栈OPTRpublic:OPTR(); /缺省构造函数int InitOPTR(); /构造一个空栈char GetTop(); /返回栈顶元素int Push(char e); /进栈char Pop(); /出栈virtual OPTR(); /析构函数Public: char *base; /栈底指针char *top; /栈顶指针int size; /当前已分配的存储空间3.3存

6、储运算数的栈OPNDpublic:OPND(); /缺省构造函数int InitOPND(); /构造一个空栈double GetTop(); /返回栈顶元素int Push(double e); /进栈double Pop(); /出栈virtual OPND(); /析构函数Public: double *base; /栈底指针double *top; /栈顶指针int size; /当前已分配的存储空间3.4 圆circlepublic: afx_msg void OnChangeEdit1();afx_msg void OnChangeEdit2();afx_msg void OnCh

7、angeEdit3();afx_msg void OnButton1();circle(CWnd* pParent = NULL); enum IDD = IDD_DIALOG1 ;Public: doublem_x; /圆心横坐标doublem_y; /圆心纵坐标doublem_r; /半径 3.5椭圆ellipsepublic: afx_msg void OnChangeEdit1();afx_msg void OnChangeEdit2();afx_msg void OnChangeEdit3();afx_msg void OnChangeEdit4();afx_msg void OnB

8、utton1();ellipse(CWnd* pParent = NULL); enum IDD = IDD_DIALOG2 ;Public: doublem_x; /椭圆中心横坐标doublem_y; /椭圆中心纵坐标doublem_lr; /长轴doublem_sr; /短轴3.6 三叶玫瑰线sanyiepublic: afx_msg void OnChangeEdit1();afx_msg void OnChangeEdit2();afx_msg void OnButton1();sanyie(CWnd* pParent = NULL); enum IDD = IDD_DIALOG3 ;

9、Public: doublem_a; /系数adoublem_b; /角度3.7 四叶玫瑰线siyepublic: afx_msg void OnChangeEdit1();afx_msg void OnChangeEdit2();afx_msg void OnButton1();siye(CWnd* pParent = NULL);enum IDD = IDD_DIALOG4 ;Public: doublem_a; /系数adoublem_b; /角度3.8 阿基米德螺线ajimidepublic: afx_msg void OnChangeEdit1();afx_msg void OnBu

10、tton1();ajimide(CWnd* pParent = NULL);enum IDD = IDD_DIALOG5 ;Public: doublem_a; /系数adoublem_b; /角度3.9 心形线xinxingxianpublic: afx_msg void OnChangeEdit1();afx_msg void OnButton1();xinxingxian(CWnd* pParent = NULL);enum IDD = IDD_DIALOG6 ;Public: doublem_a; /系数a(箭头代表调用)CGraphDlg:OnButton1()4. 函数关系图 CG

11、raphDlg:OnDrawing()类ajimide类sanyie类circle类siye类xinxingxian类ellipseCGraphDlg:Coordinate()circle:OnButton1() sanyie:OnButton1() CGraphDlg:Calculate(CString m_expression,double x)ellipse:OnButton1() xinxingxian:OnButton1() siye:OnButton1() ajimide:OnButton1()OPND:Push(double e)OPND:GetTop()OPND:InitOPN

12、D()OPTR:GetTop()OPTR:InitOPTR()OPND:Pop()OPTR:GetTop()OPTR:Push(char )CGraphDlg:In(char ch)CGraphDlg:Precede(char s,char c)CGraphDlg:Operate(double,char,double )CGraphDlg:Pow(double, double )5. 编写程序代码 1画坐标轴CClientDC dc(this);CRect rect; GetClientRect(&rect) ; dc.SetMapMode(MM_LOMETRIC) ; /设置映射模式

13、;dc.SetWindowOrg(0,0) ; /设置屏幕窗口原点;dc.SetViewportOrg(CPoint(rect.right/2,rect.bottom/2) ; /设置视口原点CPen pen1(PS_DOT,1,RGB(100,100,100); /创建笔,并调整坐标颜色CPen *pOldPen = dc.SelectObject(&pen1); /更改笔并保存旧的笔for(int i=-900;i<=900;i+=50) dc.MoveTo (i,500); dc.LineTo (i,-500); for(int j=-500;j<=500;j+=50

14、)dc.MoveTo (-900,j); dc.LineTo (900,j); dc.TextOut (10,500,'y'); /标记y轴dc.TextOut (870,0,'x'); /标记x轴dc.TextOut (0,0,'0'); /标记坐标原点dc.TextOut (-8,510,'');dc.TextOut (900,25,'>');CPen pen(PS_SOLID,1,RGB(0,0,0);/创建笔,并调整坐标颜色pOldPen = dc.SelectObject(&pen);/更改

15、笔并保存旧的笔dc.MoveTo (-900,0); /横坐标dc.LineTo (900,0); dc.MoveTo (0,-500); /纵坐标dc.LineTo (0,500);2. 选择图形类型 /默认是表达式 RedrawWindow();m_expression=""UpdateData(FALSE);CString text;m_type.GetWindowText(text);if(text="圆")circle d_circle; d_circle.DoModal(); /显示画圆的对话框else if(text="椭圆&qu

16、ot;)ellipse d_ellipse;d_ellipse.DoModal(); /显示画椭圆的对话框else if(text="三叶玫瑰线")sanyie d_sanyie;d_sanyie.DoModal(); /显示画三叶玫瑰线的对话框else if(text="四叶玫瑰线")siye d_siye;d_siye.DoModal(); /显示画四叶玫瑰线的对话框else if(text="阿基米德螺线")ajimide d_ajimide;d_ajimide.DoModal(); /显示画阿基米德螺线的对话框else if(

17、text="心形线")xinxingxian d_xinxingxian;d_xinxingxian.DoModal(); /显示画心形线的对话框3. 根据表达式画出图形for(m_num-=1;m_num>0;m_num-) /从点集合中依次取出点并且相连dc.MoveTo (CPoint *)m_ptrarray.GetAt(m_num)->x, (CPoint *)m_ptrarray.GetAt(m_num)->y);dc.LineTo (CPoint *)m_ptrarray.GetAt(m_num-1)->x, (CPoint *)m_p

18、trarray.GetAt(m_num-1)->y);4. 画圆dc.Ellipse(m_x-m_r)*50,(m_y+m_r)*50,(m_x+m_r)*50,(m_y-m_r)*50); /调用Ellipse函数5. 画椭圆dc.Ellipse(m_x-m_lr)*50,(m_y+m_sr)*50,(m_x+m_lr)*50,(m_y-m_sr)*50); /调用Ellipse函数6. 画三叶玫瑰线double x=0,y=0;dc.MoveTo (0,0); /从原点开始画for(double p=-3.14;p<=3.14;p+=0.01) /计算点的同时画线x=m_a*c

19、os(3*(m_b+p)*cos(p);y=m_a*cos(3*(m_b+p)*sin(p);dc.LineTo(50*x,50*y);dc.MoveTo(50*x,50*y); dc.SelectObject(&pen);7. 画四叶玫瑰线double x=0,y=0;dc.MoveTo (0,0); /从原点开始画for(double p=-3.14;p<=3.14;p+=0.01) /计算点的同时画线x=m_a*sin(2*(m_b+p)*cos(p);y=m_a*sin(2*(m_b+p)*sin(p);dc.LineTo(50*x,50*y);dc.MoveTo(50*

20、x,50*y); dc.SelectObject(&pen);8. 画阿基米德螺线double p=-10;double x=0,y=0;x=m_a*p*cos(p);y=m_a*p*sin(p);dc.MoveTo (x*20,20*y);for( p=-10;p<=10;p+=0.01) /计算点的同时画线x=m_a*p*cos(p);y=m_a*p*sin(p);dc.LineTo(20*x,20*y);dc.MoveTo(20*x,20*y); dc.SelectObject(&pen);9. 画心形线double x=0,y=0;dc.MoveTo (0,0);

21、 /从原点开始画for(double p=-3.14;p<=3.14;p+=0.01) /计算点的同时画线x=m_a*(1-cos(p)*cos(p);y=m_a*(1-cos(p)*sin(p);dc.LineTo(50*x,50*y);dc.MoveTo(50*x,50*y); dc.SelectObject(&pen);3、 调试分析1. 实际完成的情况说明(完成的功能、支持的数据类型等) 本程序支持用户选择数学图形类型并输入相应的参数,然后输出其对应的函数图形。当选择表达式时,用户输入表达式,例如:一次(二次)函数,三角函数,双曲余弦,双曲正弦,双曲正切,幂函数,指数函数

22、(以10为底,以e为底),点击图形按钮输出图形。当选择的数学图形时,例如:圆,椭圆,三叶玫瑰线,四叶玫瑰线,阿基米德螺线,心形线,弹出其对应的对话框,用户输入参数,点击画图按钮输出图形。此程序输入的参数可以是int类型,也可以是double类型。2. 程序的性能分析本程序中为不同的数学图形定义了相应的对话框,运行程序时选择不同的图形对应不同的对话框,使程序更加清晰明了。本程序根据不同的图形建立了不同的类,这样保证程序的封装性。而且,这样使程序便于阅读。3. 上机过程中出现的问题及其解决方案在类CGraphaelDlg中调用类OPTR和类OPNE中的函数时编译出错。解决方案:在类CGraphDl

23、g的添加OPTR和OPND的头文件。在coordinate()定义Cpoint point2000并将其地址保存到变量m_ptrarray中,点击画图按钮调用Ondrawing()函数,结果没有图形输出。解决方案:coordinate()定义Cpoint point2000,在函数coordinate()结束前point的内存被释放,所以数组没有被保存。应该采用new进行如下定义Cpoint *point;point=new CPoint2000;使用sin,cos等数学函数时,提示未定义。解决方案:将头文件“math.h”包含到程序中。在调用OPTR和OPND的pop()函数,push()函

24、数,gettop()函数时,程序中止运行。解决方案:在使用栈之前应按分解先调用InitOPTR()函数和InitOPND()函数定义两个空栈。使用头文件“math.h”中的pow(double a,double b)函数时,输出有误。解决方案:当b为负数时,pow(double a,double b)的计算结果是一个复数,所以输出有误。自己定义一个Pow(double a,double b)函数,对b进行判断,当b是负数时取pow(a,-b)的倒数。4. 程序中可以改进的地方说明以及可以扩充的功能本程序不支持自加自减运算,所以可以增加此项功能。本程序在画指数图形时,仅仅支持以e为底和以10为底

25、的指数函数。可以扩展一下指数函数的功能。本程序的运行界面太单调,可以改变一下背景图片,增加用户使用时的舒适度。本程序不支持用户改变线条类型,线条颜色。为了适应不同的用户,这方面需要改进。4、 用户手册第一步:选择所要绘制图形的类型,点击“确定”按钮,如图选择“表达式”第二步:如果第一步选择表达式,则在右边的编辑框中输入表达式,然后点击“画图”按钮即可。如果第一步选择其他类型,例如“心形线”,则会弹出相应的对话框,输入相应的参数,然后点击“图形”按钮即可,如下图:第三步:点击“退出”按钮,回到初始界面,然后点击”X”号退出程序。5、 设计总结 通过两周对C+面向对象程序设计的课程设计(绘制各种数

26、学图形)的研究主要有以下几点感受:首先,C+面向对象程序设计课程设计很好的反映了自己这一学期对C+面向对象程序设计基础知识的掌握情况,让自己清醒的认识到自己的真实水平。不动手不知道,自己亲自动手设计程序时才感觉到知识的不扎实。有的知识虽然已经学过,但是用起来还是感觉有点模糊,这也算是给自己的一个警醒吧。另外,刚开始学习MFC感觉很难,通过对在网上查找的视频以及在学校图书馆借阅的有关图书的学习渐渐地对MFC有了一个初步的认识,随着课设的一点点深入,自己对MFC的掌握也越来越好,最后完成课设要求。这个过程不仅会拓宽自己的知识面,还会提高自己的自学能力。同时,宿舍里的同学集体讨论如何去实现各种功能,

27、各自发表看法彼此交流也是一种学习的过程。最深刻的感受就是编写程序过程中的酸甜苦辣。刚开始构思时漏洞百出,程序出错。但是令人高兴的是通过不断的调试程序,不断的出错,然后不断的修改,从这过程中学到了一些调试程序的技巧。虽然有些语句没有语法错误,但是如果语句顺序不对也会提示错误 。经过痛苦又快乐的调试过程之后,当自己自如的运行着程序时成就感十足啊!顿时感觉之前付出的一切值了,实在是值了。总之,我感觉C+面向对象程序设计课程设计在锻炼我们查阅资料以及提高编程技巧方面很有用。课程设计提高了我们的动手能力,我们能将课本上的死知识灵活地应用到生活当中,还有就是能够感受到十足的成就感,增加学习专业课的兴趣。6

28、、 参考文献李兰、任凤华C+面向对象程序设计西安电子科技大学出版社姚领田、高守传MFC窗口程序设计中国水利水电出版社吴乃玲、李海文C+程序设计实践教程(第二版)高等教育出版社孙鑫 孙鑫C+教程7、 附录1. 判断运算符和运算数int CGraphDlg:In(char ch)if(ch='+'|ch='-'|ch='*'|ch='/'|ch='('|ch='#'|ch=')'|ch='s'|ch='c'| ch='t'|ch='

29、l'|ch='h'|ch='H'|ch='T'|ch='') /操作符return 1; else if(ch='0'|ch='1'|ch='2'|ch='3'|ch='4'|ch='5'| ch='6'|ch='7'|ch='8'|ch='9'|ch='x') /操作数return 2; else /非法操作符flag=3;return 3;2.

30、判断运算符优先级char CGraphDlg:Precede(char s,char c)switch(s) case '+': case '-': if(c='+'|c='-') return '>' /先出现的+-优先级大于相继出现的+- else if(c='*'|c='/') return '<' /先出现的+-优先级小于相继出现的*/ else if(c='(') return '<' /先出现的+-优先级小

31、于相继出现的( else if(c=')') return '>' /先出现的+-优先级大于相继出现的) else if(c='s'|c='c'|c='t'|c='C'|c='l'|c='L'|c='h'|c='H'|c='T'|c='') return '<' /先出现的+-优先级小于相继出现的三角函数 /指数、幂函数运算符 else if(c='#') /表

32、达式结束标志 return '>' case '*': case '/': if(c='+'|c='-') return '>' else if(c='*'|c='/') return '>' else if(c='(') return '<' else if(c=')') return '>' else if(c='s'|c='c&#

33、39;|c='t'|c='C'|c='l'|c='L'|c='h'|c='H'|c='T'|c='') return '<' else if(c='#') return '>' case '(': if(c='+'|c='-') return '<' else if(c='*'|c='/') return &

34、#39;<' else if(c='(') return '<' else if(c=')') return '=' else if(c='s'|c='c'|c='t'|c='C'|c='l'|c='L'|c='h'|c='H'|c='T'|c='') return '<' else if(c='#') return

35、 'E' case ')': if(c='+'|c='-') return '>' else if(c='*'|c='/') return '>' else if(c='(') return 'E' else if(c=')') return '>' else if(c='s'|c='c'|c='t'|c='C'|c=

36、9;l'|c='L'|c='h'|c='H'|c='T'|c='') return 'E' else if(c='#') return '>' case '#': /运算符栈底元素,即表达式开始标志 if(c='+'|c='-') return '<' else if(c='*'|c='/') return '<' else if(

37、c='(') return '<' else if(c=')') return 'E' else if(c='s'|c='c'|c='t'|c='C'|c='l'|c='L'|c='h'|c='H'|c='T'|c='') return '<' else if(c='#') return '='case '

38、s':case 'c':case 't':case 'C':case 'l':case 'L':case 'h':case 'H':case 'T': if(c='+'|c='-') return '>' else if(c='*'|c='/') return '>' else if(c='(') return '<'

39、; else if(c=')') return '>' else if(c='s'|c='c'|c='t'|c='C'|c='l'|c='L'|c='h'|c='H'|c='T') return 'E' else if(c='') return '<' else if(c='#') return '>'case '&

40、#39;: if(c='+'|c='-') return '>' else if(c='*'|c='/') return '>' else if(c='(') return '<' else if(c=')') return '>' else if(c='s'|c='c'|c='t'|c='C'|c='l'|c='L'

41、|c='h'|c='H'|c='T') return 'E' else if(c='') return '<' else if(c='#') return '>' default: break;return 'E' /错误提示3. 根据运算符优先级进行运算符和运算数进栈、出栈、计算操作double CGraphDlg:Calculate(CString m_expression,double x)double a=0,b=0;char *p

42、,e;OPTR s; /定义OPND对象存放运算符OPND q; /定义OPND对象存放运算数s.InitOPTR (); /定义一个空栈q.InitOPND (); /定义一个空栈p=m_expression.GetBuffer (100); /将CString类型的表达式转换成char *类型s.Push('#'); /将#进栈作为表达式开始的标志while(*p!='#'|s.GetTop()!='#') /当栈底的#碰到栈顶的#表示结束if(In(*p)=3) /非法操作符return 0;else if(In(*p)=2&&am

43、p;flag=0) /运算数double A;if(*p='x')q.Push (x);p+;elseA=strtod(p,&m_stop); /提取表达式中的操作数q.Push (A);p=m_stop;elseswitch(Precede(s.GetTop(),*p) /判断运算符优先级case '<': /当前运算符的优先级低前一个运算符,进栈if(*p='s'&&*(p+1)='h') /运算符双曲正弦shs.Push ('h');p+;p+;break;else if(*p=

44、'c'&&*(p+1)='h') /运算符双曲余弦chs.Push ('H');p+;p+;break;else if(*p='t'&&*(p+1)='h') /运算符双曲正切ths.Push ('T');p+;p+;break;else if(*p='l'&&*(p+1)='n') /运算符lns.Push ('l');p+;p+;break;else if(*p='l'&&am

45、p;*(p+1)='g') /运算符lgs.Push ('L');p+;p+;break;else if(*p='c'&&*(p+1)='o'&&*(p+2)='t') /运算符cots.Push ('C');p+;p+;p+;break;else if(*p='s'&&*(p+1)='i'&&*(p+2)='n'|*p='c'&&*(p+1)='o'&&*(p+2)='s'|*p='t'&&*(p+1)='a'&&*(p+2)='n') /运算符sin,cos,tans.Push (*p);p+;p+;p+;break;else if(*p='('&&(*(p+1)='#'|*(p+1)='+'|*(p+1)='-'|*(p+1)='*'|*(p+1)='/'|*(p+1)=''|*(p

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论