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.
418 lines
10 KiB
C++
418 lines
10 KiB
C++
#include "StdAfx.h"
|
|
#include ".\itemextendcurve.h"
|
|
#include "SigmaDoc.h"
|
|
#include "SigmaView.h"
|
|
#include "ActionListItem.h"
|
|
#include "itemsolid.h"
|
|
|
|
extern "C" __declspec(dllexport)
|
|
double Global_GetExtendLength();
|
|
|
|
POSITION FindPosition(CPtrList& list, COne* pOther);
|
|
|
|
namespace NItem
|
|
{
|
|
|
|
CItemExtendCurve::CItemExtendCurve(CSigmaDoc * ppDoc)
|
|
: CItemBreakCurve(ppDoc)
|
|
, maxExtendLength(100)
|
|
, m_nExtendIdea(2)
|
|
{
|
|
m_nActionID=ID_EDIT_TOOL_EXTEND_CURVE;
|
|
this->SetType(ITEM_EXTEND_CURVE);
|
|
m_bAutoDelete=FALSE;
|
|
}
|
|
|
|
CItemExtendCurve::~CItemExtendCurve(void)
|
|
{
|
|
}
|
|
|
|
void CItemExtendCurve::DoLButtonUp(CDC *pDC)
|
|
{
|
|
ProcessLButtonUp();
|
|
}
|
|
|
|
int CItemExtendCurve::GetSubMenu()
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
BOOL CItemExtendCurve::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
|
|
{
|
|
return CItemBreakCurve::OnSetCursor(pWnd, nHitTest, message);
|
|
//return FALSE;
|
|
}
|
|
|
|
void CItemExtendCurve::OnRButtonDown(UINT nFlags, CPoint point)
|
|
{
|
|
//GetDoc()->EnableDefaultTool();
|
|
}
|
|
|
|
BOOL CItemExtendCurve::ExtendCurve(CCurveEx* pBaseCurve, CCurveEx* pExtendCurve, int nExtendIdea)
|
|
{
|
|
//maxExtendLength=GetPreferences;().WorkaroundEdit.m_dMaxExtendLength;
|
|
//maxExtendLength = pBaseCurve->Length();; //TODO:需要用户设置此值
|
|
maxExtendLength = Global_GetExtendLength();
|
|
|
|
dfPoint dp, bp;
|
|
CCrossPoint cp;
|
|
CCrossList list;
|
|
BOOL bReturn=FALSE;
|
|
|
|
CCurveEx* pc=new CCurveEx(2);
|
|
pc->nPoint=4;
|
|
pc->bAutoLocation=FALSE;
|
|
|
|
int num=pExtendCurve->num;
|
|
dfPoint dp_bak;
|
|
dp_bak.x0=pExtendCurve->x[num-2];
|
|
dp_bak.y0=pExtendCurve->y[num-2];
|
|
dp_bak.z0=pExtendCurve->z[num-2];
|
|
dp_bak.l =pExtendCurve->l[num-2];
|
|
|
|
CPoint2D point;
|
|
if(nExtendIdea==0||nExtendIdea==2)//延伸头
|
|
{
|
|
bp.x0=pExtendCurve->x[0];
|
|
bp.y0=pExtendCurve->y[0];
|
|
point.SetPoint(bp.x0, bp.y0);
|
|
|
|
pExtendCurve->Extend(maxExtendLength,0);//0=延伸头
|
|
pc->x[0]=pExtendCurve->x[0];
|
|
pc->y[0]=pExtendCurve->y[0];
|
|
pc->z[0]=pExtendCurve->z[0];
|
|
pc->l[0]=pExtendCurve->l[0];
|
|
pc->x[1]=pExtendCurve->x[1];
|
|
pc->y[1]=pExtendCurve->y[1];
|
|
pc->z[1]=pExtendCurve->z[1];
|
|
pc->l[1]=pExtendCurve->l[1];
|
|
pc->Cross(*(CCurve*)pBaseCurve,list);
|
|
if(list.GetCount()>0)
|
|
{
|
|
cp=CItemSolid::GetNearestCrossPoint(list, point);
|
|
pc->GetCoordinate(cp.x[0],dp.x0,dp.y0,dp.z0);
|
|
pExtendCurve->x[0]=dp.x0;
|
|
pExtendCurve->y[0]=dp.y0;
|
|
pExtendCurve->z[0]=dp.z0;
|
|
pExtendCurve->l[0]=cp.x[0];
|
|
bReturn=TRUE;
|
|
|
|
////判断夹角
|
|
//CPoint2D p1(pc->x[1], pc->y[1]);
|
|
//CPoint2D p2(dp.x0, dp.y0);
|
|
//CPoint2D p3;
|
|
//int i=pf.BinarySearch(cp.x[1], pBaseCurve->num, pBaseCurve->l);
|
|
//p3.SetPoint(pBaseCurve->x[i], pBaseCurve->y[i]);
|
|
//double a1=pf.GetAngle(p1.x0, p1.y0, p2.x0, p2.y0, p3.x0, p3.y0);
|
|
//if(a1<0) a1+=360;
|
|
//p3.SetPoint(pBaseCurve->x[i+1], pBaseCurve->y[i+1]);
|
|
//double a2=pf.GetAngle(p1.x0, p1.y0, p2.x0, p2.y0, p3.x0, p3.y0);
|
|
//if(a2<0) a2+=360;
|
|
//a1=min(a1, a2);
|
|
//if(a1>30)
|
|
//{
|
|
// pExtendCurve->x[0]=dp.x0;
|
|
// pExtendCurve->y[0]=dp.y0;
|
|
// pExtendCurve->z[0]=dp.z0;
|
|
// pExtendCurve->l[0]=cp.x[0];
|
|
// bReturn=TRUE;
|
|
//}
|
|
//else
|
|
//{
|
|
// pExtendCurve->x[0]=bp.x0;
|
|
// pExtendCurve->y[0]=bp.y0;
|
|
//}
|
|
}
|
|
else
|
|
{
|
|
pExtendCurve->x[0]=bp.x0;
|
|
pExtendCurve->y[0]=bp.y0;
|
|
}
|
|
}
|
|
if(nExtendIdea==1||nExtendIdea==2)//延伸尾
|
|
{
|
|
bp.x0=pExtendCurve->x[num-1];
|
|
bp.y0=pExtendCurve->y[num-1];
|
|
point.SetPoint(bp.x0, bp.y0);
|
|
|
|
list.RemoveAll();
|
|
pExtendCurve->Extend(maxExtendLength,1);//1=延伸尾
|
|
pc->x[0]=dp_bak.x0;
|
|
pc->y[0]=dp_bak.y0;
|
|
pc->z[0]=dp_bak.z0;
|
|
pc->l[0]=dp_bak.l;
|
|
pc->x[1]=pExtendCurve->x[num-1];
|
|
pc->y[1]=pExtendCurve->y[num-1];
|
|
pc->z[1]=pExtendCurve->z[num-1];
|
|
pc->l[1]=pExtendCurve->l[num-1];
|
|
pc->Cross(*(CCurve*)pBaseCurve,list);
|
|
if(list.GetCount()>0)
|
|
{
|
|
cp=CItemSolid::GetNearestCrossPoint(list, point);
|
|
pc->GetCoordinate(cp.x[0],dp.x0,dp.y0,dp.z0);
|
|
pExtendCurve->x[num-1]=dp.x0;
|
|
pExtendCurve->y[num-1]=dp.y0;
|
|
pExtendCurve->z[num-1]=dp.z0;
|
|
pExtendCurve->l[num-1]=cp.x[0];
|
|
bReturn=TRUE;
|
|
|
|
////判断夹角
|
|
//CPoint2D p1(pc->x[0], pc->y[0]);
|
|
//CPoint2D p2(dp.x0, dp.y0);
|
|
//CPoint2D p3;
|
|
//int i=pf.BinarySearch(cp.x[1], pBaseCurve->num, pBaseCurve->l);
|
|
//p3.SetPoint(pBaseCurve->x[i], pBaseCurve->y[i]);
|
|
//double a1=pf.GetAngle(p1.x0, p1.y0, p2.x0, p2.y0, p3.x0, p3.y0);
|
|
//if(a1<0) a1+=360;
|
|
//p3.SetPoint(pBaseCurve->x[i+1], pBaseCurve->y[i+1]);
|
|
//double a2=pf.GetAngle(p1.x0, p1.y0, p2.x0, p2.y0, p3.x0, p3.y0);
|
|
//if(a2<0) a2+=360;
|
|
//a1=min(a1, a2);
|
|
//if(a1>30)
|
|
//{
|
|
// pExtendCurve->x[num-1]=dp.x0;
|
|
// pExtendCurve->y[num-1]=dp.y0;
|
|
// pExtendCurve->z[num-1]=dp.z0;
|
|
// pExtendCurve->l[num-1]=cp.x[0];
|
|
// bReturn=TRUE;
|
|
//}
|
|
//else
|
|
//{
|
|
// pExtendCurve->x[num-1]=bp.x0;
|
|
// pExtendCurve->y[num-1]=bp.y0;
|
|
//}
|
|
}
|
|
else
|
|
{
|
|
pExtendCurve->x[num-1]=bp.x0;
|
|
pExtendCurve->y[num-1]=bp.y0;
|
|
}
|
|
}
|
|
delete pc;
|
|
return bReturn;
|
|
}
|
|
|
|
int CItemExtendCurve::ProcessCurve(CCurveEx* pCurve, COne* pOne, CPoint2D* pPoint)
|
|
{
|
|
//延伸曲线
|
|
CCurveEx* pSourceCurve=(CCurveEx*)pOne->GetValue();
|
|
CCurveEx* pExtendCurve=new CCurveEx;
|
|
*pExtendCurve=*pSourceCurve;
|
|
|
|
if(ExtendCurve(pCurve, pExtendCurve, m_nExtendIdea))
|
|
{
|
|
if(pExtendCurve->bAutoLocation)
|
|
pExtendCurve->GetLocation();
|
|
if (AddCurve(pOne, pExtendCurve))
|
|
{
|
|
m_bExtendCurveFinished = true;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
m_bExtendCurveFinished= true;
|
|
|
|
delete pExtendCurve;
|
|
return 0;
|
|
}
|
|
|
|
int CItemExtendCurve::ExtendCurve(CPositionList& baseList)
|
|
{
|
|
DelList.RemoveAll();
|
|
AddList.RemoveAll();
|
|
|
|
COne *pOne, *pBaseOne;
|
|
|
|
//获得所有曲线
|
|
CPtrList faultList;
|
|
POSITION pos,pt;
|
|
pos=baseList.GetHeadPosition();
|
|
while(pos)
|
|
{
|
|
pt=baseList.GetNext(pos);
|
|
pOne=GetDoc()->GetDraw()->GetAt(pt);
|
|
if(!pOne->IsCanEdit() || !pOne->IsView()) continue;
|
|
if(pOne->GetType()!=DOUBLEFOX_CURVE) continue;
|
|
faultList.AddTail(pOne);
|
|
}
|
|
|
|
//GetDoc()->BeginProgress(ID_LAYERTREE_EXTEND_CURVE);
|
|
|
|
double len=GetDoc()->GetDraw()->GetCount();
|
|
long count=0;
|
|
int num=0;
|
|
CCurveEx *pCurve, *pBaseCurve, *pExtendCurve;
|
|
|
|
pos=GetDoc()->GetDraw()->GetValueList()->GetHeadPosition();
|
|
while(pos)
|
|
{
|
|
AfxGetPublicFunction()->SetProgressPos(AfxGetPublicFunction()->FloatToLong(++count/len*100));
|
|
|
|
curPos=pos;
|
|
pOne=(COne*)GetDoc()->GetDraw()->GetValueList()->GetNext(pos);
|
|
pCurve = (CCurveEx*)pOne->GetValue();
|
|
if(!pOne->IsCanEdit() || !pOne->IsView()) continue;
|
|
if(pOne->GetType()!=DOUBLEFOX_CURVE) continue;
|
|
if(FindPosition(faultList, pOne)!=NULL) continue; //该曲线是基线时
|
|
if (pCurve->num < 2) continue;
|
|
|
|
if (pCurve->num == 2)//如果曲线是两个点构成的,在中间插入一个点,满足后续算法要求
|
|
{
|
|
CPointList pl;
|
|
dfPoint dp,dp1,dp2;
|
|
pCurve->GetPoint(0, dp1);
|
|
pCurve->GetPoint(1, dp2);
|
|
pl.AddTail(dp1);
|
|
dp = dp1;
|
|
dp.x0 = dp1.x0 + (dp2.x0 - dp1.x0) / 2;
|
|
dp.y0 = dp1.y0 + (dp2.y0 - dp1.y0) / 2;
|
|
pl.AddTail(dp);
|
|
pl.AddTail(dp2);
|
|
pCurve->SetPoints(pl, pCurve->nPoint, 1);
|
|
pCurve->GetLocation();
|
|
}
|
|
pExtendCurve=new CCurveEx;
|
|
*pExtendCurve=*pCurve;
|
|
num=0;
|
|
pt=FindBaseCurve(faultList, pCurve, FALSE); //延伸头
|
|
if(pt)
|
|
{
|
|
pBaseOne=(COne*)faultList.GetAt(pt);
|
|
pBaseCurve=(CCurveEx*)pBaseOne->GetValue();
|
|
if(ExtendCurve(pBaseCurve, pExtendCurve, 0)) //0=延伸头
|
|
num++;
|
|
pExtendCurve->GetLocation();
|
|
}
|
|
pt=FindBaseCurve(faultList, pCurve, TRUE); //延伸尾
|
|
if(pt)
|
|
{
|
|
pBaseOne=(COne*)faultList.GetAt(pt);
|
|
pBaseCurve=(CCurveEx*)pBaseOne->GetValue();
|
|
if(ExtendCurve(pBaseCurve, pExtendCurve, 1)) //1=延伸尾
|
|
num++;
|
|
pExtendCurve->GetLocation();
|
|
}
|
|
if(num>0)
|
|
{
|
|
if(pExtendCurve->bAutoLocation)
|
|
pExtendCurve->GetLocation();
|
|
AddCurve(pOne,pExtendCurve);
|
|
DelList.AddTail(curPos);
|
|
}
|
|
else
|
|
delete pExtendCurve;
|
|
}
|
|
|
|
//for undo/redo
|
|
if(DelList.GetCount()>0 || AddList.GetCount()>0)
|
|
{
|
|
CActionListItem* pItem=new CActionListItem(GetDoc(),m_nActionID);
|
|
pItem->AddDeleteItem(DelList);
|
|
pItem->AddAddItem(AddList);
|
|
GetDoc()->SetActionItem(pItem);
|
|
|
|
DelList.RemoveAll();
|
|
AddList.RemoveAll();
|
|
}
|
|
//GetDoc()->EndProgress();
|
|
|
|
return 0;
|
|
}
|
|
|
|
//按照点到直线的距离获得最近曲线
|
|
POSITION CItemExtendCurve::FindBaseCurve(CPtrList& list, CCurveEx* pCurve, BOOL bIsTail)
|
|
{
|
|
//maxExtendLength=GetPreferences().WorkaroundEdit.m_dMaxExtendLength;
|
|
//maxExtendLength = 5000; //TODO;需要用户设置
|
|
maxExtendLength = Global_GetExtendLength();
|
|
|
|
CPoint2D point;
|
|
if(bIsTail)
|
|
point.SetPoint(pCurve->x[pCurve->num-1], pCurve->y[pCurve->num-1]);
|
|
else
|
|
point.SetPoint(pCurve->x[0], pCurve->y[0]);
|
|
|
|
//当需要延伸的距离大于曲线两端点之间的距离时
|
|
double dis=AfxGetPublicFunction()->Distance(pCurve->x[pCurve->num-1], pCurve->y[pCurve->num-1], pCurve->x[0], pCurve->y[0]);
|
|
if(dis<maxExtendLength*0.5 && fabs(pCurve->l[pCurve->num-1]-pCurve->l[0])>dis*2)
|
|
return NULL;
|
|
|
|
CRect8 range(point.x0, point.y0, point.x0, point.y0);
|
|
range.InflateRect(maxExtendLength*2, maxExtendLength*2);
|
|
|
|
POSITION findPos=NULL;
|
|
POSITION bkpos;
|
|
double l0;
|
|
double min_dis=1e300;
|
|
int count=0;
|
|
COne* pBaseOne;
|
|
CCurveEx* pBaseCurve;
|
|
POSITION pos=list.GetHeadPosition();
|
|
while(pos)
|
|
{
|
|
bkpos=pos;
|
|
pBaseOne=(COne*)list.GetNext(pos);
|
|
pBaseCurve=(CCurveEx*)pBaseOne->GetValue();
|
|
if(!pBaseCurve->IsInRange(range)) continue;
|
|
|
|
dis=pBaseCurve->PointDistance(point.x0, point.y0, l0);
|
|
if(count==0)
|
|
{
|
|
findPos=bkpos;
|
|
min_dis=dis;
|
|
}
|
|
else if(min_dis>dis)
|
|
{
|
|
findPos=bkpos;
|
|
min_dis=dis;
|
|
}
|
|
count++;
|
|
}
|
|
if(min_dis>maxExtendLength) return NULL;
|
|
if(findPos==NULL) return NULL;
|
|
|
|
//如果与断层已经有交点时
|
|
CCrossPoint cp;
|
|
CCrossList cplist;
|
|
pBaseOne=(COne*)list.GetAt(findPos);
|
|
pBaseCurve=(CCurveEx*)pBaseOne->GetValue();
|
|
pCurve->Cross(*(CCurve*)pBaseCurve,cplist);
|
|
if(cplist.GetCount()>0)
|
|
{
|
|
if(cplist.GetCount()==1)
|
|
{
|
|
cp=cplist.GetHead();
|
|
if(bIsTail)
|
|
{
|
|
if(fabs(cp.x[0]-pCurve->l[0]) > fabs(cp.x[0]-pCurve->l[pCurve->num-1]))
|
|
return NULL;
|
|
}
|
|
else
|
|
{
|
|
if(fabs(cp.x[0]-pCurve->l[0]) < fabs(cp.x[0]-pCurve->l[pCurve->num-1]))
|
|
return NULL;
|
|
}
|
|
}
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
return findPos;
|
|
}
|
|
|
|
BOOL CItemExtendCurve::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
|
|
{
|
|
switch(nChar)
|
|
{
|
|
case VK_RETURN:
|
|
m_pSelectCurve->RemoveAllSelect();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return CItemBreakCurve::OnKeyUp(nChar, nRepCnt, nFlags);
|
|
}
|
|
|
|
}//namespace
|
|
|