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

459 lines
8.4 KiB
C++

//-------------------------------------------------------------------------------------------------------+
// Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd.
// = FileName : TPGeCircle2D 类
// = Version : ver2.0
// = Author : wlw
// = CreateDate : 2002-09-09
// = Description: TPGeCircle2D 定义
// = Maintainers:
//
//-------------------------------------------------------------------------------------------------------+
#include "StdAfx.h"
#include "TPGeCircle2D.h"
#include "TGPoint2D.h"
#include "TPGeGLine2D.h"
#include "TPGeGLineRay2D.h"
// #include "TchGeLib.h"
double TPGeCircle2D::g_fMLinePreci = 0.1;
IMPLEMENT_RUN_TIME_CLASS1(TPGeCircle2D,"TPGeCircle2D",TPGeCurve2D)
TPGeCircle2D::TPGeCircle2D(bool bUnclock/* = true*/)
{
if (!bUnclock)
{
AddFlag(CLOCKWISE_CURVE);
}
}
TPGeCircle2D::TPGeCircle2D(const TGPoint& pt,double r,bool bUnclock/* = true*/):TPGeCircle(pt,r)
{
if (!bUnclock)
{
AddFlag(CLOCKWISE_CURVE);
}
}
TPGeCircle2D::TPGeCircle2D(const TPGeCircle& circle,bool bUnclock/* = true*/):TPGeCircle(circle)
{
if (!bUnclock)
{
AddFlag(CLOCKWISE_CURVE);
}
}
TPGeCircle2D::TPGeCircle2D(const TGPoint& pt0,const TGPoint& pt1,const TGPoint& pt2)
{
Init(pt0,pt1,pt2);
}
TPGeCircle2D::TPGeCircle2D(const TGPoint& pt0,const TGPoint& pt1,double angle)
{
Init(pt0,pt1,angle);
}
TPGeCircle2D::~TPGeCircle2D()
{
}
void TPGeCircle2D::GetTangent(double pa,TPGeLine2D&line) const
{
if (Is(CLOCKWISE_CURVE))
{
TPGeCircle::GetTangent(PI2 - pa,line);
line.Reverse();
}
else
{
TPGeCircle::GetTangent(pa,line);
}
}
void TPGeCircle2D::Pt2Pa(const TGPoint& pt,double&pa) const
{
TPGeCircle::Pt2Pa(pt,pa);
if (Is(CLOCKWISE_CURVE))
{
pa = PI2 - pa;
}
}
void TPGeCircle2D::Pa2Pt(double pa,TGPoint& pt) const
{
if (Is(CLOCKWISE_CURVE))
{
TPGeCircle::Pa2Pt(PI2-pa,pt);
}
else
{
TPGeCircle::Pa2Pt(pa,pt);
}
}
void TPGeCircle2D::SetMLinePreci(double preci)
{
g_fMLinePreci = preci;
}
void TPGeCircle2D::Reverse()
{
if (Is(CLOCKWISE_CURVE))
{
RemoveFlag(CLOCKWISE_CURVE);
}
else
{
AddFlag(CLOCKWISE_CURVE);
}
}
bool TPGeCircle2D::IsClosed() const
{
return true;
}
bool TPGeCircle2D::IsFinite(bool bStart) const
{
return false;
}
bool TPGeCircle2D::IsClockwise() const
{
return Is(CLOCKWISE_CURVE);
}
double TPGeCircle2D::Area() const
{
return TPGeCircle::Area();
}
double TPGeCircle2D::Length() const
{
return TPGeCircle::Length();
}
double TPGeCircle2D::GetMLinePrec() const
{
return g_fMLinePreci;
}
bool TPGeCircle2D::Offset(double offset)
{
if (IsClockwise())
{
offset = -offset;
}
return TPGeCircle::Offset(offset);
}
void TPGeCircle2D::SetElev(double elev)
{
center.z = elev;
}
double TPGeCircle2D::GetElev() const
{
return center.z;
}
bool TPGeCircle2D::IsValid() const
{
return TPGeCircle::IsValid();
}
void TPGeCircle2D::TransformBy(const TGMatrix&matrix)
{
matrix.Transform2D(center);
}
TGObject * TPGeCircle2D::Clone() const
{
return new TPGeCircle2D(*this);
}
GRelation TPGeCircle2D::HitTest(const TGPoint& pt) const
{
return TPGeCircle::HitTest(pt);
}
double TPGeCircle2D::Integration(double pa0,double pa1) const
{
if (Is(CLOCKWISE_CURVE))
{
return TPGeCircle::Integration(PI2 - pa0, PI2 - pa1);
}
else
{
return TPGeCircle::Integration(pa0, pa1);
}
}
bool TPGeCircle2D::Intersect(const TGObject& obj, TGObjectList& res) const
{
switch(obj.GetClassID())
{
case CID_GLine2D:
{
TGPoint2D* pPt1 = new TGPoint2D, *pPt2 = new TGPoint2D;
int ret = TPGeCircle::Intersect((const TPGeGLine2D&)obj,*pPt1,*pPt2);
if (ret == INT_NULL)
{
delete pPt1;
delete pPt2;
return false;
}
else if (ret == INT_2PT)
{
res << pPt1 << pPt2;
}
else
{
res << pPt1;
delete pPt2;
}
return true;
}
case CID_GLineRay2D:
{
double pa1,pa2;
const TPGeGLineRay2D& ray = (const TPGeGLineRay2D&)obj;
const TPGeLine2D& line = ray;
int ret = line.Intersect(this,pa1,pa2);
if (ret == INT_NULL)
{
return false;
}
else if (ret == INT_2PT)
{
bool result = false;
if (UPEQUAL_ZERO(pa1))
{
TGPoint2D* pPt = new TGPoint2D;
ray.Pa2Pt(pa1,*pPt);
res << pPt;
result = true;
}
if (UPEQUAL_ZERO(pa2))
{
TGPoint2D* pPt = new TGPoint2D;
ray.Pa2Pt(pa2,*pPt);
res << pPt;
result = true;
}
return result;
}
else
{
if (UPEQUAL_ZERO(pa1))
{
TGPoint2D* pPt = new TGPoint2D;
ray.Pa2Pt(pa1,*pPt);
res << pPt;
return true;
}
return false;
}
}
case CID_GLineSeg2D:
{
double pa1,pa2;
const TPGeGLineSeg2D& seg = (const TPGeGLineSeg2D&)obj;
const TPGeLine2D& line = seg;
int ret = line.Intersect(this,pa1,pa2);
if (ret == INT_NULL)
{
return false;
}
else if (ret == INT_2PT)
{
bool result = false;
if (UPEQUAL_ZERO(pa1) && DOWNEQUAL_ZERO(pa1 - 1))
{
TGPoint2D* pPt = new TGPoint2D;
seg.Pa2Pt(pa1,*pPt);
res << pPt;
result = true;
}
if (UPEQUAL_ZERO(pa2) && DOWNEQUAL_ZERO(pa2 - 1))
{
TGPoint2D* pPt = new TGPoint2D;
seg.Pa2Pt(pa2,*pPt);
res << pPt;
result = true;
}
return result;
}
else
{
if (UPEQUAL_ZERO(pa1) && DOWNEQUAL_ZERO(pa1 - 1))
{
TGPoint2D* pPt = new TGPoint2D;
seg.Pa2Pt(pa1,*pPt);
res << pPt;
return true;
}
return false;
}
}
case CID_GCircle2D:
{
TGPoint2D* pPt1 = new TGPoint2D,*pPt2 = new TGPoint2D;
int ret = TPGeCircle::Intersect((const TPGeCircle2D&)obj,*pPt1,*pPt2);
if (ret == INT_NULL)
{
delete pPt1;
delete pPt2;
return false;
}
else if (ret == INT_2PT)
{
res << pPt1 << pPt2;
}
else if (ret == INT_1PT)
{
res << pPt1;
delete pPt2;
}
else
{
delete pPt1;
delete pPt2;
res << new TPGeCircle2D(*this);
}
return true;
}
default:
return obj.Intersect(*this,res);
}
}
bool TPGeCircle2D::IsInclude(const TGObject& obj) const
{
switch(obj.GetClassID())
{
case CID_GLine2D:
case CID_GLineRay2D:
case CID_GLineSeg2D:
return false;
case CID_GArc2D:
return IsSameCircle(((const TPGeArc2D&)obj).circle);
case CID_GCircle2D:
return IsSameCircle((const TPGeCircle2D&)obj);
default:
return TPGeCurve2D::IsInclude(obj);
}
}
bool TPGeCircle2D::GetExtend2D(TPGeExtend2D&ext) const
{
ext.SetRange(center.x - r,center.x + r, center.y - r, center.y + r);
return true;
}
TPGeCurve2D* TPGeCircle2D::GetSubCurve(double pa0,double pa1) const
{
TPGeArc2D* pArc = new TPGeArc2D(*this);
pArc->SetStartAngle(pa0);
pArc->centralAngle = NA(pa1 - pa0);
if (DOWNEQUAL_ZEROA(pArc->centralAngle))
{
pArc->centralAngle = PI2;
}
return pArc;
}
TGMLine2D* TPGeCircle2D::PLinearize(double paDist) const
{
return new TGPLine2D(*this);
}
void TPGeCircle2D::Split(const TTable<double>& paTable, TGObjectList& res) const
{
if (paTable.IsEmpty())
{
return;
}
if (paTable.GetLength() == 1)
{
res << GetSubCurve(paTable.GetAt(0),paTable.GetAt(0));
}
else
{
for (long i = 1; i < paTable.GetLength(); i++)
{
if (DOWN_ZEROA(paTable.GetAt(i - 1) - paTable.GetAt(i)))
{
res << GetSubCurve(paTable.GetAt(i - 1), paTable.GetAt(i));
}
}
double last = paTable.GetAt(i - 1);
if (DOWN_ZEROA(last - PI2) || UP_ZEROA(paTable.GetAt(0)))
{
res << GetSubCurve(last,paTable.GetAt(0));
}
}
}
TGMLine2D* TPGeCircle2D::MLinearize(double paDist) const
{
if (paDist < 1E-9)
{
paDist = GetMLinePrec();
}
long num = (long)(PI2 / paDist + 0.999999);
if (num < 2)
{
return NULL;
}
paDist = PI2 / num;
TGMLine2D *pMLine = new TGMLine2D(num,true);
double pa = 0;
for (long i = 0; i < num; i++, pa += paDist)
{
Pa2Pt(pa,(*pMLine)[i]);
}
return pMLine;
}
void TPGeCircle2D::Init(const TGPoint& pt0,const TGPoint& pt1,const TGPoint& pt2)
{
TPGeCircle::Init(pt0,pt1,pt2);
if (TGVector2D(pt0,pt1).IsVectorRight(TGVector2D(pt1,pt2)))
{
AddFlag(CLOCKWISE_CURVE);
}
else
{
RemoveFlag(CLOCKWISE_CURVE);
}
}
void TPGeCircle2D::Init(const TGPoint& pt0,const TGPoint& pt1,double angle)
{
TPGeCircle::Init(pt0,pt1,angle);
if (angle < 0)
{
AddFlag(CLOCKWISE_CURVE);
}
else
{
RemoveFlag(CLOCKWISE_CURVE);
}
}
bool TPGeCircle2D::IsSameCircle(const TPGeCircle2D& cir, bool bSameDirection) const
{
if (TPGeCircle::operator == (cir))
{
if (bSameDirection)
{
return (Is(CLOCKWISE_CURVE) && cir.Is(CLOCKWISE_CURVE)) || (IsNot(CLOCKWISE_CURVE) && cir.IsNot(CLOCKWISE_CURVE));
}
return true;
}
return false;
}