图形编辑“点线”联动_第1页
图形编辑“点线”联动_第2页
图形编辑“点线”联动_第3页
图形编辑“点线”联动_第4页
图形编辑“点线”联动_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

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

文档简介

1、Visual C+图形编辑“点-线”联动 摘 要 以统筹图绘制程序的编制为例,详细给出了应用Visual C+开发工具及MFC实现图形编辑中的节点-箭线联动方法。该方法对于实现GIS应用、标图应用和统筹图应用中的类似功能有较好的参考价值。关键词 节点;箭线;编辑联动1 引言很多的图形应用如统筹图应用、GIS应用、标图应用中都存在着编辑联动的问题。所谓编辑联动,是指在对一个图元编辑修改包括位置的变动后,其他图元由于与这个图元有某种关系,而能自动同步被修改。按图元类型,可将图形联动划分为点-点、点-线、点-面、线-线、线-面、面-面等6种。文中以统筹图为例,讨论节点-箭线联动编辑问题。节

2、点与箭线图元的实现以VC自带面向对象图形例程DRAWCLI基础,添加自定义类CDrawNode和CDrawArrow来实现。依据功能设计,程序的主要工作包括:(1) 基本图元的绘制。包括绘制节点和箭线。绘制的节点图形表示为圆心标有编号圆圈;箭线的两侧标注有文字说明,且文字行与箭线保持平行,箭线带有起节点和终节点。(2) 处理图元及相互位置关系。包括删除操作和移动操作。删除某一节点,与该节点相连的箭线全部删除,且调整编号在其后面的节点编号,删除箭线不影响节点。移动节点时,与之相连的箭线相应移动,其关键是准确计算箭线的位置。2 基本图元及联动21基本图元实现设在+6.0的环境下已建立了工程Draw

3、.dsp。节点类和箭线类都是以CDrawObj为基类派生。在建立这两个类之前,需要添加以下全局变量enum DrawShape,circle,arrow,;/图元类型以及相应的工具circleTool和arrowTool(arrow)、arrowlineTool211节点类CDrawNode的设计class CDrawNode : public CDrawObjpublic:CDrawNode(const CRect& position,int Radius);void SetCircleIndex(int Index) m_nIndex=Index; 设置节点编号virtual in

4、t GetObjIndex()return m_nIndex ; /获取编号public:int m_Radius; /节点半径int m_CentreX,m_CentreY;/圆心/在圆中心写上编号,要考虑编号的位数情况 virtual void Draw(CDC* pDC,CDrawView* pView);  protected:int m_nIndex;/编号CDrawNode* m_pDrawObj;friend class CCircleTool;绘制节点的工具CCircleTool在鼠标左键按下OnLButtonDown的消息处理函数中,实际分配内存,产生一个节点对象。

5、212箭线类CDrawArrow的设计class CDrawArrow: public CDrawObjpublic: CDrawRect(const CRect& position);void SetProjectName(CString name)m_ProjectName=name;void SetProjectTime(int time) m_ProjectTime=time;CString GetProjectName() return m_ProjectName;void SetProjectTime(int time) return m_ProjectTime;bool

6、m_bForeConnect;/箭线始节点标志bool m_bBackConnect;/箭线终节点标志int m_ForeConnect; /箭线连接的始节点序号int m_BackConnect; /箭线连接的终节点序号virtual int GetObjIndex() return o;/绘制时,计算平行于箭线的说明文字的角度,位置,项目名称总在线的上方virtual void Draw(CDC* pDC,CDrawView* pView);enum ArrowType none, pureArrow, openArrow,stealthArrow, diamondArrow, ovalA

7、rrow;enum Shape rectangle, roundRectangle, ellipse, line,arrow ;protected:CString m_ProjectName; /项目名称int m_ProjectTime; /时间Shape m_nShape;ArrowType m_lArrow, m_rArrow; /for arrow only int m_lArrowSize, m_rArrowSize; /for arrow onlyprivate:void DrawArrow(ArrowType arrowType, POINT p1, POINT p2, int

8、arrowSize, CDC *,int, int , int, CBrush *);friend class CArrowTool; 绘制箭线的工具CArrowTool在OnLButtonDown中实际生成箭线对象,并记录箭线所连的开始节点,箭线的终节点确定在后面说明。2. 2图元联动操作221删除节点及箭线void CDrawView:OnEditClear() CDrawDoc* pDoc=(CDrawDoc*)GetDocument();POSITION pos = m_selection.GetHeadPosition();while (pos != NULL)CDrawO

