1899 lines
35 KiB
C++
1899 lines
35 KiB
C++
//-----------------------------------------------------------------------------+
|
|
// Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd.
|
|
// = FileName : TGGePoly2D 类
|
|
// = Version : ver2.0
|
|
// = Author : wlw
|
|
// = CreateDate : 2002-09-09
|
|
// = Description: TGGePoly2D 类定义
|
|
// = Maintainers:
|
|
//
|
|
//-----------------------------------------------------------------------------+
|
|
#include "StdAfx.h"
|
|
#include "TGGePoly2D.h"
|
|
#include "TADSGePointList.h"
|
|
#include "dbregion.h"
|
|
#include "TPushPrec.h"
|
|
#include "TAcDbObjectPtr.h"
|
|
#include "TGGePoly3D.h"
|
|
//#include "TGGeDirectionCurve.h"
|
|
#include "TList.h"
|
|
#include "TGGePolygonEx.h"
|
|
#include "TPointList.h"
|
|
#include "TchGlobalFunc.h"
|
|
#include "TchPrivateGlobalFunc.h"
|
|
#include "TchGlobalCurveFunc.h"
|
|
#include "geblok3d.h"
|
|
#include "geblok2d.h"
|
|
#include "TGGeCurveInline.h"
|
|
|
|
TGGePoly2D::TGGePoly2D()
|
|
: m_nFlag(0)
|
|
{
|
|
m_ardbulges.Reset();
|
|
}
|
|
|
|
TGGePoly2D::TGGePoly2D(const TEntitySet& ent)
|
|
{
|
|
TEntitySet entPLine = ent;
|
|
TCString sEntType;
|
|
TADSGePoint3d pt;
|
|
double dTAng = 0.0, dAng = 0.0;
|
|
|
|
entPLine.GetData(0, (TCHAR *)sEntType);
|
|
if (sEntType == _T("CIRCLE"))
|
|
{
|
|
TGGeCurveSegment cir(ent);
|
|
cir.AsPoly2D(*this);
|
|
return;
|
|
}
|
|
else if (sEntType == _T("LINE") || sEntType == _T("ARC"))
|
|
{
|
|
TGGeCurveSegment segTemp(ent);
|
|
if (!segTemp)
|
|
{
|
|
return;
|
|
}
|
|
|
|
segTemp.AsPoly2D(*this);
|
|
}
|
|
|
|
if ((sEntType != _T("POLYLINE") && sEntType != _T("LWPOLYLINE"))
|
|
|| entPLine.GetData(70, &m_nFlag) != RTNORM)
|
|
{
|
|
return;
|
|
}
|
|
|
|
int nFlag = m_nFlag;
|
|
|
|
if ((nFlag & 2) || (nFlag & 4) || (nFlag & 16) || (nFlag & 32) || (nFlag & 64))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (sEntType == _T("POLYLINE"))
|
|
{
|
|
OPENOBJ_BEGIN(entPLine, AcDb::kForRead, AcDb3dPolyline, pLine);
|
|
if (pLine != NULL)
|
|
{
|
|
AcDbObjectIterator* pIter = pLine->vertexIterator();
|
|
if (pIter != NULL)
|
|
{
|
|
for (pIter->start(); !pIter->done(); pIter->step())
|
|
{
|
|
AcDb3dPolylineVertex *pVertex = NULL;
|
|
acdbOpenObject(pVertex, pIter->objectId(), AcDb::kForRead);
|
|
|
|
if (pVertex != NULL)
|
|
{
|
|
if (pVertex->vertexType() == AcDb::k3dSimpleVertex)
|
|
{
|
|
m_ardbulges.Append(new double(0.0));
|
|
Append(new TADSGePoint3d(pVertex->position()));
|
|
}
|
|
|
|
pVertex->close();
|
|
}
|
|
}
|
|
|
|
delete pIter;
|
|
}
|
|
|
|
return;
|
|
}
|
|
OPENOBJ_END();
|
|
|
|
TEntitySet subEnt = entPLine;
|
|
while ( 1 )
|
|
{
|
|
TEntitySet sub_ent;
|
|
if (ads_entnext(subEnt, sub_ent) != RTNORM)
|
|
{
|
|
break;
|
|
}
|
|
|
|
subEnt = sub_ent;
|
|
subEnt.FreeGroups();
|
|
|
|
if (!subEnt.Is(_T("VERTEX")))
|
|
{
|
|
break;
|
|
}
|
|
|
|
subEnt.GetData(10, pt);
|
|
subEnt.GetData(42, &dTAng);
|
|
|
|
if (fabs(dTAng) < 1E-6)
|
|
{
|
|
m_ardbulges.Append(new double(0.0));
|
|
}
|
|
else
|
|
{
|
|
dAng = atan(dTAng) * 4.0;
|
|
m_ardbulges.Append(new double(dAng));
|
|
}
|
|
|
|
Append(new TADSGePoint3d(pt));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
double dElevation = 0.0;
|
|
entPLine.GetData(38, &dElevation);
|
|
resbuf *ebuf = (resbuf *)(entPLine.groups);
|
|
if (!ebuf)
|
|
{
|
|
TchGeLib::adsout << _T("\nResbuf error");
|
|
}
|
|
|
|
while(ebuf)
|
|
{
|
|
resbuf *rb1 = GetResbufAtCode(ebuf, 10);
|
|
resbuf *rb2 = rb1 ? GetResbufAtCode(rb1, 42) : NULL;
|
|
|
|
if (rb1 && rb2)
|
|
{
|
|
dTAng = rb2->resval.rreal;
|
|
pt = rb1->resval.rpoint;
|
|
|
|
if (fabs(dTAng) < 1E-6)
|
|
{
|
|
m_ardbulges.Append(new double(0.0));
|
|
}
|
|
else
|
|
{
|
|
dAng = atan(dTAng) * 4.0;
|
|
m_ardbulges.Append(new double(dAng));
|
|
}
|
|
|
|
pt.z = dElevation;
|
|
Append(new TADSGePoint3d(pt));
|
|
ebuf = rb2->rbnext;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
TGGePoly2D::TGGePoly2D(int nflg)
|
|
: m_nFlag(nflg)
|
|
{
|
|
m_ardbulges.Reset();
|
|
}
|
|
|
|
TGGePoly2D::TGGePoly2D(const TGGePoly2D &src)
|
|
{
|
|
TADSGePointList::copyFrom(src);
|
|
m_ardbulges.Reset();
|
|
m_ardbulges.copyFrom( src.m_ardbulges );
|
|
m_nFlag = src.GetFlag();
|
|
}
|
|
|
|
TGGePoly2D::~TGGePoly2D()
|
|
{
|
|
|
|
}
|
|
|
|
void TGGePoly2D::CopyFrom(const TGGeEntity* pSrc)
|
|
{
|
|
if (this != pSrc && pSrc->IsKindOf(TGGeEntity::ePoly2D))
|
|
{
|
|
m_nFlag = ((TGGePoly2D*)pSrc)->m_nFlag;
|
|
copyFrom(*((TGGePoly2D*)pSrc));
|
|
m_ardbulges.copyFrom(((TGGePoly2D*)pSrc)->m_ardbulges);
|
|
}
|
|
}
|
|
|
|
int TGGePoly2D::operator !() const
|
|
{
|
|
return (Length() < 2 ? 1 : 0);
|
|
}
|
|
|
|
TGGePoly2D& TGGePoly2D::operator = (const TGGePoly2D &src)
|
|
{
|
|
if (this != &src)
|
|
{
|
|
Reset();
|
|
m_nFlag = src.m_nFlag;
|
|
for(int i = 0; i < src.Length(); i++)
|
|
{
|
|
const TADSGePoint3d &pt = src[i];
|
|
double val = src.m_ardbulges[i];
|
|
Append(new TADSGePoint3d(pt));
|
|
m_ardbulges.Append(new ads_real(val));
|
|
}
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
int TGGePoly2D::IsValid(int nIndex) const
|
|
{
|
|
int nLen = Length();
|
|
if (nIndex < 0 || nIndex >= nLen)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if (!(m_nFlag & 1) && nIndex == nLen - 1)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
int TGGePoly2D::IsClosed() const
|
|
{
|
|
return ((m_nFlag & 0x01) ? 1 : 0);
|
|
}
|
|
|
|
bool TGGePoly2D::SetClosed()
|
|
{
|
|
if (Length() > 2)
|
|
{
|
|
m_nFlag = 1;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
int TGGePoly2D::TotalSegments() const
|
|
{
|
|
int nLen = Length();
|
|
return (m_nFlag & 1) ? nLen : nLen - 1;
|
|
}
|
|
|
|
double TGGePoly2D::Area() const
|
|
{
|
|
return fabs(PathArea());
|
|
}
|
|
|
|
double TGGePoly2D::GetLength()const
|
|
{
|
|
double dLength = 0.0;
|
|
for (int i = 0; i < TotalSegments(); i++)
|
|
{
|
|
TGGeCurveSegment seg;
|
|
Nth(i, seg);
|
|
dLength += seg.GetLength();
|
|
}
|
|
return dLength;
|
|
}
|
|
|
|
void TGGePoly2D::Reset()
|
|
{
|
|
TDPtrList<TADSGePoint3d>::Reset();
|
|
m_ardbulges.Reset();
|
|
}
|
|
|
|
resbuf* TGGePoly2D::Fence(int nCirDiv)
|
|
{
|
|
TGGePoly pts;
|
|
if (MapToPolygon(pts, nCirDiv) == RTNORM)
|
|
{
|
|
return (IsClosed() ? pts.Fence() : pts.Polygon());
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
resbuf* TGGePoly2D::Polygon(int nCirDiv)
|
|
{
|
|
TGGePoly pts;
|
|
if (MapToPolygon(pts, nCirDiv) == RTNORM)
|
|
{
|
|
return pts.Polygon();
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void TGGePoly2D::AppendNode(const TADSGePoint3d &pt, ads_real dBulge, AcDb::Visibility eVal)
|
|
{
|
|
assert(Length() == m_ardbulges.Length());
|
|
Append(new TADSGePoint3d(pt));
|
|
m_ardbulges.Append(new double(dBulge));
|
|
}
|
|
|
|
void TGGePoly2D::InsertNodeAt(int nIndex, const TADSGePoint3d &pt, double dBulge, AcDb::Visibility eVal)
|
|
{
|
|
if (nIndex >= Length())
|
|
{
|
|
AppendNode(pt, dBulge);
|
|
}
|
|
else
|
|
{
|
|
(*this)[nIndex];
|
|
Insert(new TADSGePoint3d(pt));
|
|
m_ardbulges[nIndex];
|
|
m_ardbulges.Insert(new double(dBulge));
|
|
}
|
|
}
|
|
|
|
void TGGePoly2D::InsertNodeAt(const TADSGePoint3d &pt, AcDb::Visibility eVal)
|
|
{
|
|
|
|
}
|
|
void TGGePoly2D::RemoveNode(long nIndex)
|
|
{
|
|
Remove(nIndex);
|
|
m_ardbulges.Remove(nIndex);
|
|
}
|
|
|
|
void TGGePoly2D::TransformBy(const AcGeMatrix3d &mat)
|
|
{
|
|
//lfy 2010-08-31 修改
|
|
BOOL bIsMirror = IsMirrorMatrix(mat);
|
|
|
|
for (int i = 0; i < Length(); i++)
|
|
{
|
|
TADSGePoint3d *pt = (*this)[i];
|
|
pt->TransformBy(mat);
|
|
|
|
// lfy 2010-08-31 修改,减少循环
|
|
if (bIsMirror)
|
|
{
|
|
*m_ardbulges[i] = -*(m_ardbulges[i]);
|
|
}
|
|
}
|
|
|
|
/*
|
|
if (IsMirrorMatrix(mat))
|
|
{
|
|
for (int m = 0; m < Length(); m++)
|
|
{
|
|
*m_ardbulges[m] = -*(m_ardbulges[m]);
|
|
}
|
|
}*/
|
|
}
|
|
|
|
TADSGePoint3d TGGePoly2D::GetPoint(int nIOFlag, ads_real dDist)
|
|
{
|
|
TADSGePoint3d ptPick;
|
|
TGGeCurveSegment curve;
|
|
if (Nth(0, curve) != RTNORM)
|
|
{
|
|
return ptPick;
|
|
}
|
|
|
|
if (nIOFlag == 0)
|
|
{
|
|
ptPick = curve.Offset(PathArea() > 0 ? OFFSET_RIGHT : OFFSET_LEFT, dDist, LS_FINITE).MidPoint();
|
|
}
|
|
else
|
|
{
|
|
ptPick = curve.Offset(PathArea() > 0 ? OFFSET_LEFT : OFFSET_RIGHT, dDist, LS_FINITE).MidPoint();
|
|
}
|
|
|
|
return ptPick;
|
|
}
|
|
|
|
TADSGePoint3d TGGePoly2D::GetInsidePoint()
|
|
{
|
|
assert(Length());
|
|
|
|
TGGePoly polyTemp;
|
|
MapToPolygon(polyTemp);
|
|
|
|
TGGePolygonEx polyEx(polyTemp);
|
|
TADSGePoint3d pt;
|
|
if (polyEx.GetInsidePoint(pt, TRUE) == RTNORM)
|
|
{
|
|
return pt;
|
|
}
|
|
|
|
return GetPoint(0, 10 * _DIST_SNAP);
|
|
}
|
|
|
|
ads_real TGGePoly2D::Distance2d() const
|
|
{
|
|
int nLen = TotalSegments();
|
|
double dRes = 0.0;
|
|
for (int i = 0; i < nLen; i++)
|
|
{
|
|
dRes += Distance2d(i);
|
|
}
|
|
|
|
return dRes;
|
|
}
|
|
|
|
ads_real TGGePoly2D::Distance2d(int nIndex) const
|
|
{
|
|
int nLen = Length();
|
|
if (nIndex < 0 || nIndex >= nLen)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if (!(m_nFlag & 1) && nIndex == nLen - 1)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
TGGeCurveSegment seg;
|
|
Nth(nIndex, seg);
|
|
seg.SetElevation(0.0);
|
|
|
|
return seg.GetLength();
|
|
}
|
|
|
|
ads_real TGGePoly2D::Distance3d() const
|
|
{
|
|
int nLen = TotalSegments();
|
|
double dRes = 0.0;
|
|
for (int i = 0; i < nLen; i++)
|
|
{
|
|
dRes += Distance3d(i);
|
|
}
|
|
return dRes;
|
|
}
|
|
|
|
ads_real TGGePoly2D::Distance3d(int nIndex) const
|
|
{
|
|
int nLen = Length();
|
|
if (nIndex < 0 || nIndex >= nLen)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if (!(m_nFlag & 1) && nIndex == nLen - 1)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
TGGeCurveSegment seg;
|
|
Nth(nIndex, seg);
|
|
|
|
return seg.GetLength();
|
|
}
|
|
|
|
int TGGePoly2D::HitTestOnCurve(const TADSGePoint3d &ptTest, double dTol) const
|
|
{
|
|
const TGGePoly2D &polyPath = *this;
|
|
TADSGePoint3d pt2d = ptTest;
|
|
|
|
for (int i = 0; i < polyPath.Length(); i++)
|
|
{
|
|
if (pt2d.Distance2d(polyPath[i]) < dTol)
|
|
{
|
|
return (i + 1);
|
|
}
|
|
}
|
|
|
|
TPushPrec vTemp(dTol, _angSnap);
|
|
int nEdgeNum = polyPath.TotalSegments();
|
|
for (i = 0; i < nEdgeNum; i++)
|
|
{
|
|
TGGeCurveSegment seg;
|
|
polyPath.Nth(i, seg);
|
|
seg.SetElevation(0.0);
|
|
|
|
if ((pt2d & seg) == PR_INSIDE)
|
|
{
|
|
return (-i - 1);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
inline int TGGePoly2D::Nth(int nIndex, TGGeCurveSegment &curve, AcDb::Visibility *pVal) const
|
|
{
|
|
if (!IsValid(nIndex))
|
|
{
|
|
return RTERROR;
|
|
}
|
|
|
|
static TGGeLine ln;
|
|
static TGGeArc arc;
|
|
int nflg = Nth(nIndex, ln, arc);
|
|
int nFlag = curve.m_nFlag;
|
|
int nRet = RTNORM;
|
|
|
|
switch(nflg)
|
|
{
|
|
case LINE_SEGMENT:
|
|
//curve = ln;
|
|
curve.m_startPoint = ln.m_startPoint;
|
|
curve.m_endPoint = ln.m_endPoint;
|
|
curve.m_dBulge = 0.0;
|
|
break;
|
|
case ARC_SEGMENT:
|
|
curve = arc;
|
|
break;
|
|
default:
|
|
nRet = RTERROR;
|
|
}
|
|
|
|
curve.m_nFlag = nFlag;
|
|
return nRet;
|
|
}
|
|
|
|
inline int TGGePoly2D::Nth(int nIndex, TGGeLine &xline, TGGeArc &xarc, AcDb::Visibility *pVal) const
|
|
{
|
|
if (!IsValid(nIndex))
|
|
{
|
|
return RTERROR;
|
|
}
|
|
|
|
int nLen = Length();
|
|
TADSGePoint3d p1 = (*this)[nIndex];
|
|
TADSGePoint3d p2;
|
|
if (nIndex == nLen - 1)
|
|
{
|
|
p2 = (*this)[0];
|
|
}
|
|
else
|
|
{
|
|
p2 = (*this)[nIndex + 1];
|
|
}
|
|
|
|
double dAng = m_ardbulges[nIndex];
|
|
if (fabs(dAng) > 1.0E-6)
|
|
{
|
|
xarc.Set(p1,p2,dAng);
|
|
return ARC_SEGMENT;
|
|
}
|
|
else
|
|
{
|
|
//xline.SetPoints(p1, p2);
|
|
xline.m_startPoint = p1;
|
|
xline.m_endPoint = p2;
|
|
return LINE_SEGMENT;
|
|
}
|
|
}
|
|
|
|
inline int TGGePoly2D::Nth(int nIndex, TGGeDirectionCurve &curve, AcDb::Visibility *pVal) const
|
|
{
|
|
if (!IsValid(nIndex))
|
|
{
|
|
return RTERROR;
|
|
}
|
|
|
|
int nLen = Length();
|
|
TADSGePoint3d p1 = (*this)[nIndex], p2;
|
|
if (nIndex == nLen - 1)
|
|
{
|
|
p2 = (*this)[0];
|
|
}
|
|
else
|
|
{
|
|
p2 = (*this)[nIndex + 1];
|
|
}
|
|
|
|
double dAng = m_ardbulges[nIndex];
|
|
curve.m_startPoint = p1;
|
|
curve.m_endPoint = p2;
|
|
curve.m_dBulge = dAng;
|
|
|
|
return RTNORM;
|
|
}
|
|
|
|
int TGGePoly2D::Make(const TCHAR *szlay) const
|
|
{
|
|
int nLen = Length();
|
|
if (nLen <= 1)
|
|
{
|
|
return RTERROR;
|
|
}
|
|
|
|
// LWPLINE
|
|
AcDbPolyline *pLwPoly = new AcDbPolyline(nLen);
|
|
for (int i = 0; i < nLen; i++)
|
|
{
|
|
double dBuge = tan(m_ardbulges[i] / 4.0);
|
|
pLwPoly->addVertexAt(i, (*this)[i].AsAcGePoint2d(), dBuge);
|
|
}
|
|
|
|
if (szlay)
|
|
{
|
|
AssureLayer(szlay, LAYSTAT_UNLOCK);
|
|
pLwPoly->setLayer(szlay);
|
|
}
|
|
|
|
pLwPoly->setClosed(m_nFlag ? Adesk::kTrue : Adesk::kFalse);
|
|
|
|
double dThickness = 0.0;
|
|
TGGetVar(_T("THICKNESS"), &dThickness);
|
|
|
|
pLwPoly->setThickness(dThickness);
|
|
pLwPoly->setElevation((*this)[0].z);
|
|
|
|
AddToModelSpace(pLwPoly, Adesk::kTrue);
|
|
|
|
return RTNORM;
|
|
}
|
|
|
|
int TGGePoly2D::MakeSegments(const TCHAR *szlay) const
|
|
{
|
|
int nLen = Length();
|
|
for (int i = 0; i < nLen; i++)
|
|
{
|
|
MakeSegment(i, szlay);
|
|
}
|
|
|
|
return RTNORM;
|
|
}
|
|
|
|
int TGGePoly2D::MakeSegment(int nIndex, const TCHAR *szlay) const
|
|
{
|
|
TGGeLine line;
|
|
TGGeArc arc;
|
|
int nrc = Nth(nIndex, line, arc);
|
|
if (nrc == LINE_SEGMENT)
|
|
{
|
|
line.Make(szlay);
|
|
}
|
|
else if (nrc == ARC_SEGMENT)
|
|
{
|
|
arc.Make(szlay);
|
|
}
|
|
|
|
return RTNORM;
|
|
}
|
|
|
|
// dDrt--ptRes所在的切向
|
|
// 按2d距离求点和方向,注意返回的点是3d
|
|
int TGGePoly2D::Polar2d(ads_real dis, TADSGePoint3d &ptRes, ads_real *dDrt) const
|
|
{
|
|
//lfy 2010-08-31 修改存取方式
|
|
int nLen = TotalSegments(), iNext = 0;
|
|
double dSum = 0.0, dAng = 0.0, dsita = 0.0;
|
|
TADSGePoint3d p1, p2, pt1, pt2;
|
|
|
|
for (int i = 0; i < nLen; i++)
|
|
{
|
|
dSum += Distance2d(i);
|
|
if (dSum > dis - _DIST_SNAP)
|
|
{
|
|
p1 = (*this)[i];
|
|
iNext = i + 1;
|
|
if (iNext >= Length())
|
|
{
|
|
iNext = 0;
|
|
}
|
|
|
|
p2 = (*this)[iNext];
|
|
dAng = m_ardbulges[i];
|
|
|
|
if (fabs(dAng) > 1E-6)
|
|
{
|
|
TGGeArc xarc(p1, p2, dAng);
|
|
dsita = (dSum - dis) / xarc.m_dRadius;
|
|
if (dAng > 0)
|
|
{
|
|
ads_polar(xarc.m_ptCenter, xarc.m_dendAngle - dsita, xarc.m_dRadius, ptRes);
|
|
if (dDrt)
|
|
{
|
|
*dDrt = AngleRangeTo2PI(xarc.m_dendAngle - dsita + PI / 2.0);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ads_polar(xarc.m_ptCenter, xarc.m_dstartAngle + dsita, xarc.m_dRadius, ptRes);
|
|
if (dDrt)
|
|
{
|
|
*dDrt = AngleRangeTo2PI(xarc.m_dstartAngle + dsita - PI / 2.0);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ads_polar(p2, ads_angle(p2, p1), dSum - dis, ptRes);
|
|
pt1 = p1;
|
|
pt2 = p2;
|
|
pt2.z = pt1.z;
|
|
ptRes.z += (p1.z - p2.z) / ads_distance(pt2, pt1) * (dSum - dis);
|
|
|
|
if (dDrt)
|
|
{
|
|
*dDrt = ads_angle(pt1, pt2);
|
|
}
|
|
}
|
|
|
|
return i;
|
|
}
|
|
}
|
|
|
|
return RTERROR;
|
|
}
|
|
|
|
int TGGePoly2D::Polar3d(ads_real dis, TADSGePoint3d &ptRes, TVector3D &vt) const
|
|
{
|
|
//lfy 2010-08-31 修改存取方式
|
|
int nLen = TotalSegments(), iNext = 0;
|
|
double dSum = 0.0, dAng = 0.0, dsita = 0.0;
|
|
TADSGePoint3d p1, p2, pt1, pt2;
|
|
double dDrt = 0.0;
|
|
|
|
for (int i = 0; i < nLen; i++)
|
|
{
|
|
dSum += Distance3d(i);
|
|
if (dSum > dis - _DIST_SNAP)
|
|
{
|
|
p1 = (*this)[i];
|
|
iNext = i + 1;
|
|
if (iNext >= Length())
|
|
{
|
|
iNext = 0;
|
|
}
|
|
|
|
p2 = (*this)[iNext];
|
|
dAng = m_ardbulges[i];
|
|
if (fabs(dAng) > 1E-6)
|
|
{
|
|
TGGeArc xarc(p1, p2, dAng);
|
|
dsita = (dSum - dis) / xarc.m_dRadius;
|
|
if (dAng > 0)
|
|
{
|
|
ads_polar(xarc.m_ptCenter, xarc.m_dendAngle - dsita, xarc.m_dRadius, ptRes);
|
|
dDrt = AngleRangeTo2PI(xarc.m_dendAngle - dsita + PI / 2.0);
|
|
}
|
|
else
|
|
{
|
|
ads_polar(xarc.m_ptCenter, xarc.m_dstartAngle + dsita, xarc.m_dRadius, ptRes);
|
|
dDrt = AngleRangeTo2PI(xarc.m_dstartAngle + dsita - PI / 2.0);
|
|
}
|
|
|
|
vt.x = cos(dDrt);
|
|
vt.y = sin(dDrt);
|
|
vt.z = 0;
|
|
}
|
|
else
|
|
{
|
|
vt = p2 - p1;
|
|
TVector3D vtNormal = vt;
|
|
((AcGeVector3d &)vtNormal).normalize();
|
|
vt = vtNormal;
|
|
vtNormal *= dis - dSum;
|
|
ptRes = p2 + vtNormal;
|
|
}
|
|
|
|
return i;
|
|
}
|
|
}
|
|
|
|
return RTERROR;
|
|
}
|
|
|
|
ads_real TGGePoly2D::PathArea() const
|
|
{
|
|
int i = 0;
|
|
int nflg;
|
|
TGGeArc arc;
|
|
TGGeLine line;
|
|
double dresult = 0.0;
|
|
|
|
while ((nflg = Nth(i, line, arc)) != RTERROR)
|
|
{
|
|
if (nflg == LINE_SEGMENT)
|
|
{
|
|
dresult += line.PathArea();
|
|
}
|
|
else if (m_ardbulges[i] > 0)
|
|
{
|
|
dresult += arc.PathArea();
|
|
}
|
|
else
|
|
{
|
|
dresult -= arc.PathArea();
|
|
}
|
|
i++;
|
|
}
|
|
|
|
return dresult;
|
|
}
|
|
|
|
int TGGePoly2D::MapToPolygon(TGGePoly &pts, int nCirDiv)
|
|
{
|
|
//lfy 2010-08-31 修改存取方式
|
|
pts.Reset();
|
|
int nLen = Length();
|
|
int i = 0, n = 0, nNum = 0, nRetFlag = 0;
|
|
TADSGePoint3d pt;
|
|
double dincrement = 0.0;
|
|
|
|
for (i = 0; i < nLen; i++)
|
|
{
|
|
if (fabs(*m_ardbulges[i]) < 1E-6)
|
|
{
|
|
pts.Append(new TADSGePoint3d(*(*this)[i]));
|
|
}
|
|
else if (i < nLen - 1 || IsClosed())
|
|
{
|
|
TGGeArc arc;
|
|
TGGeLine ll;
|
|
nRetFlag = Nth(i, ll, arc);
|
|
ASSERT(nRetFlag == ARC_SEGMENT);
|
|
|
|
//圆用30边做成
|
|
nNum = (int)(arc.Bulge() / (2.0 * PI) * nCirDiv);
|
|
nNum = max(nNum, 1);
|
|
|
|
dincrement = arc.Bulge() / nNum;
|
|
for (n = 0; n < nNum; n++)
|
|
{
|
|
if (*m_ardbulges[i] > 0)
|
|
{
|
|
ads_polar(arc.m_ptCenter, arc.m_dstartAngle + dincrement * n, arc.m_dRadius, pt);
|
|
}
|
|
else
|
|
{
|
|
ads_polar(arc.m_ptCenter, arc.m_dendAngle - dincrement * n, arc.m_dRadius, pt);
|
|
}
|
|
pts.Append(new TADSGePoint3d(pt));
|
|
}
|
|
}
|
|
}
|
|
|
|
return RTNORM;
|
|
}
|
|
|
|
void TGGePoly2D::Disperse(TGGePoly2D &polyBase1, int nCirDivSeg) const
|
|
{
|
|
TGGePoly polyBase;
|
|
AsOpenPoly(polyBase, nCirDivSeg);
|
|
|
|
int nCount = polyBase.Length();
|
|
if (IsClosed())
|
|
{
|
|
nCount--;
|
|
}
|
|
|
|
for (int n = 0; n < nCount; n++)
|
|
{
|
|
polyBase1.AppendNode(*polyBase[n]);
|
|
}
|
|
|
|
polyBase1.SetFlag(m_nFlag);
|
|
}
|
|
|
|
int TGGePoly2D::AsOpenPoly(TGGePoly &pts, int nCirDiv) const
|
|
{
|
|
//lfy 2010-08-31 修改存取方式
|
|
pts.Reset();
|
|
int nLen = Length();
|
|
const TGGePoly2D &poly = *this;
|
|
int i = 0, n = 0, nNum = 0, nRetFlag = 0;
|
|
TADSGePoint3d pt;
|
|
double dincrement = 0.0;
|
|
TGGeArc arc;
|
|
TGGeLine ll;
|
|
for ( i = 0; i < nLen; i++)
|
|
{
|
|
if (fabs(m_ardbulges[i]) < 1E-6)
|
|
{
|
|
pts.Append(new TADSGePoint3d(poly[i]));
|
|
if (i == nLen - 1 && IsClosed())
|
|
{
|
|
//最后一点为起点
|
|
pts.Append(new TADSGePoint3d(poly[0]));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//Arc
|
|
if (!IsClosed() && i == nLen - 1)
|
|
{
|
|
//不封闭的最后一点
|
|
pts.Append(new TADSGePoint3d(poly[i]));
|
|
return RTNORM;
|
|
}
|
|
|
|
nRetFlag = Nth(i, ll, arc);
|
|
ASSERT(nRetFlag == ARC_SEGMENT);
|
|
|
|
nNum = (int)(arc.Bulge() / (2.0 * PI) * nCirDiv);
|
|
nNum = max(nNum, 1);
|
|
dincrement = arc.Bulge() / nNum;
|
|
|
|
if (i == nLen-1 && IsClosed())
|
|
{
|
|
//最后一封闭弧段
|
|
nNum += 1;
|
|
}
|
|
|
|
for (n = 0; n < nNum; n++)
|
|
{
|
|
if (m_ardbulges[i] > 0)
|
|
{
|
|
ads_polar(arc.m_ptCenter, arc.m_dstartAngle + dincrement * n, arc.m_dRadius, pt);
|
|
}
|
|
else
|
|
{
|
|
ads_polar(arc.m_ptCenter, arc.m_dendAngle - dincrement * n, arc.m_dRadius, pt);
|
|
}
|
|
pts.Append(new TADSGePoint3d(pt));
|
|
}
|
|
}
|
|
}
|
|
|
|
return RTNORM;
|
|
}
|
|
|
|
int TGGePoly2D::MapToPolygon1(TGGePoly &pts, double dDeviation)
|
|
{
|
|
//lfy 2010-08-31 修改存取方式
|
|
pts.Reset();
|
|
int nLen = Length();
|
|
int i = 0, n = 0, nNum = 0, nRetFlag = 0, nCirDiv = 0;
|
|
TADSGePoint3d pt;
|
|
double dincrement = 0.0;
|
|
TGGeArc arc;
|
|
TADSGePoint3d* pPtScr = NULL;
|
|
TGGeLine ll;
|
|
for (i = 0; i < nLen; i++)
|
|
{
|
|
if (fabs(*m_ardbulges[i]) < 1E-6)
|
|
{
|
|
pPtScr = new TADSGePoint3d(*(*this)[i]);
|
|
pts.Append(pPtScr);
|
|
}
|
|
else if (i < nLen - 1 || IsClosed())
|
|
{
|
|
//不到最后一点或闭合的最后一段
|
|
nRetFlag = Nth(i, ll, arc);
|
|
ASSERT(nRetFlag == ARC_SEGMENT);
|
|
if (arc.GetLength() < _DIST_SNAP)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
nCirDiv = GetCirDivNum(arc.m_dRadius, dDeviation);
|
|
nNum = (int)(arc.Bulge() / (2.0 * PI) * nCirDiv);
|
|
nNum = max(nNum, 1);
|
|
dincrement = arc.Bulge() / nNum;
|
|
|
|
for (n = 0; n < nNum; n++)
|
|
{
|
|
if (*m_ardbulges[i] > 0)
|
|
{
|
|
ads_polar(arc.m_ptCenter, arc.m_dstartAngle + dincrement * n, arc.m_dRadius, pt);
|
|
}
|
|
else
|
|
{
|
|
ads_polar(arc.m_ptCenter, arc.m_dendAngle - dincrement * n, arc.m_dRadius, pt);
|
|
}
|
|
pts.Append(new TADSGePoint3d(pt));
|
|
}
|
|
}
|
|
}
|
|
|
|
return RTNORM;
|
|
}
|
|
|
|
void TGGePoly2D::Disperse1(TGGePoly2D &polyBase1, double dDeviation) const
|
|
{
|
|
TGGePoly polyBase;
|
|
AsOpenPoly1(polyBase, dDeviation);
|
|
|
|
int nCount = polyBase.Length();
|
|
if (IsClosed())
|
|
{
|
|
nCount--;
|
|
}
|
|
|
|
for (int n = 0; n<nCount; n++)
|
|
{
|
|
polyBase1.AppendNode(*polyBase[n]);
|
|
}
|
|
|
|
polyBase1.SetFlag(m_nFlag);
|
|
}
|
|
|
|
int TGGePoly2D::AsOpenPoly1(TGGePoly &pts, double dDeviation) const
|
|
{
|
|
pts.Reset();
|
|
int nLen = Length();
|
|
|
|
int i = 0, n = 0, nNum = 0, nRetFlag = 0, nCirDiv = 0;
|
|
TADSGePoint3d pt;
|
|
double dincrement = 0.0;
|
|
TGGeArc arc;
|
|
TGGeLine ll;
|
|
TADSGePoint3d* pPtScr = NULL;
|
|
TADSGePoint3d* pPtScr0 = NULL;
|
|
|
|
for (i = 0; i < nLen; i++)
|
|
{
|
|
if (fabs(m_ardbulges[i]) < 1E-6)
|
|
{
|
|
pPtScr = new TADSGePoint3d((*this)[i]);
|
|
pts.Append(pPtScr);
|
|
if (i == nLen - 1 && IsClosed())
|
|
{
|
|
pPtScr0 = new TADSGePoint3d((*this)[0]);
|
|
pts.Append(pPtScr0);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!IsClosed() && i == nLen - 1)
|
|
{
|
|
pPtScr = new TADSGePoint3d((*this)[i]);
|
|
pts.Append(pPtScr);
|
|
return RTNORM;
|
|
}
|
|
|
|
nRetFlag = Nth(i, ll, arc);
|
|
ASSERT(nRetFlag == ARC_SEGMENT);
|
|
|
|
nCirDiv = GetCirDivNum(arc.m_dRadius, dDeviation);
|
|
nNum = (int)(arc.Bulge() / (2.0 * PI) * nCirDiv);
|
|
nNum = max(nNum, 1);
|
|
dincrement = arc.Bulge() / nNum;
|
|
|
|
if (i == nLen - 1 && IsClosed())
|
|
{
|
|
nNum += 1;
|
|
}
|
|
|
|
for (n = 0; n < nNum; n++)
|
|
{
|
|
if (m_ardbulges[i] > 0)
|
|
{
|
|
ads_polar(arc.m_ptCenter, arc.m_dstartAngle + dincrement * n, arc.m_dRadius, pt);
|
|
}
|
|
else
|
|
{
|
|
ads_polar(arc.m_ptCenter, arc.m_dendAngle - dincrement * n, arc.m_dRadius, pt);
|
|
}
|
|
pts.Append(new TADSGePoint3d(pt));
|
|
}
|
|
}
|
|
}
|
|
return RTNORM;
|
|
}
|
|
|
|
double TGGePoly2D::PathDistance2d(TADSGePoint3d ptHit) const
|
|
{
|
|
double nRet = 0.0;
|
|
int nHitLeft = HitTestOnCurve(ptHit);
|
|
if (nHitLeft < 0)
|
|
{
|
|
int iLeft = abs(nHitLeft) - 1;
|
|
TGGeDirectionCurve leftHitCurve;
|
|
|
|
Nth(iLeft, leftHitCurve);
|
|
nRet = leftHitCurve.PathDistance(ptHit);
|
|
|
|
for (int k = 0; k < iLeft; k++)
|
|
{
|
|
Nth(k, leftHitCurve);
|
|
nRet += leftHitCurve.GetLength();
|
|
}
|
|
}
|
|
|
|
// add by xlc on 110415 ptHit在顶点时计算路径长度
|
|
else if (nHitLeft > 0)
|
|
{
|
|
for (int k = 0; k < nHitLeft - 1; k++)
|
|
{
|
|
TGGeDirectionCurve leftHitCurve;
|
|
Nth(k, leftHitCurve);
|
|
nRet += leftHitCurve.GetLength();
|
|
}
|
|
}
|
|
|
|
return nRet;
|
|
}
|
|
|
|
int TGGePoly2D::CreatePface(int nCirDiv, const TCHAR *pszLay)
|
|
{
|
|
TGGePoly pts;
|
|
MapToPolygon(pts, nCirDiv);
|
|
return pts.CreatePface(pszLay);
|
|
}
|
|
|
|
int TGGePoly2D::GetExtend(ads_point lowPt, ads_point upPt) const
|
|
{
|
|
int nNum = TotalSegments();
|
|
if (!nNum)
|
|
{
|
|
return RTERROR;
|
|
}
|
|
|
|
TGGeCurveSegment seg;
|
|
TADSGePoint3d ptlow, ptup;
|
|
ptlow = ptup = ((*this)[0]);
|
|
|
|
for (int n = 0; n < nNum; n++)
|
|
{
|
|
if (Nth(n, seg) != RTNORM)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
TADSGePoint3d pt1, pt2;
|
|
seg.GetExtend(pt1, pt2);
|
|
ptlow = Min(ptlow, pt1);
|
|
ptup = Max(ptup, pt2);
|
|
}
|
|
|
|
ptlow > lowPt;
|
|
ptup > upPt;
|
|
|
|
return RTNORM;
|
|
}
|
|
|
|
// 没有判断边重合的情况
|
|
BOOL TGGePoly2D::IsSelfIntersect() const
|
|
{
|
|
const TGGePoly2D &polyOutline = *this;
|
|
|
|
int nLen = polyOutline.Length();
|
|
TGGeArc arc;
|
|
for (int i = 0; i < nLen - 2; i++)
|
|
{
|
|
TGGeLine ln0(LS_FINITE);
|
|
polyOutline.Nth(i, ln0, arc);
|
|
|
|
if (ln0.GetLength() < _DIST_SNAP)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
for (int j = i + 2; j < ((i == 0 && m_nFlag == 1) ? (nLen - 1) : nLen); j++)
|
|
{
|
|
TGGeLine ln1(LS_FINITE);
|
|
polyOutline.Nth(j, ln1, arc);
|
|
if (ln1.GetLength() < _DIST_SNAP)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
TADSGePoint3d ptInt;
|
|
if (ln0.Intersection(&ln1, ptInt))
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
int TGGePoly2D::AppendSegment(const TGGeCurveSegment &curve, int bMinus, int bFinal)
|
|
{
|
|
if (bMinus)
|
|
{
|
|
Append(new TADSGePoint3d(curve.GetEndPoint()));
|
|
m_ardbulges.Append(new double(-curve.GetBulge()));
|
|
if (bFinal && !(m_nFlag & 0x01))
|
|
{
|
|
Append(new TADSGePoint3d(curve.GetStartPoint()));
|
|
m_ardbulges.Append(new double(0.0));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Append(new TADSGePoint3d(curve.GetStartPoint()));
|
|
m_ardbulges.Append(new double(curve.GetBulge()));
|
|
if (bFinal && !(m_nFlag & 0x01))
|
|
{
|
|
Append(new TADSGePoint3d(curve.GetEndPoint()));
|
|
m_ardbulges.Append(new double(0.0));
|
|
}
|
|
}
|
|
|
|
return RTNORM;
|
|
}
|
|
|
|
int TGGePoly2D::Compress(bool bUnionCurve)
|
|
{
|
|
if (Length() < 1)
|
|
{
|
|
return RTERROR;
|
|
}
|
|
|
|
const TGGePoly2D &poly = *this;
|
|
TList<TADSGePoint3d> ptList;
|
|
TList<double> anList;
|
|
ptList.AddTail(poly[0]);
|
|
|
|
for (long i = 1; i < Length(); i++)
|
|
{
|
|
if (ptList.GetCurData() != poly[i])
|
|
{
|
|
ptList.AddTail(poly[i]);
|
|
anList.AddTail(*(m_ardbulges[i - 1]));
|
|
}
|
|
}
|
|
anList.AddTail(*(m_ardbulges[i - 1]));
|
|
|
|
if (IsClosed())
|
|
{
|
|
if (ptList.GetLength() > 1 && poly[0] == ptList.GetCurData())
|
|
{
|
|
ptList.DelCur();
|
|
anList.DelCur();
|
|
}
|
|
}
|
|
|
|
if (ptList.GetLength() < Length())
|
|
{
|
|
Reset();
|
|
m_ardbulges.Reset();
|
|
for (ptList.MoveToFirst(), anList.MoveToFirst(); !ptList.IsOut(); ptList.MoveToNext(), anList.MoveToNext())
|
|
{
|
|
AppendNode(ptList.GetCurData(), anList.GetCurData());
|
|
}
|
|
}
|
|
|
|
if (!bUnionCurve)
|
|
{
|
|
return RTNORM;
|
|
}
|
|
|
|
TGGePoly2D destPoly(m_nFlag);
|
|
int nTotalSeg = TotalSegments();
|
|
TGGeCurveSegment curve;
|
|
int bMinusCurve = 0, bMinusSeg = 0, bMerged = 0;
|
|
|
|
for (int n = 0; n < nTotalSeg; n++)
|
|
{
|
|
TGGeCurveSegment seg;
|
|
Nth(n, seg);
|
|
if (!seg)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
bMinusSeg = (*m_ardbulges[n] < -1.0E-8);
|
|
bMerged = 0;
|
|
if (!curve)
|
|
{
|
|
curve = seg;
|
|
bMinusCurve = bMinusSeg;
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
bMerged = MergeCurve(curve, seg, bMinusCurve, bMinusSeg);
|
|
}
|
|
|
|
if (!bMerged)
|
|
{
|
|
destPoly.AppendSegment(curve, bMinusCurve);
|
|
curve = seg;
|
|
bMinusCurve = bMinusSeg;
|
|
}
|
|
}
|
|
|
|
if (!curve)
|
|
{
|
|
return RTERROR;
|
|
}
|
|
else
|
|
{
|
|
destPoly.AppendSegment(curve, bMinusCurve, 1);
|
|
}
|
|
|
|
if ((destPoly.GetFlag() & 0x01) && destPoly.TotalSegments() >= 2)
|
|
{
|
|
int nTotalDest = destPoly.TotalSegments();
|
|
int bMinusFirst = (destPoly.GetBulge(0) < -1.0E-8);
|
|
int bMinusFinal = (destPoly.GetBulge(nTotalDest - 1) < -1.0E-8);
|
|
TGGeCurveSegment curveFirst, curveFinal;
|
|
destPoly.Nth(0, curveFirst);
|
|
destPoly.Nth(nTotalDest - 1, curveFinal);
|
|
|
|
if (MergeCurve(curveFinal, curveFirst, bMinusFinal, bMinusFirst))
|
|
{
|
|
if (bMinusFinal)
|
|
{
|
|
destPoly.SetBulge(0,-curveFinal.GetBulge());
|
|
destPoly.SetPointListAt(0, curveFinal.EndPoint());
|
|
}
|
|
else
|
|
{
|
|
destPoly.SetBulge(0, curveFinal.GetBulge());
|
|
destPoly.SetPointListAt(0, curveFinal.StartPoint());
|
|
}
|
|
destPoly.RemoveBugle(nTotalDest - 1);
|
|
destPoly.RemovePointListAt(nTotalDest - 1);
|
|
}
|
|
}
|
|
|
|
*this = destPoly;
|
|
return RTNORM;
|
|
}
|
|
|
|
int TGGePoly2D::Reverse()
|
|
{
|
|
if (Length() < 2)
|
|
{
|
|
return RTERROR;
|
|
}
|
|
|
|
TGGePoly2D destPoly;
|
|
int nTotalSeg = TotalSegments();
|
|
TGGeDirectionCurve cv;
|
|
|
|
for (int i = nTotalSeg - 1; i >= 0; i--)
|
|
{
|
|
Nth(i, cv);
|
|
destPoly.AppendNode(cv.EndPoint(), -cv.GetBulge());
|
|
}
|
|
|
|
if (!(m_nFlag & 0x01))
|
|
{
|
|
destPoly.AppendNode(*((*this)[0]), -(*m_ardbulges[nTotalSeg]));
|
|
}
|
|
|
|
destPoly.SetFlag(m_nFlag);
|
|
*this = destPoly;
|
|
return RTNORM;
|
|
}
|
|
|
|
int TGGePoly2D::Offset(ads_real dDist, TGGePoly2D &destPoly) const
|
|
{
|
|
int nTotalSeg = TotalSegments();
|
|
if (!nTotalSeg)
|
|
{
|
|
return RTERROR;
|
|
}
|
|
|
|
if (fabs(dDist) < _DIST_SNAP)
|
|
{
|
|
destPoly = *this;
|
|
return RTNORM;
|
|
}
|
|
|
|
destPoly.Reset();
|
|
destPoly.SetFlag(m_nFlag);
|
|
|
|
TGGeDirectionCurve finalMidSeg, lastSeg;
|
|
if (m_nFlag & 0x01)
|
|
{
|
|
Nth(nTotalSeg - 1, finalMidSeg);
|
|
lastSeg = finalMidSeg.Offset(dDist, LS_INFINITE);
|
|
|
|
if (!lastSeg)
|
|
{
|
|
return RTERROR;
|
|
}
|
|
}
|
|
|
|
TADSGePoint3d nextPt,pt1, pt2, curPt;
|
|
TGGeDirectionCurve curMidSeg, curSeg, nextMidSeg, nextSeg;
|
|
int nNum = 0, nextIndex = 0;
|
|
TGGeArc arc;
|
|
|
|
for (int i = 0; i < nTotalSeg; i++)
|
|
{
|
|
Nth(i, curMidSeg);
|
|
curSeg = curMidSeg.Offset(dDist, LS_INFINITE);
|
|
|
|
if (!curSeg)
|
|
{
|
|
return RTERROR;
|
|
}
|
|
|
|
if (!i)
|
|
{
|
|
// 求当前点
|
|
if (!lastSeg)
|
|
{
|
|
curPt = curSeg.GetStartPoint();
|
|
}
|
|
else
|
|
{
|
|
nNum = curSeg.Intersection(lastSeg, pt1, pt2);
|
|
if (nNum == 2)
|
|
{
|
|
curPt = TGGeLine(pt1, pt2).NearPoint(curSeg.GetStartPoint());
|
|
}
|
|
else if (nNum == 1)
|
|
{
|
|
curPt = pt1;
|
|
}
|
|
else
|
|
{
|
|
if (IsSameDrt(curSeg.IDirection(0), lastSeg.IDirection(1), _angSnap))
|
|
{
|
|
//同方向, 两段连接.
|
|
curPt = curSeg.GetStartPoint();
|
|
}
|
|
else
|
|
{
|
|
return RTERROR;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
curPt = nextPt;
|
|
}
|
|
|
|
// 求下一个端点
|
|
if (i == nTotalSeg - 1 && !(m_nFlag & 0x01))
|
|
{
|
|
//不封闭的最后一段
|
|
nextPt = curSeg.GetEndPoint();
|
|
}
|
|
else
|
|
{
|
|
//为最后时下一段为起始
|
|
nextIndex = i >= nTotalSeg - 1 ? 0 : i + 1;
|
|
Nth(nextIndex, nextMidSeg);
|
|
nextSeg = nextMidSeg.Offset(dDist, LS_INFINITE);
|
|
if (!nextSeg)
|
|
{
|
|
return RTERROR;
|
|
}
|
|
|
|
nNum = curSeg.Intersection(nextSeg, pt1, pt2);
|
|
if (nNum == 2)
|
|
{
|
|
nextPt = TGGeLine(pt1, pt2).NearPoint(curSeg.GetEndPoint());
|
|
}
|
|
else if (nNum == 1)
|
|
{
|
|
nextPt = pt1;
|
|
}
|
|
else
|
|
{
|
|
if (IsSameDrt(curSeg.IDirection(1), nextSeg.IDirection(0), _angSnap))
|
|
{
|
|
nextPt = curSeg.GetEndPoint();
|
|
}
|
|
else
|
|
{
|
|
return RTERROR;
|
|
}
|
|
}
|
|
}
|
|
|
|
lastSeg = curSeg;
|
|
if (curSeg.Is(CURVE_ARC))
|
|
{
|
|
arc = curSeg.GetArc();
|
|
if (!curSeg.IsMinusArc())
|
|
{
|
|
//逆时针
|
|
arc.SetStarAngle(ads_angle(arc.GetCenterPt(), curPt));
|
|
arc.SetEndAngle(ads_angle(arc.GetCenterPt(), nextPt));
|
|
curSeg.SetBulge(arc.Bulge());
|
|
}
|
|
else
|
|
{
|
|
arc.SetStarAngle(ads_angle(arc.GetCenterPt(), nextPt));
|
|
arc.SetEndAngle(ads_angle(arc.GetCenterPt(), curPt));
|
|
curSeg.SetBulge(-arc.Bulge());
|
|
}
|
|
curSeg.SetStartPoint(curPt);
|
|
curSeg.SetEndPoint(nextPt);
|
|
}
|
|
|
|
assert(!curSeg.Is(CURVE_CIRCLE));
|
|
//加一段
|
|
destPoly.Append(new TADSGePoint3d(curPt));
|
|
destPoly.m_ardbulges.Append(new double(curSeg.GetBulge()));
|
|
if (i == nTotalSeg - 1 && !(m_nFlag & 0x01))
|
|
{
|
|
destPoly.Append(new TADSGePoint3d(nextPt));
|
|
destPoly.m_ardbulges.Append(new double(0.0));
|
|
}
|
|
}
|
|
|
|
return RTNORM;
|
|
}
|
|
|
|
int TGGePoly2D::HasArcSegment() const
|
|
{
|
|
for (int i = 0; i < TotalSegments(); i++)
|
|
{
|
|
if (fabs(m_ardbulges[i]) > 1.0E-6)
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int TGGePoly2D::QuickOffset(ads_real dDist, TGGePoly2D &destPoly) const
|
|
{
|
|
const TGGePoly2D &basePoly = *this;
|
|
destPoly.Reset();
|
|
destPoly.m_nFlag = m_nFlag;
|
|
|
|
int nVertexNum = basePoly.Length();
|
|
TGGeDirectionCurve prevEdge;
|
|
|
|
int bIsClosed = ((basePoly.m_nFlag & 0x01) != 0);
|
|
if (bIsClosed)
|
|
{
|
|
basePoly.Nth(nVertexNum - 1, prevEdge);
|
|
}
|
|
|
|
TADSGePoint3d newVertex;
|
|
for (int j = 0; j < nVertexNum; j++)
|
|
{
|
|
TGGeDirectionCurve curEdge;
|
|
double dFromDirection, dToDirection;
|
|
if (j == nVertexNum - 1)
|
|
{
|
|
dToDirection = AngleRangeTo2PI(prevEdge.IDirection(1) - PI);
|
|
dFromDirection = prevEdge.IDirection(1);
|
|
|
|
if (bIsClosed)
|
|
{
|
|
basePoly.Nth(nVertexNum - 1, curEdge);
|
|
dFromDirection = AngleRangeTo2PI(curEdge.IDirection(0) - PI);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
basePoly.Nth(j, curEdge);
|
|
dFromDirection = AngleRangeTo2PI(curEdge.IDirection(0) - PI);
|
|
dToDirection = curEdge.IDirection(0);
|
|
if (j > 0 || bIsClosed)
|
|
{
|
|
dToDirection = AngleRangeTo2PI(prevEdge.IDirection(1) - PI);
|
|
}
|
|
}
|
|
|
|
double dDirection = TGGeSector(dFromDirection, dToDirection).MidAngle();
|
|
const TADSGePoint3d &thisVertex = basePoly[j];
|
|
double dSinAng = fabs(sin(AngleRangeTo2PI(dDirection - dFromDirection)));
|
|
|
|
if (fabs(dSinAng) < 1E-6)
|
|
{
|
|
return RTERROR;
|
|
}
|
|
else
|
|
{
|
|
ads_polar(thisVertex, dDirection, dDist / dSinAng, newVertex);
|
|
}
|
|
|
|
destPoly.AppendNode(newVertex, m_ardbulges[j]);
|
|
prevEdge = curEdge;
|
|
}
|
|
|
|
TADSGePoint3d ptMid;
|
|
double dAbsBulge;
|
|
assert(TotalSegments() == destPoly.TotalSegments());
|
|
for (int i = 0; i < TotalSegments(); i++)
|
|
{
|
|
TGGeDirectionCurve cvSrc, cvDest, dv;
|
|
Nth(i, cvSrc);
|
|
destPoly.Nth(i, cvDest);
|
|
|
|
if (fabs(cvSrc.GetBulge()) > 1.0E-5)
|
|
{
|
|
TGGeDirectionCurve dv = cvSrc.Offset(dDist, LS_FINITE);
|
|
if (!dv)
|
|
{
|
|
return RTERROR;
|
|
}
|
|
|
|
dv.GetArc().MidPoint(ptMid);
|
|
|
|
TGGeArc ar(cvDest.GetStartPoint(), ptMid, cvDest.GetEndPoint());
|
|
|
|
dAbsBulge = ar.Bulge();
|
|
if (dAbsBulge < 1.0E-5)
|
|
{
|
|
return RTERROR;
|
|
}
|
|
*destPoly.m_ardbulges[i] = (cvSrc.GetBulge() > 0) ? dAbsBulge : -dAbsBulge;
|
|
}
|
|
}
|
|
|
|
return RTNORM;
|
|
}
|
|
|
|
AcDbRegion* TGGePoly2D::AsRegion() const
|
|
{
|
|
const TGGePoly2D &poly = *this;
|
|
if (!poly.IsClosed())
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
AcDbPolyline pline;
|
|
PolyConvert(poly, pline);
|
|
|
|
AcDbVoidPtrArray curveSegments;
|
|
curveSegments.append(&pline);
|
|
|
|
AcDbVoidPtrArray regions;
|
|
if (AcDbRegion::createFromCurves(curveSegments, regions) == Acad::eOk && regions.length() > 0)
|
|
{
|
|
AcDbRegion *regioni = (AcDbRegion *)regions[0];
|
|
regions.removeAt(0);
|
|
ReleaseEntSet(regions);
|
|
return regioni;
|
|
}
|
|
|
|
//如果整个pline创建region,不成功的时候,再炸开
|
|
AcDbVoidPtrArray explodeSegments;
|
|
pline.explode(explodeSegments);
|
|
|
|
AcDbVoidPtrArray regions2;
|
|
if (AcDbRegion::createFromCurves(curveSegments, regions2) == Acad::eOk && regions2.length() > 0)
|
|
{
|
|
AcDbRegion *regioni = (AcDbRegion *)regions2[0];
|
|
regions2.removeAt(0);
|
|
ReleaseEntSet(regions2);
|
|
return regioni;
|
|
}
|
|
|
|
ReleaseEntSet(explodeSegments);
|
|
return NULL;
|
|
}
|
|
|
|
bool TGGePoly2D::IsRegionInclude(const TGGePoly2D& poly) const
|
|
{
|
|
TGGePoly2D poly1, poly2;
|
|
poly1 = *this;
|
|
poly2 = poly;
|
|
|
|
poly1.SetElevation(0.0);
|
|
poly2.SetElevation(0.0);
|
|
|
|
AcDbRegion *pRegion1 = poly1.AsRegion();
|
|
AcDbRegion *pRegion2 = poly2.AsRegion();
|
|
double area0;
|
|
double area1;
|
|
|
|
if (pRegion1 != NULL && pRegion2 != NULL)
|
|
{
|
|
pRegion1->getArea(area0);
|
|
if (pRegion1->booleanOper(AcDb::kBoolUnite,pRegion2) == Acad::eOk)
|
|
{
|
|
pRegion1->getArea(area1);
|
|
if (fabs(area1 - area0) < 1E-6)
|
|
{
|
|
delete pRegion1;
|
|
delete pRegion2;
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (pRegion1 != NULL)
|
|
{
|
|
delete pRegion1;
|
|
}
|
|
|
|
if (pRegion2 != NULL)
|
|
{
|
|
delete pRegion2;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool TGGePoly2D::IsRegionOverlap(const TGGePoly2D& poly) const
|
|
{
|
|
TGGePoly2D poly1, poly2;
|
|
poly1 = *this;
|
|
poly2 = poly;
|
|
poly1.SetElevation(0.0);
|
|
poly2.SetElevation(0.0);
|
|
|
|
AcDbRegion *pRegion1 = poly1.AsRegion();
|
|
AcDbRegion *pRegion2 = poly2.AsRegion();
|
|
double area;
|
|
|
|
if (pRegion1 != NULL && pRegion2 != NULL)
|
|
{
|
|
if (pRegion1->booleanOper(AcDb::kBoolIntersect, pRegion2) == Acad::eOk)
|
|
{
|
|
pRegion1->getArea(area);
|
|
if (area > 1E-6)
|
|
{
|
|
delete pRegion1;
|
|
delete pRegion2;
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (pRegion1 != NULL)
|
|
{
|
|
delete pRegion1;
|
|
}
|
|
|
|
if (pRegion2 != NULL)
|
|
{
|
|
delete pRegion2;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
AcDbCurve* TGGePoly2D::AsAcDbCurve() const
|
|
{
|
|
AcDbPolyline* pLwPoly = new AcDbPolyline(Length());
|
|
double dBuge = 0.0;
|
|
for (int i = 0; i < Length(); i++)
|
|
{
|
|
dBuge = tan(m_ardbulges[i] / 4.0);
|
|
pLwPoly->addVertexAt(i, ((*this)[i]).AsAcGePoint2d(), dBuge);
|
|
}
|
|
|
|
if (Length() >0)
|
|
{
|
|
pLwPoly->setElevation((*this)[0].z);
|
|
}
|
|
|
|
pLwPoly->setClosed(IsClosed() ? Adesk::kTrue : Adesk::kFalse);
|
|
|
|
return pLwPoly;
|
|
}
|
|
|
|
bool TGGePoly2D::SetAcDbCurve(AcDbCurve*pCurve)
|
|
{
|
|
AcDbPolyline* pLwPoly = AcDbPolyline::cast(pCurve);
|
|
if (pLwPoly == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
Reset();
|
|
|
|
double dElev = pLwPoly->elevation();
|
|
AcGePoint2d pt;
|
|
double dBulge = 0.0;
|
|
|
|
for (long i = 0; i < (long)pLwPoly->numVerts(); i++)
|
|
{
|
|
pLwPoly->getPointAt(i, pt);
|
|
pLwPoly->getBulgeAt(i, dBulge);
|
|
dBulge = atan(dBulge) * 4;
|
|
AppendNode(TADSGePoint3d(pt.x, pt.y, dElev), dBulge);
|
|
}
|
|
|
|
if (pLwPoly->isClosed())
|
|
{
|
|
m_nFlag = 1;
|
|
}
|
|
else
|
|
{
|
|
m_nFlag = 0;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void TGGePoly2D::SetFlag(int nFlag)
|
|
{
|
|
m_nFlag = nFlag;
|
|
}
|
|
|
|
int TGGePoly2D::GetFlag() const
|
|
{
|
|
return m_nFlag;
|
|
}
|
|
|
|
void TGGePoly2D::RemoveBugle(int nIndex)
|
|
{
|
|
m_ardbulges.Remove(nIndex);
|
|
}
|
|
|
|
void TGGePoly2D::AppendBugle(ads_real dBugle)
|
|
{
|
|
m_ardbulges.Append( new double(dBugle));
|
|
}
|
|
|
|
double TGGePoly2D::GetBulge(int nIndex) const
|
|
{
|
|
return m_ardbulges[nIndex];
|
|
}
|
|
|
|
void TGGePoly2D::SetBulge(int nIndex, double dBugle)
|
|
{
|
|
*m_ardbulges[nIndex] = dBugle;
|
|
}
|
|
|
|
void TGGePoly2D::SetPointListAt(int nIndex, const TADSGePoint3d& pt)
|
|
{
|
|
if (Length() > nIndex)
|
|
{
|
|
*((*this)[nIndex]) = pt;
|
|
}
|
|
}
|
|
|
|
void TGGePoly2D::RemovePointListAt(int nIndex)
|
|
{
|
|
if (Length() > nIndex)
|
|
{
|
|
Remove(nIndex);
|
|
}
|
|
}
|
|
|
|
void TGGePoly2D::AppendPointListAt(TADSGePoint3d* pPt)
|
|
{
|
|
Append(pPt);
|
|
}
|
|
|
|
TADSGePoint3d* TGGePoly2D::GetPointListAt(int nIndex)
|
|
{
|
|
return (*this)[nIndex];
|
|
}
|
|
|
|
const TADSGePoint3d& TGGePoly2D::GetPointListAt(int nIndex) const
|
|
{
|
|
return (*this)[nIndex];
|
|
}
|
|
|
|
TGGePoly3D TGGePoly2D::PlaneToWcs(const AcGeVector3d& normal)const
|
|
{
|
|
TGGePoly3D poly3d = *this;
|
|
AcGeMatrix3d mat;
|
|
mat.setToPlaneToWorld(normal);
|
|
poly3d.TransformBy(mat);
|
|
return poly3d;
|
|
}
|
|
|
|
int TGGePoly2D::SetBulges(const TDPtrList<double>& ardbulges)
|
|
{
|
|
if (ardbulges.Length() > 0)
|
|
{
|
|
m_ardbulges.Reset();
|
|
m_ardbulges.copyFrom(ardbulges);
|
|
return m_ardbulges.Length();
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int TGGePoly2D::GetBulges(TDPtrList<double>& ardbulges)
|
|
{
|
|
if (m_ardbulges.Length() > 0)
|
|
{
|
|
ardbulges.copyFrom(m_ardbulges);
|
|
return ardbulges.Length();
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
TDPtrList<double>& TGGePoly2D::GetBulges()
|
|
{
|
|
return m_ardbulges;
|
|
}
|
|
|
|
bool TGGePoly2D::IsKindOf(TGGeEntity::TEntityId entType) const
|
|
{
|
|
switch(entType)
|
|
{
|
|
case TGGeEntity::eEntity:
|
|
case TGGeEntity::eCurve:
|
|
case TGGeEntity::ePoly2D:
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
TGGeEntity::TEntityId TGGePoly2D::Type() const
|
|
{
|
|
return TGGeEntity::ePoly2D;
|
|
}
|
|
|