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

421 lines
7.9 KiB
C++

//-------------------------------------------------------------------------------------------------------+
// Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd.
// = FileName : TPGeGLineSeg2D Àà
// = Version : ver2.0
// = Author : wlw
// = CreateDate : 2002-09-09
// = Description: TPGeGLineSeg2D ¶¨Òå
// = Maintainers:
//
//-------------------------------------------------------------------------------------------------------+
#include "StdAfx.h"
#include "TPGeGLineSeg2D.h"
#include "TPGeGLineSeg3D.h"
#include "TGPoint2D.h"
IMPLEMENT_RUN_TIME_CLASS1(TPGeGLineSeg2D,"TPGeGLineSeg2D",TPGeGLine2D)
TPGeGLineSeg2D::TPGeGLineSeg2D()
{
}
TPGeGLineSeg2D::TPGeGLineSeg2D(const TGVector2D& vt,const TGPoint& pt):TPGeGLine2D(vt,pt)
{
}
TPGeGLineSeg2D::TPGeGLineSeg2D(const TGPoint& pt0,const TGPoint& pt1):TPGeGLine2D(pt0,pt1)
{
}
TPGeGLineSeg2D::TPGeGLineSeg2D(const TPGeLine2D& line):TPGeGLine2D(line)
{
}
TPGeGLineSeg2D::~TPGeGLineSeg2D()
{
}
const TGPoint& TPGeGLineSeg2D::GetStartPoint() const
{
return basePoint;
}
TGPoint TPGeGLineSeg2D::GetEndPoint() const
{
return TGPoint(basePoint.x + a,basePoint.y + b,basePoint.z + c);
}
TGPoint TPGeGLineSeg2D::GetMidPoint() const
{
return TGPoint(basePoint.x + a / 2,basePoint.y + b / 2,basePoint.z + c / 2);
}
void TPGeGLineSeg2D::GetStartPoint(TGPoint& pt) const
{
pt = basePoint;
}
void TPGeGLineSeg2D::GetEndPoint(TGPoint& pt) const
{
pt = GetEndPoint();
}
bool TPGeGLineSeg2D::IsFinite(bool bStart) const
{
return true;
}
TPGeCurve2D* TPGeGLineSeg2D::GetExtendCurve() const
{
return new TPGeGLine2D(*this);
}
double TPGeGLineSeg2D::Length() const
{
return TPGeLine2D::Length();
}
void TPGeGLineSeg2D::Reverse()
{
basePoint = GetEndPoint();
TPGeLine2D::Reverse();
}
TGObject * TPGeGLineSeg2D::Clone() const
{
return new TPGeGLineSeg2D(*this);
}
bool TPGeGLineSeg2D::IsSameSeg(const TPGeGLineSeg2D&seg,bool bSameDirection) const
{
if (TGVector2D::operator == (seg) && basePoint.Equal2D(seg.basePoint))
{
return true;
}
else if (!bSameDirection)
{
return basePoint.Equal2D(seg.GetEndPoint()) && seg.basePoint.Equal2D(GetEndPoint());
}
else
{
return false;
}
}
GRelation TPGeGLineSeg2D::HitTest(const TGPoint&pt) const
{
GRelation r = TPGeLine2D::HitTest(pt);
if (r.Is(GR_IN))
{
double pa;
Pt2Pa(pt,pa);
if (DOWN_ZERO(pa) && UP_ZEROD(Distance2D(basePoint,pt)))
{
return GR_OUT;
}
else
{
pa -= 1;
if (UP_ZERO(pa) && UP_ZEROD(Distance2D(GetEndPoint(),pt)))
{
return GR_OUT;
}
else
{
return GR_IN;
}
}
}
return r;
}
void TPGeGLineSeg2D::Split(const TTable<double>&paTable,TGObjectList&res) const
{
if (paTable.IsEmpty())
{
return;
}
TGPoint pt0;
if (UP_ZERO(paTable.GetAt(0)))
{
Pa2Pt(paTable.GetAt(0),pt0);
res<<new TPGeGLineSeg2D(basePoint,pt0);
}
else
{
pt0 = basePoint;
}
for (long i = 1;i < paTable.GetLength();i++)
{
if (UP_ZERO(paTable.GetAt(i)- paTable.GetAt(i - 1)))
{
TGPoint pt1;
Pa2Pt(paTable.GetAt(i),pt1);
res<<new TPGeGLineSeg2D(pt0,pt1);
pt0 = pt1;
}
}
if (UP_ZERO(1 - paTable.GetAt(i - 1)))
{
res<<new TPGeGLineSeg2D(pt0,GetEndPoint());
}
}
bool TPGeGLineSeg2D::SubtractBy(const TPGeGLineSeg2D&seg,TGObjectList&res) const
{
TGObjectList oList;
if (Intersect(seg,oList) && IS_TYPE(oList[0],TPGeGLineSeg2D))
{
const TPGeGLineSeg2D& seg1 = (const TPGeGLineSeg2D&)(oList.GetCurPData());
double pa1,pa2;
Pt2Pa(seg1.GetStartPoint(),pa1);
Pt2Pa(seg1.GetEndPoint(),pa2);
if (UP_ZERO(pa1))
{
res<<new TPGeGLineSeg2D(GetStartPoint(),seg1.GetStartPoint());
}
if (DOWN_ZERO(pa2 - 1))
{
res<<new TPGeGLineSeg2D(seg1.GetEndPoint(),GetEndPoint());
}
return true;
}
return false;
}
void TPGeGLineSeg2D::SubtractBy(const TGObjectList&oList,TGObjectList&res) const
{
TGObjectList oList1(*this),oList2;
for (TGObject*const*pCur = oList.GetFirst(); pCur != NULL; pCur = oList.GetNext(pCur))
{
if (!IS_TYPE(*pCur,TPGeGLineSeg2D))
{
continue;
}
const TPGeGLineSeg2D&seg1 = (const TPGeGLineSeg2D&)(**pCur);
for (oList1.MoveToFirst();!oList1.IsOut();oList1.MoveToNext())
{
const TPGeGLineSeg2D&seg2 = (const TPGeGLineSeg2D&)(oList1.GetCurPData());
if (seg2.SubtractBy(seg1,oList2))
{
oList1.DelCur();
}
}
oList1.Conbine(oList2);
if (oList1.IsEmpty())
{
return;
}
}
res.Conbine(oList1);
}
bool TPGeGLineSeg2D::Intersect(const TGObject&obj,TGObjectList&res) const
{
switch(obj.GetClassID())
{
case CID_GLine2D:
{
double pa;
int ret = TPGeLine2D::Intersect((const TPGeGLine2D&)obj,pa);
if (ret == INT_NULL)
{
return false;
}
else if (ret == INT_LINE)
{
res<<new TPGeGLineSeg2D(*this);
return true;
}
else
{
if (DOWN_ZERO(pa) || UP_ZERO(pa - 1))
{
return false;
}
else
{
TGPoint2D *pPt = new TGPoint2D;
Pa2Pt(pa,*pPt);
res<<pPt;
return true;
}
}
}
case CID_GLineRay2D:
{
double pa1,pa2;
const TPGeGLineRay2D&ray = (const TPGeGLineRay2D&)obj;
int ret = TPGeLine2D::Intersect(ray,pa1,pa2);
if (ret == INT_NULL)
{
return false;
}
else if (ret == INT_LINE)
{
TPGeGLineSeg2D seg(*this);
if (IsReverseDirection(ray))
{
seg.Reverse();
}
ray.Pt2Pa(seg.GetStartPoint(),pa1);
if (UPEQUAL_ZERO(pa1))
{
res<<new TPGeGLineSeg2D(seg);
}
else
{
seg.Pt2Pa(ray.basePoint,pa1);
pa1 -= 1;
if (UP_ZERO(pa1))
{
return false;
}
else if (DOWN_ZERO(pa1))
{
res<<new TPGeGLineSeg2D(ray.basePoint,GetEndPoint());
}
else
{
res<<new TGPoint2D(ray.basePoint);
}
}
return true;
}
else
{
if (DOWN_ZERO(pa1) || DOWN_ZERO(pa2) || UP_ZERO(pa1-1))
{
return false;
}
else
{
TGPoint2D *pPt = new TGPoint2D;
Pa2Pt(pa1,*pPt);
res<<pPt;
return true;
}
}
}
case CID_GLineSeg2D:
{
double pa1,pa2;
const TPGeGLineSeg2D&seg = (const TPGeGLineSeg2D&)obj;
int ret = TPGeLine2D::Intersect(seg,pa1,pa2);
if (ret == INT_NULL)
{
return false;
}
else if (ret == INT_LINE)
{
Pt2Pa(seg.GetStartPoint(),pa1);
Pt2Pa(seg.GetEndPoint(),pa2);
if (pa2<pa1)
{
Exchange(pa1,pa2);
}
if (DOWN_ZERO(pa2) || UP_ZERO(pa1-1))
{
return false;
}
else if (EQUAL_ZERO(pa2))
{
res<<new TGPoint2D(GetStartPoint());
}
else if (EQUAL_ZERO(pa1-1))
{
res<<new TGPoint2D(GetEndPoint());
}
else
{
pa1 = Max2(pa1,0.0);
pa2 = Min2(pa2,1.0);
TGPoint sPt,ePt;
Pa2Pt(pa1,sPt);
Pa2Pt(pa2,ePt);
res<<new TPGeGLineSeg2D(sPt,ePt);
}
return true;
}
else
{
if (DOWN_ZERO(pa1) || DOWN_ZERO(pa2) || UP_ZERO(pa1-1) || UP_ZERO(pa2-1))
{
return false;
}
else
{
TGPoint2D *pPt = new TGPoint2D;
Pa2Pt(pa1,*pPt);
res<<pPt;
return true;
}
}
}
default:
return obj.Intersect(*this, res);
}
}
bool TPGeGLineSeg2D::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;
return HitTest(seg.GetStartPoint()).Is(GR_IN) && HitTest(seg.GetEndPoint()).Is(GR_IN);
}
case CID_GCircle2D:
case CID_GArc2D:
return false;
default:
return TPGeCurve2D::IsInclude(obj);
}
}
bool TPGeGLineSeg2D::GetExtend2D(TPGeExtend2D&ext) const
{
double x0,x1,y0,y1;
if (a > 0)
{
x0 = basePoint.x;
x1 = x0 + a;
}
else
{
x1 = basePoint.x;
x0 = x1 + a;
}
if (b > 0)
{
y0 = basePoint.y;
y1 = y0 + b;
}
else
{
y1 = basePoint.y;
y0 = y1 + b;
}
ext.SetRange(x0,x1,y0,y1);
return true;
}
TGMLine2D* TPGeGLineSeg2D::MLinearize(double paDist) const
{
TGMLine2D* pMLine = new TGMLine2D(2,false);
(*pMLine)[0] = GetStartPoint();
(*pMLine)[1] = GetEndPoint();
return pMLine;
}
TGObject3D* TPGeGLineSeg2D::Convert3D() const
{
return new TPGeGLineSeg3D(TGVector3D(x,y,z),basePoint);
}