Files
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

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;
}
}