|
|
#include "StdAfx.h"
|
|
|
#include "CatchMgr.h"
|
|
|
#include "GlobalDrawMgr.h"
|
|
|
#include "GlobalFunction.h"
|
|
|
#include "LogMgr.h"
|
|
|
#include "DrawSimpleShape.h"
|
|
|
#include "ObjComponentMgr.h"
|
|
|
#include "MouseToolmgr.h"
|
|
|
|
|
|
CCatchMgr gCatchMgr;//捕捉管理
|
|
|
CCatchMgr::CCatchMgr()
|
|
|
{
|
|
|
ResetCatchNode();
|
|
|
}
|
|
|
CCatchMgr::~CCatchMgr(void)
|
|
|
{
|
|
|
}
|
|
|
#if 1//捕捉基础函数
|
|
|
void CCatchMgr::DrawCatchPoint(CCatchPoint CatchPt,CDC* pDC)
|
|
|
{
|
|
|
if(m_CatchPointVec.empty())
|
|
|
{
|
|
|
ResetCatchPoint(pDC);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//擦除之前的
|
|
|
if(!CatchPt.Equal(m_CatchNode))
|
|
|
{
|
|
|
ResetCatchPoint(pDC);
|
|
|
}
|
|
|
if(!CatchPt.Equal(m_CatchNode))
|
|
|
{
|
|
|
DrawCatchPointExt(CatchPt,pDC);
|
|
|
//保存当前的捕获
|
|
|
m_CatchNode = CatchPt;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
void CCatchMgr::DrawCatchPointExt(CCatchPoint pt,CDC* pDC)
|
|
|
{
|
|
|
DbRect NodeRect(pt,gDraw->GetCatchNodeSize());
|
|
|
switch(pt.GetType())
|
|
|
{
|
|
|
case _CATCH_NODE:
|
|
|
DrawRect(pDC,gDraw->GetCatchNodePen(),NodeRect);
|
|
|
break;
|
|
|
case _CATCH_INTERSECT:
|
|
|
case _CATCH_ORTHO:
|
|
|
case _CATCH_CUT_TRACK:
|
|
|
XorDrawCrossX(pDC,gDraw->GetCatchNodePen(),NodeRect);
|
|
|
break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
void CCatchMgr::ResetCatchNode()
|
|
|
{
|
|
|
m_CatchNode.x = -10000.123456;
|
|
|
m_CatchNode.y = -10000.123456;
|
|
|
}
|
|
|
void CCatchMgr::ResetCatchPoint(CDC* pDC)
|
|
|
{
|
|
|
if(HasCatchPoint())
|
|
|
{
|
|
|
//擦除之前的
|
|
|
DrawCatchPointExt(m_CatchNode,pDC);
|
|
|
}
|
|
|
//重置坐标
|
|
|
ResetCatchNode();
|
|
|
}
|
|
|
bool CCatchMgr::HasCatchPoint()
|
|
|
{
|
|
|
if(m_CatchNode.x == -10000.123456)
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
bool CCatchMgr::GetCatchPoint(CPoint &pt)
|
|
|
{
|
|
|
if(HasCatchPoint())
|
|
|
{
|
|
|
pt = gDraw->Dbxy2CPoint(m_CatchNode);
|
|
|
return true;
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
//获取离鼠标最近的捕获点
|
|
|
CCatchPoint CCatchMgr::GetNearestCatchPt(Dbxy pt)
|
|
|
{
|
|
|
CCatchPoint CatchPt;
|
|
|
double MinDis;
|
|
|
vector<CCatchPoint>::iterator iter = m_CatchPointVec.begin();
|
|
|
vector<CCatchPoint>::iterator iter_end = m_CatchPointVec.end();
|
|
|
for(;iter!=iter_end;iter++)
|
|
|
{
|
|
|
double dis = CalDistance(pt,(*iter));
|
|
|
if(iter == m_CatchPointVec.begin())
|
|
|
{
|
|
|
MinDis = dis;
|
|
|
CatchPt = (*iter);
|
|
|
}
|
|
|
else if(dis<MinDis)
|
|
|
{
|
|
|
MinDis = dis;
|
|
|
CatchPt = (*iter);
|
|
|
}
|
|
|
}
|
|
|
return CatchPt;
|
|
|
}
|
|
|
#endif
|
|
|
#if 1//每种捕捉对应的函数
|
|
|
//捕获pt 附近的点
|
|
|
void CCatchMgr::Catch(Dbxy DownPt,Dbxy pt,CDC* pDC,bool bCatchTemp)
|
|
|
{
|
|
|
//先清空捕获点容器
|
|
|
m_CatchPointVec.clear();
|
|
|
m_DataPtLineVec.clear();
|
|
|
//获得鼠标为中心的捕获矩形rect
|
|
|
DbRect rect = gDraw->GetCurCatchRect(pt);
|
|
|
|
|
|
//收集rect 范围内所有的线段
|
|
|
GetLineInRect(rect,bCatchTemp);
|
|
|
//捕获rect 范围内的node 节点
|
|
|
CatchNode(rect);
|
|
|
//捕获rect 范围内线段的交点
|
|
|
CatchIntersectPointOfLines(rect);
|
|
|
//捕获鼠标rect 和线段的交点
|
|
|
CatchIntersectPointWithMouse(rect);
|
|
|
//捕获正交点
|
|
|
CatchOrthoPoint(DownPt,pt,rect);
|
|
|
//捕捉元件对象切割道的交点,用于指定mark 点
|
|
|
CatchCutTrack(rect);
|
|
|
//选择离鼠标最近的点为捕获点
|
|
|
CCatchPoint CatchPt;
|
|
|
if(!m_CatchPointVec.empty())
|
|
|
{
|
|
|
CatchPt = GetNearestCatchPt(pt);
|
|
|
}
|
|
|
//绘制捕获点
|
|
|
DrawCatchPoint(CatchPt,pDC);
|
|
|
}
|
|
|
//收集rect 范围内所有的线段
|
|
|
void CCatchMgr::GetLineInRect(DbRect &rect,bool bCatchTemp)
|
|
|
{
|
|
|
gLayer.GetLineInRect(rect,m_DataPtLineVec,bCatchTemp);
|
|
|
}
|
|
|
//收集rect 范围内的节点
|
|
|
void CCatchMgr::CatchNode(DbRect rect)
|
|
|
{
|
|
|
if(gDraw->IsCatchObjNode()== false)
|
|
|
return;
|
|
|
//优先级控制
|
|
|
if(!m_CatchPointVec.empty())
|
|
|
return;
|
|
|
//检查线段的端点是否在矩形内即可
|
|
|
vector<DbLine>::iterator iter = m_DataPtLineVec.begin();
|
|
|
vector<DbLine>::iterator iter_end = m_DataPtLineVec.end();
|
|
|
for(;iter!=iter_end;iter++)
|
|
|
{
|
|
|
if((*iter).m_pt1.IsNode())
|
|
|
{
|
|
|
Dbxy pt = (*iter).m_pt1.GetPt();
|
|
|
if(IsPointInRect(pt,rect))
|
|
|
{
|
|
|
CCatchPoint CatchPoint(pt.x,pt.y,_CATCH_NODE);
|
|
|
m_CatchPointVec.push_back(CatchPoint);
|
|
|
}
|
|
|
}
|
|
|
if((*iter).m_pt2.IsNode())
|
|
|
{
|
|
|
Dbxy pt = (*iter).m_pt2.GetPt();
|
|
|
if(IsPointInRect(pt,rect))
|
|
|
{
|
|
|
CCatchPoint CatchPoint(pt.x,pt.y,_CATCH_NODE);
|
|
|
m_CatchPointVec.push_back(CatchPoint);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
//收集rect 范围内的线段交点
|
|
|
void CCatchMgr::CatchIntersectPointOfLines(DbRect rect)
|
|
|
{
|
|
|
if(gDraw->IsCatchCrossPoint()== false)
|
|
|
return;
|
|
|
//优先级控制
|
|
|
if(!m_CatchPointVec.empty())
|
|
|
return;
|
|
|
int size = m_DataPtLineVec.size();
|
|
|
for(int i=0;i<size;i++)
|
|
|
{
|
|
|
DbLine &line1 = m_DataPtLineVec[i];
|
|
|
for(int j=i+1;j<size;j++)
|
|
|
{
|
|
|
DbLine &line2 = m_DataPtLineVec[j];
|
|
|
//连续线段的交点不算
|
|
|
if(line1.IsSerialLine(line2))
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
//先判断是否相交
|
|
|
if(IsTwoLineIntersect(line1.m_pt1.GetPt(),line1.m_pt2.GetPt(),line2.m_pt1.GetPt(),line2.m_pt2.GetPt()))
|
|
|
{
|
|
|
//如果相交求出交点
|
|
|
Dbxy pt = CalIntersection(line1.m_pt1.GetPt(),line1.m_pt2.GetPt(),line2.m_pt1.GetPt(),line2.m_pt2.GetPt());
|
|
|
//交点在rect 内则加入捕捉点
|
|
|
if(IsPointInRect(pt,rect))
|
|
|
{
|
|
|
CCatchPoint CatchPoint(pt.x,pt.y,_CATCH_INTERSECT);
|
|
|
m_CatchPointVec.push_back(CatchPoint);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
//捕获线段和鼠标的交点
|
|
|
void CCatchMgr::CatchIntersectPointWithMouse(DbRect rect)
|
|
|
{
|
|
|
if(gDraw->IsCatchObjLine()== false)
|
|
|
return;
|
|
|
//优先级控制
|
|
|
if(!m_CatchPointVec.empty())
|
|
|
return;
|
|
|
vector<DbLine>::iterator iter = m_DataPtLineVec.begin();
|
|
|
vector<DbLine>::iterator iter_end = m_DataPtLineVec.end();
|
|
|
for(;iter!=iter_end;iter++)
|
|
|
{
|
|
|
Dbxy LinePt1 = (*iter).m_pt1.GetPt();
|
|
|
Dbxy LinePt2 = (*iter).m_pt2.GetPt();
|
|
|
if(IsPointInRect(LinePt1,rect)||IsPointInRect(LinePt2,rect))//不要捕捉端点的部分
|
|
|
{
|
|
|
break;
|
|
|
}
|
|
|
Dbxy pt = IntersectionOfRectAndLine(LinePt1,LinePt2,rect);
|
|
|
CCatchPoint CatchPoint(pt.x,pt.y,_CATCH_INTERSECT);
|
|
|
m_CatchPointVec.push_back(CatchPoint);
|
|
|
}
|
|
|
}
|
|
|
//捕获正交点
|
|
|
void CCatchMgr::CatchOrthoPoint(Dbxy DownPt,Dbxy MousePt,DbRect rect)
|
|
|
{
|
|
|
if(gDraw->IsCatchOrthoPoint()== false)
|
|
|
return;
|
|
|
//优先级控制
|
|
|
if(!m_CatchPointVec.empty())
|
|
|
return;
|
|
|
|
|
|
DbSize size = rect.GetSize();
|
|
|
if(abs(MousePt.x-DownPt.x)<=size.w/2)
|
|
|
{
|
|
|
CCatchPoint CatchPoint(DownPt.x,MousePt.y,_CATCH_ORTHO);
|
|
|
m_CatchPointVec.push_back(CatchPoint);
|
|
|
}
|
|
|
else if(abs(MousePt.y-DownPt.y)<=size.h/2)
|
|
|
{
|
|
|
CCatchPoint CatchPoint(MousePt.x,DownPt.y,_CATCH_ORTHO);
|
|
|
m_CatchPointVec.push_back(CatchPoint);
|
|
|
}
|
|
|
}
|
|
|
//捕捉元件对象切割道的交点,用于指定mark 点
|
|
|
void CCatchMgr::CatchCutTrack(DbRect rect)
|
|
|
{
|
|
|
if(gDraw->IsCatchCutTrack()== false)
|
|
|
return;
|
|
|
//优先级控制
|
|
|
if(!m_CatchPointVec.empty())
|
|
|
return;
|
|
|
//只有在测量的时候才捕捉
|
|
|
MOUSE_TOOL tool = gMouseToolMgr.GetToolType();
|
|
|
if(tool == _TOOL_MEASURE)
|
|
|
{
|
|
|
vector<CObjComponent>&vec = gObjComponentMgr->GetComponentVec();
|
|
|
|
|
|
Dbxy pt = rect.GetCenterPt();
|
|
|
|
|
|
double MinDis = 0;//最近的距离
|
|
|
|
|
|
int MinIdx = -1;
|
|
|
int size = vec.size();
|
|
|
for(int i=0;i<size;i++)
|
|
|
{
|
|
|
double CurDis = CalDistance(pt,vec[i].GetBasePt());
|
|
|
if(CurDis <= vec[i].GetSize().w)
|
|
|
{
|
|
|
if(MinDis == 0 || CurDis<MinDis)
|
|
|
{
|
|
|
MinIdx = i;
|
|
|
MinDis = CurDis;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
if(MinIdx != -1)
|
|
|
{
|
|
|
Dbxy pt = vec[MinIdx].GetBasePt();
|
|
|
CCatchPoint CatchPoint(pt.x,pt.y,_CATCH_CUT_TRACK);
|
|
|
m_CatchPointVec.push_back(CatchPoint);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
#endif
|