9、bj* pObj = m_selection.GetNext(pos);GetDocument()->Remove(pObj); /删除节点CDrawNode* pDrawCircle=(CDrawNode*)pObj;nIndex=pDrawCircle->GetObjIndex();/获取节点编号,若不是节点对象,返回0if(nIndex) pDoc->m_nIndex=nIndex;pos=GetDocument()->m_objects.GetHeadPosition();int i=0;int num=pDoc->m_objects.GetCount()

10、;m_num=pDoc->m_nIndex;while(i<num)/序号位于被删除节点之后的所有节点序号减1CDrawNode* pDrawCircle=(CDrawNode*)pDoc->m_objects.GetNext(pos);if(pDrawCircle->GetObjIndex()>m_num)pDrawCircle->SetCircleIndex(m_num);m_num+; i+;pos=pDoc->m_objects.GetHeadPosition(); if(pos!=NULL)i=0;num=pDoc->m_ob

11、jects.GetCount();while(i<num)/删除与接点相连的所有箭线CDrawRect* pDrawRect=(CDrawRect*)pDoc->m_objects.GetNext(pos);if(pDrawRect!=NULL)if(nIndex=pDrawRect->m_ForeConnect)pDoc->Remove(pDrawRect);pDrawRect->Remove();if(nIndex=pDrawRect->m_BackConnect)pDoc->Remove(pDrawRect);pDrawRect->Remo

