//-------------------------------------------------------------------------------------------------------+ // Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd. // = FileName : TGMCurve2D 类 // = Version : ver2.0 // = Author : wlw // = CreateDate : 2002-09-09 // = Description: TGMCurve2D 定义 // = Maintainers: // //-------------------------------------------------------------------------------------------------------+ #include "StdAfx.h" #include "TGMCurve2D.h" #include "TGPoint2D.h" #include "TSPTable.h" #include "TGMLine2D.h" IMPLEMENT_RUN_TIME_CLASS1(TGMCurve2D,"TGMCurve2D",TPGeCurve2D) TGMCurve2D::TGMCurve2D() { } TGMCurve2D::TGMCurve2D(const TPGeCurve2D&curve) { AddTail((TPGeCurve2D*)(curve.Clone())); } TGMCurve2D::~TGMCurve2D() { } TGPoint TGMCurve2D::GetSamplePoint() const { return GetAt(0)->GetSamplePoint(); } double TGMCurve2D::GetElev() const { return GetAt(0)->GetElev(); } TGObject* TGMCurve2D::Clone() const { return new TGMCurve2D(*this); } long TGMCurve2D::GetSegNum() const { return GetLength(); } TGMCurve2D::TGMCurve2D(const TGMCurve2D&curve) { for (TPGeCurve2D*const* p = curve.GetFirst();p != NULL;p = curve.GetNext(p)) { AddTail((TPGeCurve2D*)((*p)->Clone())); } } bool TGMCurve2D::IsValid() const { if (IsEmpty()) { return false; } const TPGeCurve2D* pSeg0 = GetAt(0); if (pSeg0 == NULL || !pSeg0->IsValid()) { return false; } for (long i = 1;iIsValid()) { return false; } if (!pSeg0->IsConnect(*pSeg)) { return false; } pSeg0 = pSeg; } return true; } bool TGMCurve2D::IsClosed() const { if (IsCurveSeg()) { return TPGeCurve2D::IsClosed(); } else if (GetSegNum() == 1) { return GetAt(0)->IsClosed(); } return false; } bool TGMCurve2D::IsFinite(bool bStart) const { if (bStart) { return GetAt(0)->IsFinite(true); } else { return GetAt(GetLastIndex())->IsFinite(false); } } bool TGMCurve2D::IsSelfCross() const { if (GetLength() == 1) { return GetAt(0)->IsSelfCross(); } TArray segs(GetSegNum()); long i = 0; for (TPGeCurve2D*const*p = GetFirst();p != NULL;p = GetNext(p),i++) { if ((*p)->IsClosed() || (*p)->IsSelfCross()) { return true; } segs[i] = (*p); } bool bClosed = IsClosed(); for (i = 0;iIntersect(*pSegj,oList)) { for (oList.MoveToFirst();!oList.IsOut();oList.MoveToNext()) { if (!IS_TYPE(oList.GetCurData(),TGPoint2D)) { return true; } } if (oList.GetLength()>2) { return true; } else if (oList.GetLength() == 2) { if (!(GetLength() == 2 && bClosed)) { return true; } } else { if (!(j == i+1 || (i == 0 && j == GetLastIndex() && bClosed))) { return true; } } } } } return false; } long TGMCurve2D::Pa2Seg(double&pa) const { pa *= GetSegNum(); long i = (long)pa; if (i<0) { i = 0; } else if (i >= GetSegNum()) { i = GetSegNum()-1; } pa -= i; return i; } TPGeCurve2D* TGMCurve2D::GetSubCurve(double pa0,double pa1) const { if (GetSegNum() == 1) { return GetAt(0)->GetSubCurve(pa0,pa1); } TGMCurve2D *pMC = new TGMCurve2D; TGPoint pt; if (IsClosed()) { if (EQUAL_ZERO(pa0-1)) { pa0 = 0; } if (EQUAL_ZERO(pa1-1)) { pa1 = 0; } } if (UP_ZERO(pa1-pa0)) { long iSeg0 = Pa2Seg(pa0),iSeg1 = Pa2Seg(pa1); TPGeCurve2D *pSeg0 = GetAt(iSeg0),*pSeg1 = GetAt(iSeg1); if (iSeg0 == iSeg1) { pMC->AddTail(pSeg0->GetSubCurve(pa0,pa1)); } else { if (DOWN_ZERO(pa0-1)) { pMC->AddTail(pSeg0->GetSubCurve(pa0,1)); } for (long i = iSeg0+1;iAddTail((TPGeCurve2D*)(GetAt(i)->Clone())); } if (UP_ZERO(pa1)) { pMC->AddTail(pSeg1->GetSubCurve(0,pa1)); } } } else if (DOWN_ZERO(pa1-pa0)) { long iSeg0 = Pa2Seg(pa0),iSeg1 = Pa2Seg(pa1); TPGeCurve2D *pSeg0 = GetAt(iSeg0),*pSeg1 = GetAt(iSeg1); if (DOWN_ZERO(pa0-1)) { pMC->AddTail(pSeg0->GetSubCurve(pa0,1)); } for (long i = iSeg0+1;iAddTail((TPGeCurve2D*)(GetAt(i)->Clone())); } for (i = 0;iAddTail((TPGeCurve2D*)(GetAt(i)->Clone())); } if (UP_ZERO(pa1)) { pMC->AddTail(pSeg1->GetSubCurve(0,pa1)); } } else { long iSeg = Pa2Seg(pa0); TPGeCurve2D* pSeg = GetAt(iSeg); if (DOWN_ZERO(pa0-1)) { pMC->AddTail(pSeg->GetSubCurve(pa0,1)); } for (long i = iSeg+1;iAddTail((TPGeCurve2D*)(GetAt(i)->Clone())); } for (i = 0;iAddTail((TPGeCurve2D*)(GetAt(i)->Clone())); } if (UP_ZERO(pa0)) { pMC->AddTail(pSeg->GetSubCurve(0,pa0)); } } if (pMC->GetSegNum() == 1) { TPGeCurve2D *pSeg = pMC->Fetch(0); delete pMC; return pSeg; } else { return pMC; } } void TGMCurve2D::Pa2Pt(double pa,TGPoint&pt) const { if (EQUAL_ZERO(pa)) { GetStartPoint(pt); } else if (EQUAL_ZERO(pa-1)) { GetEndPoint(pt); } else { long i = Pa2Seg(pa); GetAt(i)->Pa2Pt(pa,pt); } } void TGMCurve2D::GetStartPoint(TGPoint&pt) const { if (IsEmpty()) { return; } GetAt(0)->GetStartPoint(pt); } void TGMCurve2D::GetEndPoint(TGPoint &pt) const { if (IsEmpty()) { return; } GetAt(GetLastIndex())->GetEndPoint(pt); } void TGMCurve2D::Pt2Pa(const TGPoint&pt,double&pa) const { pa = -1; long i = 0; for (TPGeCurve2D*const*p = GetFirst();p != NULL;p = GetNext(p),i++) { if ((*p)->HitTest(pt).Is(GR_IN)) { (*p)->Pt2Pa(pt,pa); pa = (pa+i)/GetSegNum(); break; } } } void TGMCurve2D::GetTangent(double pa,TPGeLine2D&line) const { long i = Pa2Seg(pa); GetAt(i)->GetTangent(pa,line); } void TGMCurve2D::Reverse() { for (MoveToFirst();!IsOut();MoveToNext()) { GetCurData()->Reverse(); } ReverseList(); } double TGMCurve2D::Integration(double pa0,double pa1) const { double d = pa0-pa1; if (DOWN_ZERO(d)) { long seg0 = Pa2Seg(pa0),seg1 = Pa2Seg(pa1); TPGeCurve2D*pSeg = GetAt(seg0); if (seg0 == seg1) { return pSeg->Integration(pa0,pa1); } double r = pSeg->Integration(pa0,1); pSeg = GetAt(seg1); r += pSeg->Integration(0,pa1); for (long i = seg0+1;iAllIntegration(); } return r; } else if (UP_ZERO(d)) { TchPrivate::Exchange(pa0,pa1); long seg0 = Pa2Seg(pa0),seg1 = Pa2Seg(pa1); TPGeCurve2D*pSeg = GetAt(seg0); if (seg0 == seg1) { return -pSeg->Integration(pa0,pa1); } double r = pSeg->Integration(pa0,1); pSeg = GetAt(seg1); r += pSeg->Integration(0,pa1); for (long i = seg0+1;iAllIntegration(); } return -r; } else { return 0; } } TGMLine2D* TGMCurve2D::MLinearize(double paDist) const { if (!TPGeCurve2D::IsFinite()) { return NULL; } TList ptList; TGMLine2D* pML; long i; for (TPGeCurve2D*const*p = GetFirst();p != NULL;p = GetNext(p)) { pML = (*p)->MLinearize(paDist); long num = pML->GetSegNum(); for (i = 0;iGetEndPoint(pt); ptList< plines(GetSegNum()); long count = 0; bool bArcExist = false; for (TPGeCurve2D*const* p = GetFirst();p != NULL;p = GetNext(p)) { TGMLine2D* pMLine = (*p)->PLinearize(paDist); if (pMLine == NULL) { return NULL; } count += pMLine->GetSegNum(); if (IS_CLASS(pMLine,TGPLine2D)) { bArcExist = true; } plines.AddTail(pMLine); } bool bClosed = IsClosed(); if (!bClosed) { count++; } if (bArcExist) { TGPLine2D *pRes = new TGPLine2D(count,bClosed); count = 0; for (long i = 0;iGetSegNum();j++) { (*pRes)[count] = (*pLine1)[j]; (*pRes)(count++) = (*pLine1)(j); } } else { for (long j = 0;jGetSegNum();j++) { (*pRes)[count++] = (*pLine)[j]; } } } if (!bClosed) { GetEndPoint((*pRes)[count]); } return pRes; } else { TGMLine2D *pRes = new TGMLine2D(count,bClosed); count = 0; for (long i = 0;iGetSegNum();j++) { (*pRes)[count++] = (*pLine)[j]; } } if (!bClosed) { GetEndPoint((*pRes)[count]); } return pRes; } } void TGMCurve2D::SetElev(double elev) { for (MoveToFirst();!IsOut();MoveToNext()) { GetCurData()->SetElev(elev); } } void TGMCurve2D::TransformBy(const TGMatrix&matrix) { for (MoveToFirst();!IsOut();MoveToNext()) { GetCurData()->TransformBy(matrix); } } bool TGMCurve2D::Explode(TGObjectList&res) const { for (TPGeCurve2D*const* p = GetFirst();p != NULL;p = GetNext(p)) { res << (*p)->Clone(); } return true; } bool TGMCurve2D::IsInclude(const TGObject&obj) const { switch(obj.GetClassID()) { case CID_GLine2D: case CID_GLineRay2D: return false; case CID_GLineSeg2D: { const TPGeGLineSeg2D&seg = (const TPGeGLineSeg2D&)obj; TGObjectList oList,oList1; ExplodeEx(oList); seg.SubtractBy(oList,oList1); return oList1.IsEmpty(); } case CID_GCircle2D: case CID_GArc2D: return false; default: return TPGeCurve2D::IsInclude(obj); } } bool TGMCurve2D::Offset(double offset) { return false; }