You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

302 lines
8.1 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#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