




已阅读5页,还剩27页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
毕业设计(论文) 1实现图形系统的文档和视图1.1组织矢量图形系统的图形元素类城市的信息化为城市GIS发展带来了机遇。实际上,城市信息化表现为政府管理与决策的信息化(数字政府),企业管理、决策与服务的信息化(数字企业),市民生活的信息化(数字城市生活),即“数字城市”。由此可见,城市GIS是“数字城市”最核心的部分,可以分为政府GIS、企业GIS和社会GIS。“数字城市”的发展,要求政府、企业和社会GIS通过数据通信网络将政府、企业和社会联成一个整体,实现资源的共享。历史给了我们中国人特殊的超越他人的机遇。美国人、加拿大人、西欧人在通讯基础设施,政府、企业信息系统建设,信息系统互联互通,以及网络社会、网络社区四个阶段循序渐进的发展中占尽先机。但是当时的3维GIS技术、VR技术、4D数据融合集成技术、GIS三维表现技术都没有像今天这样成熟和廉价。访遍美国、西欧、加拿大、澳洲的城市政府网站,基于4D数据、三维表现、借助虚拟现实技术的凤毛麟角。时间和市场为我们创造了超越的重大历史机会。这个机会就是数字城市中三维和VR技术的开发和应用。抓住机遇,我国的数字城市将大放异彩。我们认为中国的数字城市特色应该定位在:建设具有4D数据的城市基础地理信息公共平台;建设以3维和VR技术为主的城市规划、建设和管理业务专业应用系统。集中抢占数字城市“43VR”的技术应用战略制高点,形成中国数字城市“43VR”的特色,开拓中国数字城市独特的市场空间10。面向对象的程序设计,是目前程序设计的主流方法,在本设计中,将利用面向对象的程序设计和C+类的组织方法,组织建立一个基本矢量图形的图形元素类。组织实现的矢量图形系统,能够处理点类、线类、面类、网络点等类别的图形元素,其中点类图形元素有包括直线,圆,圆弧,子图,标注文本等图形元素,针对每类图形元素组织建立起对其进行管理的C+类,并把每个图形元素作为一个独立的对象来管理。1.1.1图形元素基类的组织对各类图形元素进行分析,可以发现各类图形元素具有一些相同的属性和操作功能,如图形元素的颜色、线型线宽所在层等属性和得到一个图形元素是否做了删除标志等操作。把这些图形元素中共性的东西(属性和操作),组织存放在一个图形元素基类(CDraw)中,具体的图形元素由这个基类来派生。1.1.2点类图形元素组织5对于点类图形元素,其基本特性是各个图形相互独立,且每个图形元素具有有限个固定的特征点。直线的基类是CDraw.,在直线类的构造函数中,共有包括11个参数,并利用前7个参数调用基类CDraw的构造函数,对基类的成员变量进行初始化,而在本身的构造函数中对直线类CLine自身的四个参数(直线的起点和终点)进行了初始化。对圆类的创建方法与直线类CLine 类似,圆除了具有图形元素的基本特征外,还有自身的几何特性,可以用圆心和半径作为特征参数表示圆的几何特性。圆是圆弧的一个特例,当圆弧的弧度等于2时就是圆。所以可以从一个圆类派生得到一个圆弧类。矢量图形中可以有大量的标注文本,标注文本除了具有图形元素的基本特性外,还具有位置、字体及标注内容等自身的信息。CText类也有两个构造函数,第二个构造参数有多个参数,并利用多个参数对类的成员变量进行初始化。在构造函数中,调用了基类CDraw的构造函数对基类CDraw的成员变量进行初始化。子图是各类图形元素的集合体,是由多个图形元素组成的整体。为了在图形中插入子图,必须首先建立起管理子图所包含的图形元素的类,形成一个子图定义体,将选定的子图块以一定的横纵比例插入到图形中指定的位置,就形成了一个子图块。1.1.3线类图形元素组织线类图形元素包括很多种,如连续直线、混合线、树状线等,在本设计中,以最简单的连续直线为例进行讨论,对于其他类型线的实现方法,可根据连续直线的实现方法来开发。连续直线除了具有图形元素基类所具有的属性外,从图形的几何特征上,连续直线是由很多顶点组成的,而且顶点数目是不确定的。一条连续直线可能只有两个顶点,也可能有几千个顶点。所以,需要定义一个结构来存储连续直线的一个顶点坐标。1.1.4面类图形元素的组织10面类图形元素一般是由闭合线围成的区域。根据围成面的边界不同,有不同形式的面,如圆形区域椭圆形区域复合线区域多边形区域等。最常用的面是多边形区域,其边界由一条连续直线组成。因为另外各种类型面的边界一般都可以用连续直线来近似描述,所以,本设计只讨论多边形区域的实现方法。在描述多边形区域时,最主要的是要描述边界顶点坐标。描述面的边界顶点坐标时,有不同的描述方法,一种方法是将边界由几段连续直线来描述。另外一种描述方法是直接存储区域的边界顶点坐标,即把区域的整个边界作为一条连续直线来存储。这种方法的缺点是造成坐标的重复存储;优点是具有较强的独立性,不用考虑组成区域的连续直线段。在本设计中,采用直接存储边界坐标的方式。用这种方式组织多边形区域时,组织方式与连续直线类似。所以,可以由连续直线类CPline派生出一个CPlineRgn类,来对多边形区域进行管理。1.1.5网络类图形元素的组织网络分析是GIS的一项非常重要的基本功能,最佳路径分析、最佳游历路径分析、连通分析、资源分配等都需要有网络类图形元素对网络进行描述、显示和分析。为了能够对网络进行描述和处理,在系统中增加一类图形元素来描述有方向、无转角的网络图。这类图形元素称为网络点。1.1.6图形参数类在矢量图形系统中,图形参数是集中存储的。在图形元素基类中成员变量m_ColorPen,m_ColorBrush等存储的是颜色列表的序列号,m_Layer中存储的也是在图层列表中的序列号。1.2组织矢量图形系统的文档1.2.1组织面向对象的文档管理机制管理矢量图形系统图形数据的方法即文档管理机制。在本设计的开发中,采用一套完全面向对象的文档组织机制。这种机制就是通过图形元素类创建很多图形元素对象,每个图形元素对象作为一个整体来组织存储空间的分配、存取等各种管理功能。然后通过建立一种存储机制,来管理指向所有图形元素对象的指针,达到管理所有图形元素对象的目的。这种文档管理机制具有组织简单结构化和移植性好,以及比较容易利用VC+程序设计语言的开发功能等优点。缺点是需要较大的内存空间。1.2.2利用MFC摸板创建管理图形元素对象指针的对象管理一个矢量图形系统文档的思路是:每个图形元素是图形元素类创建的一个对象,在创建这个对象时得到指向这个对象的指针,建立一个对象指针数组来管理这些指针,以达到管理所有图形元素对象的目的。在VC+下可以较容易地实现对指向图形元素对象的指针的组织和管理。在MFC中有一个类模班CTypedPtrArray,可以用它来创建一个管理类指针的对象。例如,可以定义一个管理CLine 类指针的对象如下:CTypedPtrArraym_LineArray;101.2.3实现矢量图形系统的文档在应用程序Draw中,可以派生几个CObArray对象来分别管理基类图形元素。在文档类CDrawDoc 中创建几个管理各类图形元素对象指针的CObArray 对象如下:private:CTypedPtrArraym_LineArray;CTypedPtrArraym_CircleArray;CTypedPtrArraym_ArcArray;CTypedPtrArraym_TextArray;CTypedPtrArraym_TagArray;CTypedPtrArraym_PLineArray;CTypedPtrArraym_PLineRgnArray;CTypedPtrArraym_NetArray;1.2.4实现文档的管理功能增加图形元素在应用程序Draw 中增加一个图形元素对象(如一条直线)时,需要进行以下两个步骤的操作: 首先需要创建一个图形元素对象,并用图形元素的实际数据初始化这个图形元素对象。如增加一条直线时,需要创建一个CLine 对象,并用这条直线的实际数据(起终点、所在图层、颜色等)初始化这个CLine 对象的成员变量。 然后需要把指向新创建的图形元素对象的指针,增加到文档类中管理图形元素对象指针的对象中。如增加一条CLine 对象后,需要把指向这个CLine 对象的指针增加到文档类的m_LineArray 对象中。为了实现增加各类图形元素的功能,在文档类CDrawDoc 中定义几个函数,分别来完成增加各类图形元素的操作功能3CLine* AddLine(short ColorPen,short ColorBrush,float LineWide,short LineType,short Layer,int id_only,float X1,float Y1,float X2,float Y2);CCircle*AddCircle(short ColorPen,short ColorBrush,float LineWide,short LineType,short Layer,int id_only,float CircleX,float CircleY,float CircleR,BOOL bFill);CArc* AddArc(short ColorPen,short ColorBrush,float LineWide,short LineType,short Layer,int id_only,float CircleX,float CircleY,float CircleR,float Angle1,float Angle2);CText* AddText(short ColorPen,short ColorBrush,float LineWide,short LineType,short Layer,int id_only,float StartX,float StartY,float Angle1,float Angle2,float TextHeight,float TextWide,float OffWide,unsigned char TextFont,int TextLong,CString Text);CTag* AddTag(short ColorPen,int Layer,float xInsert,float yInsert,float xScale,float yScale,float angle,int only_id,int idBlock);CPline* AddPLine(short ColorPen,short ColorBrush,float LineWide,short LineType,short Layer,int id_only,int Numble,PointStruct *PointList);CPlineRgn* AddPLineRgn(short ColorPen,short ColorBrush,float LineWide,short LineType,short Layer,int id_only,int Numble,PointStruct *PointList,BOOL bTransparent,BOOL bFill);CLinkNet* AddNetPoint(float x,float y,float rRadiu,short Layer,int id_only,short ColorPen);这8个函数分别用来实现增加一条直线、一个圆、一个圆弧、一个标注文本、一个子图、一条连续直线、一个多边形区域、一个网络点的功能。函数返回指向新增图形元素对象的指针。得到指向图形元素对象的指针在一个矢量图形系统中,有大量的图形元素,指向图形元素对象的指针被保存在文档类对应的CObArray 对象中。在系统的操作过程中,为了实现对图形元素的各种操作功能,需要得到指向指定图形元素对象的指针,为此,在文档类CDrawDoc 中定义一个函数GetGraph如下:Public:CDraw* GetGraph(short Lb, int index );在实现文件drawdoc.cpp中,加入函数的具体实现代码。删除图形元素对象为了能够从 CObArray 对象中删除一个指定图形元素对象指针,在文档类CDrawDoc中定义一个成员函数:Public:Void DeleteGraph(short Lb, int index);在实现文件drawdoc.cpp中,加入函数的具体实现代码。得到各类图形元素的数目为了能够随时得到文档中各类图形元素对象的数目,在文档类CDrawDoc 中,定义一个成员函数如下:Public:Int GetGraphNumb(short Lb);在实现文件drawdoc.cpp中,加入函数的具体实现代码。得到存储各类图形元素CObArray 对象数组的最大下标在对各个图形元素类的所有图形元素进行操作时,需要得到存储在各个CObArray 对象中的最大数组下标,然后对各个数组项实现遍历操作。为了得到存储在各个CObArray 对象中的最大数组下标,在文档类CDrawDoc中定义一个函数如下:Public:Int GetGraphUpperBound(short Lb);在实现文件drawdoc.cpp中,加入函数的具体实现代码。得到某个识别号的图形元素对象指针在CObArray 数组中的存放位置Public:Int GetGraphIndex(short Lb,int ID);在实现文件drawdoc.cpp中,加入函数的具体实现代码。增加网络连接对于一个网络点来说,其最主要的特性就是指向其他网络点的连接。为了增加网络连接,首先在CNet 类中定义一个增加网络连接的函数AddLink;Public:Void AddLink(int nID);函数的参数是连接要指向的网络点的识别号;在文档类CDrawDoc中定义一个函数AddNetLink,实现在一个网络点中增加一个指向另外一个网络点的连接。在实现文件drawdoc.cpp中,加入函数的具体实现代码。1.3实现矢量图形系统的视图1.3.1建立坐标系建立坐标系该坐标系取屏幕的左下角点作为图形屏幕的基点。客户区的左下角的坐标定义为(m_xStart, m_yStart), 并确定一个变量blc 作为逻辑坐标和实际坐标的比例关系。实际坐标与逻辑坐标的转换为了实现实际坐标与逻辑坐标的转换,在视图类CDrawDoc 中定义如下的四个转换函数:Public:Void DPtoVP(float x, float y, int *X,int *Y);Void VPtoDP(int x, int y, float *X, float *Y);Int DLtoVL(float l);Float VLtoDL( int l);函数VPtoDP 用来将逻辑坐标转换成实际坐标,参数(x,y)是一个点的逻辑坐标,参数(*X ,*Y)返回转换后的实际坐标值。函数 DLtoVL用来将实际坐标长度转换成逻辑坐标长度,参数l是一个实际坐标长度,函数返回逻辑坐标表示的长度值。四个转换函数中用到的成员变量,在视图类CDrawView 中定义:Privated:Float m_xStart, m_yStart, blc;Int m_wScreen, m_hScreen;为了在应用程序Draw 的其他类中能够使用四个坐标转换函数,可以定义四个全局函数来实现转换操作功能,在实现文件drawview.cpp中,定义四个全局函数如下:Void DPtoVP(float x, float y, int *X, int *Y);Void VPtoDP(int x, int y, float *X, float *Y );Int DLtoVL(float l);Int VLtoDL(int l);以上四个全局函数利用视图类指针p_View 调用视图类的四个坐标转换函数,来完成坐标和长度的转换功能。如果在某个实现文件中使用这四个全局转换函数,只需在这个实现文件中的开始处加入全局函数的外部引用:Extern Void DPtoVP(float x, float y, int *X, int *Y);Extern Void VPtoDP(int x, int y, float *X, float *Y );Extern Int DLtoVL(float l);Extern Int VLtoDL(int l);在四个全局函数中,p_View指向当前激活的视图对象。p_View是一个在实现文件drawview中全局定义的视图类指针。1.3.2实现各类图形元素的绘制功能利用虚函数实现各种图形元素的绘制功能。在图形元素基类CDraw中,抽象定义一个进行绘制操作的虚函数。因为在应用程序 Draw中,不用CDraw类直接来创建对象,所以可以将虚函数定义成纯虚函数:8Public:Virtual void Draw(CDC* pDC,int m_DrawMode,int m_DrawModel,short BackColor)=0;在各种图形元素类CLine CCircle CArc CText CTag CPline CPlineRgn CLinkNet 中,重载虚函数Draw :public:virtual void Draw(CDC* pDC , int m_DrawMode, int m_DrawModel ,short BackColor);1.3.3实现视图为了实现应用程序Draw的图形绘制工作,在文档类CDrawDoc 中定义Draw 函数如下:public:void Draw(CDC* pDC, int m_DrawMode, int m_DrawModel ,short BackColor);1.4各类图形元素几何属性的计算以上定义的各类图形元素,除了坐标数据外,还有一些最基本的几何特征,其中最主要的两个特征是长度和面积.为了计算各类图形元素的长度和面积,在图形元素基类CDraw 中定义了两个虚函数:protected:virtual void CalLong();virtual void CalArea();直线圆圆弧连续直线等图形元素都具有长度属性.在CLine Circle Carc Cpline 类中重载计算长度的虚函数CalLong:protected:virtual void CalLong();图形元素圆和多边形区域具有面积属性.在CCircle 类和CPlineRgn 类中重载 CalArea函数. 2鼠标交互绘图2.1用鼠标绘图要解决的主要问题2.1.1捕获鼠标操作消息VC+提供了足够的窗口消息和已经保护的消息处理函数解决这个问题.在应用程序Draw 中实现鼠标交互绘制图形元素时,将主要用到以下三个鼠标操作:鼠标移动: OnMouseMove(UINT nFlags ,CPoint point) WM_MOUSEMOVE按下左键: OnLButtonDown(UINT nFlags.CPoint point) WM_LBUTTOND按下右键: OnRButtonDown(UINT nFlags.CPoint point) WM_RBUTTONDOWN2.1.2捕捉所有的鼠标输入在用鼠标交互绘制一个图形元素时,在已经开始绘图的情况下,不希望还能进行别的操作,以避免造成系统流程和变量初始化等方面的错误.VC+提供了两个成员函数来满足以上的功能需求:CWnd:SetCapture();CWnd:ReleaseCapture();2.1.3在屏幕上拖动图形在用鼠标交互绘制图形元素时,为了直观的看到所绘制的图形,一般采用拖动图形的方法.2.1.4保存图形数据到文档用鼠标在屏幕上交互绘制的图形元素,要创建一个图形元素对象并将指向这个图形元素对象的指针保存起来.2.1.5将图形以实际的形态重画用鼠标交互绘制一个图形元素后,要在屏幕上马上显示出这个图形元素的实际形态,必须将图形元素以实际的形态重画.因为在VC+的R2_NOT绘制模式下,线条不是彩色的,拖动的图形都不是用图形元素的实际颜色.必须对图形元素以实际形态进行重画.在矢量图形系统设计中,一般采用CClientDC 对象,在交互绘制图形元素操作完成后,即时在视图中重画这个新增的图形元素.2.2交互绘制各类图形元素本设计主要实现交互绘制直线、圆、填充圆、圆弧、标注文本、连续直线、多边形区域、网络点的实现过程.2.2.1加入绘图菜单1 增加菜单资源.在应用程序Draw 的菜单资源中,增加一个菜单”鼠标绘图”.在这个菜单中包含直线圆填充圆圆弧标注文本连续直线多边形区域网络点网络连接等九个菜单项. 增加菜单的消息处理函数afx_msg void OnSize(UINT nType, int cx,int cy);afx_msg void OnMouseMove(UINT nFlags, CPoint point);afx_msg void OnLButtonDown(UINT nFlags, CPoint point);afx_msg void OnRButtonDown(UINT nFlags, CPoint point);afx_msg void OnDrawArc();afx_msg void OnDrawCircle();afx_msg void OnDrawCircle1();afx_msg void OnDrawLine();afx_msg void OnDrawPline();afx_msg void OnDrawPlineRgn();afx_msg void OnDrawText();afx_msg void OnDrawNet();afx_msg void OnDrawNetLink();在实现文件drawview.cpp中,增加了函数的消息映射机制:ON_COMMAND(ID_DRAW_ARC,OnDrawArc)ON_COMMAND(ID_DRAW_CIRCLE,OnDrawCircle)ON_COMMAND(ID_DRAW_CIRCLE1,OnDrawCircle1)ON_COMMAND(ID_DRAW_LINE,OnDrawLine)ON_COMMAND(ID_DRAW_PLINE,OnDrawPline)ON_COMMAND(ID_DRAW_RGN,OnDrawPlineRgn)ON_COMMAND(ID_DRAW_TEXT,OnDrawText)ON_COMMAND(ID_DRAW_NET,OnDrawNet)ON_COMMAND(ID_DRAW_NET_LINK,OnDrawNetLink)在实现文件drawview.cpp中,增加了消息处理函数的实现代码.2.2.2获得图形元素的唯一识别号我们设计的矢量图形系统,对于任何一个图形元素,必须有一个能够与其他图形元素区分开来的属性,为每类图形元素创建惟一识别号的方法如下所述.唯一识别号的范围在应用程序Draw中,将采用同类图形元素具有惟一识别号的方法,即每一类别的图形元素具有不同的成员变量m_id_only.得到图形元素的惟一识别号 为了得到每类图形元素的惟一识别号,在文档类CDrawDoc 中定义一个成员函数:public:int GetGraphID(short Lb);函数GetGraphID用来得到要增加的各类图形元素的惟一识别号,参数Lb 用来表示图形类别.在实现文件drawdoc.cpp中,假如函数的实现代码.2.2.3依次完成对直线、圆、填充圆、圆弧、标注文本、连续直线、多边形区域、网络点、网络连接的绘制.3矢量图形系统的操作功能1. 1增加图形操作菜单3.1.1增加菜单资源3.1.2增加消息处理函数在视图类CDrawView中,加入消息处理函数的定义:afx_msg void OnGraphRedraw();afx_msg void OnGraphZoom();afx_msg void OnGraphPan();afx_msg void OnGraphUp();afx_msg void OnGraphFirst();afx_msg void OnGraphAll();在实现文件drawview.cpp中,加入消息映射机制和空的消息处理函数ON_COMMAND(ID_GRAPH_REDRAW, OnGraphRedraw)ON_COMMAND(ID_GRAPH_ZOOM, OnGraphZoom)ON_COMMAND(ID_GRAPH_PAN, OnGraphPan)ON_COMMAND(ID_GRAPH_UP, OnGraphUp)ON_COMMAND(ID_GRAPH_FIRST, OnGraphFirst)ON_COMMAND(ID_GRAPH_ALL, OnGraphAll)3.2图形重画所谓图形重画,就是把当前视图屏幕重新绘制一次,实际上也就是让视图类的函数OnDraw(CDC* pDC) 重新执行一次。根据需要重画区域的不同,图形重画可以分为全屏重画和局部重画。3.2.1全屏重画5在很多情况下,需要将当前视图屏幕全屏重画。两种方法如下:在视图类函数的实现代码中,用以下代码来激活重画机制:CDrawDoc* pDoc=GetDocument(); pDoc-UpdateAllViews(this);函数UpdateAllViews使属于当前文档对象的所有视图重画。如果应用程序采用的是单文档结构,系统只有一个视图,执行此命令时使这个视图失效并重画,即激发视图类的OnDraw执行;如果应用程序采用的是多文档结构,一个文档对象可能具有多个视图,UpdateAllViews可使属于这个文档对象的所有视图都重新绘制。在视图类函数的实现代码中,用以下代码激活重画机制:Invalidate();Invalidate函数使当前视图屏幕的客户区失效,从而激活图形重画。Invalidate函数与UpdateAllViews函数的不同点是,它只能使当前视图重画,而与其同文档的其他视图并不重画。实现图形重画功能要实现图形重画功能,需要对视图类CDrawView的OnGraphRedraw函数进行修改。修改后的代码如下:Void CDrawView:OnGraphRedraw()CDrawDoc* pDoc=GetDocument();pDoc-UpdateAllViews(this);Invalidate();OnGraphRedraw函数首先得到指向当前文档对象的指针,然后调用UpdateAllViews函数重画此文档对象所有的视图,参数this是指向当前视图对象的指针。3.2.2局部重画在很多情况下,往往只希望将当前视图屏幕的一部分区域重画,即局部重画。在VC+中,以下两个函数可以完成此功能。InvalidateRect函数的定义为:Void InvalidateRect(LPCRECT lpRect ,BOOL bErase=TRUE);函数InvalidateRect 可使视图中一个指定的矩形区域重画。这个函数的调用方法与函数Invalidate 类似。参数lpRect 中存储着视图中需要重画的区域,参数bErase用于指定当区域重画时,背景是否擦除,当bErase为TRUE时,背景被擦除,当bErase为FALSE,背景保持不变。InvalidateRgn函数InvalidateRgn函数的定义为:void InvalidateRgn(CRgn* pRgn, BOOL bErase=TRUE);函数InvalidateRgn的功能和使用方法与函数InvalidateRgn类似,惟一不同的是函数InvalidateRgn是使一个指定的区域重画。参数pRgn是指向一个CRgn对象的指针。InvalidateRgn函数可以使一个已经初始化的CRgn对象所指定的区域重画。以下代码可使CRgn对象rgn指定的区域重画:InvalidateRgn(&rgn);3.3图形放大和摆动图形放大指的是通过调整视图屏幕,使当前视图屏幕中的一部分区域放大显示到整个视图屏幕中。图形摆动指的是通过调整视图屏幕来显示图形的其他部分。3.3.1图形放大和摆动的方法图形放大矢量图形系统应具有无级放缩的功能。所谓“无级”,指的是图形能以任何的比例进行显示。在应用程序Draw已经建立的坐标系基础上,可以很容易实现图形的无级放大。实现图形放大的操作方法很多:如可以进行固定比例的图形放大,在这种放大方式下,用鼠标点中图形的一个点,系统会把图形放大一个固定的比例,鼠标按中点处于放大后的图形屏幕中心;再如可以通过窗口放大,在这种放大方式下,有鼠标在图形屏幕上选中一个窗口区域,系统会调整放大比例和屏幕基点坐标,把选中的区域正好放大到整个图形屏幕区域中。本设计将涉及到用窗口放大图形的操作方法和具体实现步骤。在此基础上,可以轻而易举的实现其他方法的图形放大操作功能。图形摆动图形摆动的实现方法与图形放大类似,不同的只是在图形摆动操作时,对于图形屏幕只是参数m_xStart, m_yStart的变化,比例尺blc不变。假定图形摆动时,图形从基点到目标点做相对移动.用变化后的m_xStart和m_yStart重新绘制屏幕时,就实现了图形摆动。3.4重画上屏和重画首屏图形经过放大、摆动操作后,还要有把图形屏幕再恢复到前一屏幕(重画上屏)或者直接使图形回到第一屏(重画首屏)的功能。要实现重画上屏和重画首屏的功能,就需要记录下每一屏幕的状态,并时刻跟踪着当前的状态。3.4.1记录屏幕状态对图形屏幕进行分析就会发现,一个图形屏幕是由三个参数来确定的:屏幕左下角原点的实际横纵坐标m_xStart、m_yStart和显示比例blc,只要记录下这三个参数,就可以记录下这一屏幕的状态。为了实现记录屏幕状态的功能,在文档类CDrawDoc中定义一个结构数组来存储历史图形屏幕。在CDrawDoc类中定义以下两个变量:Public:int m_CurrentScreen; /当前屏幕的序号int m_MaxScreen; /最多能存储的屏幕数ScreenStruct* m_Screen; /记录屏幕参数的结构数组结构ScreenStruct在头文件drawdoc.h中CDrawDoc类定义前定义:Typedef structFloat blc; /显示比例Float sx; /屏幕左下角横坐标Float sy; /屏幕左下角纵坐标ScreenStruct;在文档类CDrawDoc中定义一个函数,来完成存储一个图形屏幕状态的操作功能:Public:Void AddScreen(float StartX, float StartY, float blc);在实现文件drawdoc.cpp中,加入函数的实现代码。3.4.2 实现重画上屏和重画首屏功能重画上屏要实现重画上屏操作功能,只需把m_CurrentScreen的值减去1,从结构数组m_Screen中取出屏幕参数重画图形即可。在实现文件drawview.cpp中,将“重画上屏”菜单项的消息处理函数OnGraphUp的实现代码修改如下:5void CDrawView:OnGraphUp() CDrawDoc* pDoc=(CDrawDoc*)GetDocument();if(pDoc-m_CurrentScreen0)/如果当前不是首屏,当前图形屏幕序号减1pDoc-m_CurrentScreen-;/得到上一屏幕的图形参数并重画图形m_xStart=p_ScreenpDoc-m_CurrentScreen.sx;m_yStart=p_ScreenpDoc-m_CurrentScreen.sy;blc=p_ScreenpDoc-m_CurrentScreen.blc;Invalidate(); /重画图形p_Screen是CDrawView类中定义的指向文档对象中的结构数组m_Screen的指针,它在视图类CDrawView中定义:ScreenStruct *p_Screen;在实现文件drawview.cpp中,在重载的虚函数OnActiveView中对p_Screen进行初始化,将它指向当前文档对象中的结构数组m_Screen:void CDrawView:OnActivateView(BOOLbActivate, CView* pActivateView, CView* pDeactiveView) p_View=this;CDrawDoc* pDoc=(CDrawDoc*)GetDocument();p_Screen=pDoc-m_Screen;CView:OnActivateView(bActivate, pActivateView, pDeactiveView);重画首屏对于重画首屏功能来说,只要取出存储在结构数组m_Screen中的首屏参数,并对视图重画即可。修改实现文件drawview.cpp中的消息处理函数OnGraphFirst,得到实现代码如下:void CDrawView:OnGraphFirst() /重画首屏/ TODO: Add your command handler code hereCDrawDoc* pDoc=GetDocument();if(pDoc-m_CurrentScreen=0)return ;m_xStart=p_Screen0.sx;m_yStart=p_Screen0.sy;blc=p_Screen0.blc;pDoc-AddScreen(m_xStart,m_yStart,blc);Invalidate();3.5显示全图在矢量图形系统中,随着一些图形元素通过外部接口或者系统本身的绘制功能的加入,图形首屏可能包含不了所有的图形元素;还有一种情况是,图形中所有的图形元素都在视图屏幕的一个角上,只占图幅的一小部分。这是就需要一个操作功能,调整视图屏幕左下角原点的实际坐标(m_xStart ,m_yStart)和显示比例blc,使所有的图形元素正好能够绘制到视图屏幕中(在屏幕上留有一部分边界区域),显示全图功能就是为完成此功能而设置的。实现显示全图功能的思路是,通过得到每一类图形元素(如直线、连续直线)的边界矩形,然后根据视图屏幕的大小(逻辑坐标)进行计算,得到屏幕的参数m_xStart,m_yStart,blc.所以,解决问题的关键在于得到各类图形元素的边界矩形。3.5.1各类图形元素的边界矩形计算5在图形元素基类CDraw 中定义一个虚函数:Public:Virtual void GetRect(float *minx,float *minY,float *maxX,float *maxY)=0;函数GetRect用来计算图形元素的边界矩形,(*minX ,*minY)和 (*maxX ,*maxY )这四个指针参数用来返回边界矩形的最小和最大坐标。在由CDraw类派生的各个图形元素类中重载虚函数GetRect,即在各个类中加入以下定义代码:Public:Virtual void GetRect(float *minx,float *minY,float *maxX,float *maxY);并在各个图形元素类中实现代码,以完成计算各类图形元素边界矩形的功能。3.5.2实现显示全图功能得到所有图形元素的边界矩形把所有图形元素的边界矩形坐标进行比较,就可以得到所有图形元素的边界矩形。为了实现这个功能,在文档类CDrawDoc中定义一个函数:Public:BOOL GetRect(float *m_Xmin,float *m_Ymin,float *m_Xmax,float *m_Ymax);指针参数用来返回边界矩形的最小和最大坐标,当能计算得到边界矩形时,函数返回TRUE,否则,函数返回FALSE.在实现文件drawdoc.cpp中,加入这个函数的实现代码在函数GetRect中,首先对记录最小值和最大值的变量初始化,然后对所有的直线连续直线圆圆弧标注文本多边形区域网络点等类图形元素进行循环,得到每个图形元素的边界矩形,并比较运算得到所有图形元素的边界矩形。当至少有一个图形元素时,函数返回TRUE,没有任何图形元素时,函数返回FALSE.1 实现显示全屏功能在得到所有图形元素的边界矩形后,就可以调整视图屏幕的基点和比例,使当前视图正好能够绘制下所有的图形元素。在实现文件drawview.cpp中,对菜单项“重画全屏”的消息处理函数OnGraphAll进行修改:void CDrawView:OnGraphAll() / TODO: Add your command handler code herefloat minx,miny,maxx,maxy,bl1;CDrawDoc* pDoc=GetDocument();SetCapture();SetCursor(LoadCursor(NULL,IDC_WAIT);BOOL pb=pDoc-GetRect(&minx,&miny,&maxx,&maxy);SetCursor(LoadCursor(NULL,IDC_ARROW);ReleaseCapture();if(!pb)return ;bl1=(maxx-minx)/(m_wScreen-20);blc=(maxy-miny)/(m_hScreen-20);if(bl1blc)blc=bl1;m_xStart=minx-10*blc;m_yStart=miny-10*blc;p_Screen0.sx=m_xStart;p_Screen0.sy=m_yStart;p_Screen0.blc=blc;pDoc-m_CurrentScreen=0;Invalidate();3.6提高矢量图形系统重画速度的基本方法。3.6.1提高图形重画速度的方法一个基本的方法就是在显示一个图形元素前,对这个图形元素进行判断,判断这个图形元素是否在视图屏幕中,如果这个图形元素不在当前的视图屏幕中,就不用对这个图形元素进行绘制,以此节省绘制时间。我们采用的计算方法应该是计算简单且允许不太严密。这里所谓的不太严密,指的是用这种方法判断是在视图屏幕中的图形元素,实际也可能不在视图屏幕中,而经过判断不在视图屏幕中的图形元素一定不在视图屏幕中。这种判断一般采用这个图形元素的边界矩形和屏幕边界矩形是否相交的方法。在提高图形重画速度时,首先要得到视图屏幕即客户区的大小。在应用程序Draw中,在视图类CDrawView中有两个变量m_hScreen 和m_wScreen 分别用来存储当前视图的高度和宽度(逻辑坐标)。在进行图形绘制前,把视图屏幕矩形有逻辑坐标转换成实际坐标。定义以下四个全局变量,用来传递要绘制视图的左下角和右上角的实际坐标。在实现文件drawdoc.cpp中,增加全局变量的定义:Float xMinScreen ,yMinScreen , xMaxScreen , yMaxScreen;为了在实现文件drawview.cpp中使用这些变量,在实现文件drawview.cpp中增加对这些全局变量的引用:Extern float xMinScreen ,yMinScreen , xMaxScreen , yMaxScreen这四个全局变量在每次调用OnDraw函数实现视图的绘制功能前被初始化。在实现文件drawview.cpp中的绘制函数CDrawView:OnDraw(CDC* pDC)中加入代码,实现在每次绘制前得到视图屏幕边界的实际坐标:void CDrawView:OnDraw(CDC* pDC)CDrawDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);/ TODO: add draw code for native data herexMinScreen=m_xStart;yMinScreen=m_yStart;xMaxScreen=xMinScreen+blc*m_wScreen;yMaxScreen=yMinScreen+blc*m_hScreen;DrawBack(pDC);pDoc-Draw(pDC,0,0,m_bColor);m_MapMode=pDC-SetMapMode(1);这样在以当前的屏幕参数(m_xStart ,m_yStart ,blc)绘制图形前,把视图屏幕的左下角和右上角的实际坐标计算出来。为判断一个矩形区域与视图屏幕矩形是否相交,在drawdoc.cpp中定义一个全局函数:BOOL IsRectCross(float mi
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025咨询工程师自我提分评估含答案详解【A卷】
- 应急安全培训致辞稿件课件
- 打包站转让合同(标准版)
- 农村折屋合同(标准版)
- 国外的进口合同(标准版)
- 2024-2025学年度制冷与空调作业能力检测试卷及完整答案详解(典优)
- 2025自考专业(金融)全真模拟模拟题重点附答案详解
- 中班美术教案《漂亮的大鱼》反思
- 2025年智慧生态公园规划初步设计评估与实施策略报告
- 2025年模具行业数字化设计仿真技术应用行业创新与挑战报告001
- 公路养护技术管理与实施细则
- 2025-2030留学培训行业市场运行态势及发展前景预测与商业合作机会研究报告
- 房地产开发公司工程部经理个人工作总结
- 2025年交通工程师资格考试试题及答案解析
- 2025年私人住宅装修合同及详细工程清单
- 2025年法本法硕真题及答案
- 变压器装配工职业技能考核试卷及答案
- 驻场人员管理协议书8篇
- 秋季传染病健康知识培训课件
- 2025一级建造师考试《港口与航道工程》真题及答案
- 2024年一级建造师《建筑工程管理与实务》真题及答案
评论
0/150
提交评论