12、ve();if(nIndex<pDrawRect->m_ForeConnect)pDrawRect->m_ForeConnect-;if(nIndex<pDrawRect->m_BackConnect)pDrawRect->m_BackConnect-;i+;Invalidate();pDoc->m_nIndex=m_num;pObj->Remove(); m_selection.RemoveAll();UINT nFlags;OnLButtonDown(nFlags,CPoint(0,0);OnLButtonUp(nFlags,CPo

13、int(0,0);222用鼠标移动某一节点时,同步移动与其相连接的箭线void CSelectTool:OnMouseMove(CDrawView* pView, UINT nFlags, const CPoint& point)if (pView->GetCapture() != pView)CPoint local = point;int BackConnect;pView->ClientToDoc(local);POSITION pos;if (c_drawShape = arrow) /判断鼠标移动绘制箭线过程中是否与某一节点相连/此时函数是CRectTool:On

14、MouseMove()调用selectTool.OnMouseMove();而跳到这里CRect circlerect;CDrawNode* pForeCircle;CDrawNode* pBackCircle;pos=pView->GetDocument()->m_objects.GetHeadPosition();if(pos!=NULL)int i=0;int num=pView->GetDocument()->m_objects.GetCount();while(i<num)CDrawNode* pDrawCircle=(CDrawNode*)pView-

15、>GetDocument()->m_objects.GetNext(pos);if(pDrawCircle!=NULL) int index=pDrawCircle->GetObjIndex();if(index)/判断circlerect=pDrawCircle->m_position;pView->DocToClient(circlerect);if(circlerect.PtInRect(point)local=pDrawCircle->GetHandle(8);BackConnect=pDrawCircle->GetObjIndex(

16、);i+;CPoint delta = (CPoint)(local - lastPoint);pos = pView->m_selection.GetHeadPosition();while (pos != NULL)CDrawObj* pObj = pView->m_selection.GetNext(pos);CRect position = pObj->m_position;if (c_drawShape = arrow)/记录终节点pObj->m_BackConnect=BackConnect;pObj->m_bBackConnect=true;/以下实

17、现移动节点,使所有的箭线跟随节点同步移动if (selectMode = move) if(pView->m_selection.GetCount()=1)CDrawNode* pDrawCircle=(CDrawNode*)pObj;int Index=pDrawCircle->GetObjIndex();if(Index) /移动节点POSITION Rectpos=pView->GetDocument()->m_objects.GetHeadPosition();if(Rectpos!=NULL)int i=0; int num=pView->Ge

18、tDocument()->m_objects.GetCount();while(i<num)/所有与之相连箭线同步移动CDrawRect* pDrawObj=(CDrawRect*)pView->GetDocument()->m_objects.GetNext(Rectpos);if(pDrawObj!=NULL)if(Index=pDrawObj->m_ForeConnect)/节点是箭线始节点CRect deltarect=pDrawObj->m_position;deltarect.BottomRight()+=delta;int length=del

19、tarect.top-deltarect.bottom;int width=deltarect.left-deltarect.right;/节点移动,箭线与节点的连接点改变,计算连接点位置if(abs(length)<abs(width)&&width<0)deltarect.BottomRight()=pDrawCircle->GetHandle(8);if(abs(length)<abs(width)&&width>0)deltarect.BottomRight()=pDrawCircle->GetHandle(4);if

20、(abs(length)>abs(width)&&width>0&&length<0)|(abs(length)>abs(width)&&width<0&&length<0)deltarect.BottomRight()=pDrawCircle->GetHandle(2);if(abs(length)>abs(width)&&length>0&&width>0)|(abs(length)>abs(width)&&len

21、gth>0&&width<0)deltarect.BottomRight()=pDrawCircle->GetHandle(6);int nIndex=pDrawObj->m_BackConnect;POSITIONcirclepos=pView->GetDocument()->m_objects.GetHeadPosition();if(circlepos!=NULL)int i=0;int num=pView->GetDocument()->m_objects.GetCount();while(i<num) C

22、DrawNode* pDrawNode=(CDrawNode*)pView->GetDocument()->m_objects.GetNext(circlepos);if(pDrawNode!=NULL)if(nIndex=pDrawNode->GetObjIndex()/计算箭线的新位置if(abs(length)<abs(width)&&width<0)deltarect.TopLeft()=pDrawNode->GetHandle(4);if(abs(length)<abs(width)&&width>0)d

23、eltarect.TopLeft()=pDrawNode->GetHandle(8);if(abs(length)>abs(width)&&width>0&&length<0)|(abs(length)>abs(width)&&width<0&&length<0)deltarect.TopLeft()=pDrawNode->GetHandle(6);if(abs(length)>abs(width)&&length>0&&width>

24、0)|(abs(length)>abs(width)&&length>0&&width<0)deltarect.TopLeft()=pDrawNode->GetHandle(2);i+;pDrawObj->MoveTo(deltarect,pView);if(Index=pDrawObj->m_BackConnect)/节点是箭线终节点CRect deltarect=pDrawObj->m_position;deltarect.TopLeft()+=delta;int length=deltarect.top-delta

25、rect.bottom;int width=deltarect.left-deltarect.right;if(abs(length)<abs(width)&&width<0)deltarect.TopLeft()=pDrawCircle->GetHandle(4);if(abs(length)<abs(width)&&width>0)deltarect.TopLeft()=pDrawCircle->GetHandle(8);if(abs(length)>abs(width)&&width>0&am

26、p;&length<0)|(abs(length)>abs(width)&&width<0&&length<0)deltarect.TopLeft()=pDrawCircle->GetHandle(6);if(abs(length)>abs(width)&&length>0&&width>0)|(abs(length)>abs(width)&&length>0&&width<0)deltarect.TopLeft()=pDra

27、wCircle->GetHandle(2);int nIndex=pDrawObj->m_ForeConnect;  POSITION circlepos=pView->GetDocument()->m_objects.GetHeadPosition();if(pos!=NULL)int i=0;int num=pView->GetDocument()->m_objects.GetCount(); while(i<num)CDrawNode* pDrawNode=(CDrawNode*)pView->GetDocument()->

28、m_objects.GetNext(circlepos);if(pDrawNode!=NULL)if(nIndex=pDrawNode->GetObjIndex()if(abs(length)<abs(width)&&width<0)deltarect.BottomRight()=pDrawNode->GetHandle(8);if(abs(length)<abs(width)&&width>0)deltarect.BottomRight()=pDrawNode->GetHandle(4);if(abs(length)&

29、gt;abs(width)&&width>0&&length<0)|(abs(length)>abs(width)&&width<0&&length<0)deltarect.BottomRight()=pDrawNode->GetHandle(2);if(abs(length)>abs(width)&&length>0&&width>0)|(abs(length)>abs(width)&&length>0&&width<0)deltarect.Bo

温馨提示

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

评论

0/150

提交评论