Files
envi-code/SourceCode/Code2026/tg_shs/shs_subgeLib/TGMCurve2D.cpp
T
2026-09-28 15:28:50 +08:00

565 lines
9.6 KiB
C++

//-------------------------------------------------------------------------------------------------------+
// 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;i<GetSegNum();i++)
{
const TPGeCurve2D*pSeg = GetAt(i);
if (pSeg == NULL || !pSeg->IsValid())
{
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<TPGeCurve2D*> 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;i<GetLength();i++)
{
TPGeCurve2D*pSegi = segs[i];
for (long j = i+1;j<GetLength();j++)
{
TPGeCurve2D*pSegj = segs[j];
TGObjectList oList;
if (pSegi->Intersect(*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;i<iSeg1;i++)
{
pMC->AddTail((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;i<GetSegNum();i++)
{
pMC->AddTail((TPGeCurve2D*)(GetAt(i)->Clone()));
}
for (i = 0;i<iSeg1;i++)
{
pMC->AddTail((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;i<GetSegNum();i++)
{
pMC->AddTail((TPGeCurve2D*)(GetAt(i)->Clone()));
}
for (i = 0;i<iSeg;i++)
{
pMC->AddTail((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;i<seg1;i++)
{
pSeg = GetAt(i);
r += pSeg->AllIntegration();
}
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;i<seg1;i++)
{
pSeg = GetAt(i);
r += pSeg->AllIntegration();
}
return -r;
}
else
{
return 0;
}
}
TGMLine2D* TGMCurve2D::MLinearize(double paDist) const
{
if (!TPGeCurve2D::IsFinite())
{
return NULL;
}
TList<TGPoint> 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;i<num;i++)
{
ptList<<(*pML)[i];
}
delete pML;
}
bool bClosed = IsClosed();
if (!bClosed)
{
TGPoint2D pt;
GetAt(GetLastIndex())->GetEndPoint(pt);
ptList<<pt;
}
return new TGMLine2D(ptList,bClosed);
}
TGMLine2D* TGMCurve2D::PLinearize(double paDist) const
{
if (!TPGeCurve2D::IsFinite())
{
return NULL;
}
TSPTable<TGMLine2D> 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;i<plines.GetLength();i++)
{
TGMLine2D*pLine = plines[i];
if (IS_CLASS(pLine,TGPLine2D))
{
TGPLine2D *pLine1 = (TGPLine2D*)pLine;
for (long j = 0;j<pLine1->GetSegNum();j++)
{
(*pRes)[count] = (*pLine1)[j];
(*pRes)(count++) = (*pLine1)(j);
}
}
else
{
for (long j = 0;j<pLine->GetSegNum();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;i<plines.GetLength();i++)
{
TGMLine2D*pLine = plines[i];
for (long j = 0;j<pLine->GetSegNum();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;
}