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.
kev/Drawer/Module/GeoSigmaDraw/ItemExtendCurve.cpp

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