#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(disl[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