421 lines
7.9 KiB
C++
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);
|
|
} |