400 lines
6.7 KiB
C++
400 lines
6.7 KiB
C++
//-----------------------------------------------------------------------------+
|
|
// Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd.
|
|
// = FileName : TPGeGLineSeg3D.cpp
|
|
// = Version : ver2.0
|
|
// = Author : xlc
|
|
// = CreateDate : 2002-09-09
|
|
// = Description: 类的定义
|
|
// = Maintainers:
|
|
//
|
|
//-----------------------------------------------------------------------------+
|
|
#include "StdAfx.h"
|
|
#include "TPGeGLineSeg3D.h"
|
|
#include "TGPoint3D.h"
|
|
#include "TPGeGLineRay3D.h"
|
|
|
|
IMPLEMENT_RUN_TIME_CLASS1(TPGeGLineSeg3D,"TPGeGLineSeg3D",TPGeGLine3D)
|
|
|
|
TPGeGLineSeg3D::TPGeGLineSeg3D()
|
|
{
|
|
|
|
}
|
|
|
|
TPGeGLineSeg3D::TPGeGLineSeg3D(const TGVector3D&vt,const TGPoint&pt)
|
|
: TPGeGLine3D(vt,pt)
|
|
{
|
|
|
|
}
|
|
|
|
TPGeGLineSeg3D::TPGeGLineSeg3D(const TGPoint&pt0,const TGPoint&pt1)
|
|
: TPGeGLine3D(pt0,pt1)
|
|
{
|
|
|
|
}
|
|
|
|
TPGeGLineSeg3D::TPGeGLineSeg3D(const TPGeLine3D&line)
|
|
: TPGeGLine3D(line)
|
|
{
|
|
|
|
}
|
|
|
|
TPGeGLineSeg3D::~TPGeGLineSeg3D()
|
|
{
|
|
|
|
}
|
|
|
|
const TGPoint& TPGeGLineSeg3D::GetStartPoint()const
|
|
{
|
|
return basePoint;
|
|
}
|
|
|
|
TGPoint TPGeGLineSeg3D::GetEndPoint()const
|
|
{
|
|
return TGPoint(basePoint.x + a,basePoint.y + b,basePoint.z + c);
|
|
}
|
|
|
|
TGPoint TPGeGLineSeg3D::GetMidPoint()const
|
|
{
|
|
return TGPoint(basePoint.x + a / 2,basePoint.y + b / 2,basePoint.z + c / 2);
|
|
}
|
|
|
|
const TPGeLine3D &TPGeGLineSeg3D::GetGeLine()const
|
|
{
|
|
return *this;
|
|
}
|
|
|
|
void TPGeGLineSeg3D::GetStartPoint(TGPoint&pt)const
|
|
{
|
|
pt = basePoint;
|
|
}
|
|
|
|
void TPGeGLineSeg3D::GetEndPoint(TGPoint&pt)const
|
|
{
|
|
pt = GetEndPoint();
|
|
}
|
|
|
|
bool TPGeGLineSeg3D::IsFinite(bool bStart)const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
double TPGeGLineSeg3D::Length()const
|
|
{
|
|
return TPGeLine3D::Length();
|
|
}
|
|
|
|
void TPGeGLineSeg3D::Reverse()
|
|
{
|
|
basePoint = GetEndPoint();
|
|
TPGeLine3D::Reverse();
|
|
}
|
|
|
|
TGObject2D* TPGeGLineSeg3D::Convert2D()const
|
|
{
|
|
return new TPGeGLineSeg2D(TGVector2D(x,y),basePoint);
|
|
}
|
|
|
|
TGObject * TPGeGLineSeg3D::Clone()const
|
|
{
|
|
return new TPGeGLineSeg3D(*this);
|
|
}
|
|
|
|
GRelation TPGeGLineSeg3D::HitTest(const TGPoint&pt)const
|
|
{
|
|
GRelation r = TPGeLine3D::HitTest(pt);
|
|
if (r.Is(GR_IN))
|
|
{
|
|
double pa;
|
|
Pt2Pa(pt,pa);
|
|
if (DOWN_ZERO(pa))
|
|
{
|
|
return GR_OUT;
|
|
}
|
|
else
|
|
{
|
|
pa -= 1 ;
|
|
if (UP_ZERO(pa))
|
|
{
|
|
return GR_OUT;
|
|
}
|
|
else
|
|
{
|
|
return GR_IN;
|
|
}
|
|
}
|
|
}
|
|
return r;
|
|
}
|
|
|
|
bool TPGeGLineSeg3D::Intersect(const TGObject&obj,TGObjectList&res)const
|
|
{
|
|
switch(obj.GetClassID())
|
|
{
|
|
case CID_GLine3D:
|
|
{
|
|
double pa;
|
|
int ret = TPGeLine3D::Intersect((const TPGeGLine3D&)obj,pa);
|
|
if (ret == INT_NULL)
|
|
{
|
|
return false;
|
|
}
|
|
else if (ret == INT_LINE)
|
|
{
|
|
res<<new TPGeGLineSeg3D(*this);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
if (DOWN_ZERO(pa) || UP_ZERO(pa - 1))
|
|
return false;
|
|
else
|
|
{
|
|
TGPoint3D *pPt = new TGPoint3D;
|
|
Pa2Pt(pa,*pPt);
|
|
res<<pPt;
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
case CID_GLineRay3D:
|
|
{
|
|
double pa1,pa2;
|
|
const TPGeGLineRay3D&ray = (const TPGeGLineRay3D&)obj;
|
|
int ret = TPGeLine3D::Intersect(ray,pa1,pa2);
|
|
if (ret == INT_NULL)
|
|
{
|
|
return false;
|
|
}
|
|
else if (ret == INT_LINE)
|
|
{
|
|
TPGeGLineSeg3D seg(*this);
|
|
if (IsReverseDirection(ray))
|
|
{
|
|
seg.Reverse();
|
|
}
|
|
ray.Pt2Pa(seg.GetStartPoint(),pa1);
|
|
if (UPEQUAL_ZERO(pa1))
|
|
{
|
|
res<<new TPGeGLineSeg3D(seg);
|
|
}
|
|
else
|
|
{
|
|
seg.Pt2Pa(ray.basePoint,pa1);
|
|
pa1 -= 1;
|
|
if (UP_ZERO(pa1))
|
|
{
|
|
return false;
|
|
}
|
|
else if (DOWN_ZERO(pa1))
|
|
{
|
|
res<<new TPGeGLineSeg3D(ray.basePoint,GetEndPoint());
|
|
}
|
|
else
|
|
{
|
|
res<<new TGPoint3D(ray.basePoint);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
if (DOWN_ZERO(pa1) || DOWN_ZERO(pa2) || UP_ZERO(pa1-1))
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
TGPoint3D *pPt = new TGPoint3D;
|
|
Pa2Pt(pa1,*pPt);
|
|
res<<pPt;
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
case CID_GLineSeg3D:
|
|
{
|
|
double pa1,pa2;
|
|
const TPGeGLineSeg3D&seg = (const TPGeGLineSeg3D&)obj;
|
|
int ret = TPGeLine3D::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 TGPoint3D(GetStartPoint());
|
|
}
|
|
else if (EQUAL_ZERO(pa1-1))
|
|
{
|
|
res<<new TGPoint3D(GetEndPoint());
|
|
}
|
|
else
|
|
{
|
|
pa1 = Max2(pa1,0.0);
|
|
pa2 = Min2(pa2,1.0);
|
|
TGPoint sPt,ePt;
|
|
Pa2Pt(pa1,sPt);
|
|
Pa2Pt(pa2,ePt);
|
|
res<<new TPGeGLineSeg3D(sPt,ePt);
|
|
}
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
if (DOWN_ZERO(pa1) || DOWN_ZERO(pa2) || UP_ZERO(pa1-1) || UP_ZERO(pa2-1))
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
TGPoint3D *pPt = new TGPoint3D;
|
|
Pa2Pt(pa1,*pPt);
|
|
res<<pPt;
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
default:
|
|
return obj.Intersect(*this, res);
|
|
}
|
|
}
|
|
|
|
bool TPGeGLineSeg3D::IsInclude(const TGObject&obj)const
|
|
{
|
|
switch(obj.GetClassID())
|
|
{
|
|
case CID_GLine3D:
|
|
case CID_GLineRay3D:
|
|
return false;
|
|
case CID_GLineSeg3D:
|
|
{
|
|
const TPGeGLineSeg3D& seg = (const TPGeGLineSeg3D&)obj;
|
|
return HitTest(seg.GetStartPoint()).Is(GR_IN) && HitTest(seg.GetEndPoint()).Is(GR_IN);
|
|
}
|
|
default:
|
|
return TPGeCurve3D::IsInclude(obj);
|
|
}
|
|
}
|
|
|
|
bool TPGeGLineSeg3D::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;
|
|
}
|
|
|
|
bool TPGeGLineSeg3D::GetExtend3D(TPGeExtend3D&ext)const
|
|
{
|
|
double x0,x1,y0,y1,z0,z1;
|
|
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;
|
|
}
|
|
if (c > 0)
|
|
{
|
|
z0 = basePoint.z;
|
|
z1 = z0+c;
|
|
}
|
|
else
|
|
{
|
|
z1 = basePoint.z;
|
|
z0 = z1+c;
|
|
}
|
|
ext.SetRange(x0,x1,y0,y1,z0,z1);
|
|
return true;
|
|
}
|
|
|
|
void TPGeGLineSeg3D::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 TPGeGLineSeg3D(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 TPGeGLineSeg3D(pt0,pt1);
|
|
pt0 = pt1;
|
|
}
|
|
if (UP_ZERO( 1 - paTable.GetAt(i - 1)))
|
|
{
|
|
res<<new TPGeGLineSeg3D(pt0,GetEndPoint());
|
|
}
|
|
}
|
|
|
|
bool TPGeGLineSeg3D::IsSameSeg(const TPGeGLineSeg3D&seg,bool bSameDirection)const
|
|
{
|
|
if (TGVector3D::operator == (seg) && basePoint == seg.basePoint)
|
|
{
|
|
return true;
|
|
}
|
|
else if (!bSameDirection)
|
|
{
|
|
return basePoint == seg.GetEndPoint() && seg.basePoint == GetEndPoint();
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
} |