Files
envi-code/SourceCode/Code2026/Dimension/PointList.cpp
T
2026-09-28 15:28:50 +08:00

278 lines
5.8 KiB
C++

#include "StdAfx.h"
#include "PointList.h"
//#include "globalfunc.h"
#include "GeCurveInline.h"
//using namespace GlobalFunc;
PointList::PointList(const ADSGePoint3d & startPoint, const ADSGePoint3d & endPoint, ads_real bulge)
{
if (fabs(bulge) > 1E-6)
{ // Arc or circle
if (fabs(2*PI - bulge) < 1E-6)
{// Circle
curveType = CURVE_CIRCLE;
Append(new ADSGePoint3d (startPoint));
center = startPoint + endPoint;
center.Scale(0.5);
return;
}
else
{
center = GeArc(startPoint, endPoint, bulge).GetCenterPt();
curveType = CURVE_ARC;
}
}
else curveType = CURVE_LINE;
Append(new ADSGePoint3d (startPoint));
Append(new ADSGePoint3d (endPoint));
}
PointList::~PointList()
{
}
namespace
{
double AngleRangeTo2PI(double dAngle)
{
double dAngleTmp = dAngle;
if (fabs(dAngleTmp - 2.0 * PI) < 1.0E-9)
{
dAngleTmp = 0.0;
return dAngleTmp;
}
while ((dAngleTmp > (PI * 2.0 + 1.0E-9)) || (dAngleTmp < -1.0E-9))
{
if (dAngleTmp < -1.0E-9)
{
dAngleTmp = dAngleTmp + 2.0 * PI;
}
else if (dAngleTmp > (PI * 2.0 + 1.0E-9))
{
dAngleTmp = dAngleTmp - 2.0 * PI;
}
}
return dAngleTmp;
}
}
// Status: Insert point must between 0~max
int PointList::Insert(const ADSGePoint3d & pt, BOOL bExt)
{
if (curveType == CURVE_CIRCLE)
{
if ((pt & GeCircle(center, ads_distance(center, *(*this)[0]))) == PR_ONCIRCLE)
{
int listLen = Length();
ads_real curDrt = ads_angle(center, pt);
for (int i = 1; i < listLen; i++)
{
ads_real drt = ads_angle(center, *(*this)[i]);
if (::AngleRangeTo2PI(drt - curDrt) < g_DimOption::instance()._angSnap)
{
return RTERROR;
}
if (curDrt < drt)
{
PtrList<ADSGePoint3d>::Insert(new ADSGePoint3d(pt));
return RTNORM;
}
}
Append(new ADSGePoint3d(pt));
return RTNORM;
}
return RTERROR;
}
// arc and line
int listLen = Length();
PointList &segPoints = *this;
for (int j = 0; j < listLen-1; j++)
{
ADSGePoint3d &pt1 = *segPoints[j];
ADSGePoint3d &pt2 = *segPoints[j+1];
if (curveType == CURVE_LINE)
{
GeLine lineSeg(pt1, pt2, LS_FINITE);
if ((pt & lineSeg) == PR_INSIDE)
{
PtrList<ADSGePoint3d>::Insert(new ADSGePoint3d (pt));
return RTNORM;
}
}
else
{
GeArc arcSeg(center, ads_distance(center, pt1), ads_angle(center,pt1), ads_angle(center, pt2));
if ((pt & arcSeg) == PR_INSIDE)
{
PtrList<ADSGePoint3d>::Insert(new ADSGePoint3d (pt));
return RTNORM;
}
}
}
if (bExt)
{
ASSERT(listLen >= 2);
if (curveType == CURVE_LINE)
{
GeLine lineSeg(*Head(), *Tail());
if ((pt & lineSeg) == PR_EXTEND)
{
if (pt.Distance2d(*Head()) < pt.Distance2d(*Tail()))
{
(*this)[0];
PtrList<ADSGePoint3d>::Insert(new ADSGePoint3d(pt));
}
else
{
PtrList<ADSGePoint3d>::Append(new ADSGePoint3d(pt));
}
}
}
else
{
GeArc arcSeg(center, ads_distance(center, *Head()), ads_angle(center, *Head()), ads_angle(center, *Tail()));
// 没有考虑在端点,改正2001/9/13
if (fabs(pt.Distance2d(arcSeg.GetCenterPt()) - arcSeg.GetRadius()) < g_Option::instance()._DIST_SNAP &&
pt.Distance2d(*Head()) > g_Option::instance()._DIST_SNAP && pt.Distance2d(*Tail()) > g_Option::instance()._DIST_SNAP)
{ //在弧外
if (pt.Distance2d(*Head()) < pt.Distance2d(*Tail()))
{
(*this)[0];
PtrList<ADSGePoint3d>::Insert(new ADSGePoint3d(pt));
}
else
{
PtrList<ADSGePoint3d>::Append(new ADSGePoint3d(pt));
}
}
}
}
return RTERROR;
}
int PointList::Update(const ads_name ref)
{
EntitySet entRef = ref;
//entRef.GetGroups();
int listLen = Length();
PointList &pts = *this;
if (curveType == CURVE_CIRCLE)
{
if (listLen <= 2)
{// circle, but not cut to arcs
return RTERROR;
}
TCHAR lay[80] = _T("0");
entRef.GetData(8, lay);
for (int i = 1; i < listLen; i++)
{
ADSGePoint3d pt2;
if (i == listLen - 1)
{
pt2 = *pts[1];
}
else
{
pt2 = *pts[i+1];
}
GeArc arcSeg(center, ads_distance(center, *pts[i]), ads_angle(center, *pts[i]), ads_angle(center, pt2));
arcSeg.Make(lay);
}
ads_entdel(ref);
}
else
{
for (int j = 0; j<listLen-1; j++)
{ // arc and line
ADSGePoint3d &pt1 = *pts[j];
ADSGePoint3d &pt2 = *pts[j+1];
if (curveType == CURVE_LINE)
{
GeLine lineSeg(pt1, pt2);
if (j == 0)
{
lineSeg.Modify(&entRef);
}
else
{
lineSeg.MakeEntity(&entRef);
}
}
else
{
GeArc arcSeg(center, ads_distance(center, pt1), ads_angle(center,pt1), ads_angle(center, pt2));
if (j == 0)
{
arcSeg.Modify(&entRef);
}
else
{
arcSeg.MakeEntity(&entRef);
}
}
}
}
return RTNORM;
}
// 化作Poly2D
void PointList::AsPoly2D(GePoly2D &poly) const
{
int listLen = Length();
const PointList &pts = *this;
if (curveType == CURVE_CIRCLE)
{
if (listLen <= 2)
{ //圆分解为两段弧
GeCurveSegment segCir;
segCir = GeCircle(center, ads_distance(center, pts[0]));
segCir.AsPoly2D(poly);
}
else
{
//圆分解为多段弧
for (int i = 1; i < listLen; i++)
{
ADSGePoint3d pt2;
if (i == listLen-1) pt2 = pts[1];
else pt2 = pts[i+1];
GeArc arcSeg(center, ads_distance(center, pts[i]), ads_angle(center, pts[i]), ads_angle(center, pt2));
poly.AppendNode(pts[i], arcSeg.Bulge());
}
}
poly.SetFlag(1);
}
else
{
for (int j = 0; j<listLen-1; j++)
{ // arc and line
const ADSGePoint3d &pt1 = pts[j];
const ADSGePoint3d &pt2 = pts[j+1];
if (curveType == CURVE_LINE)
{
poly.AppendNode(pt1);
}
else
{
GeArc arcSeg(center, ads_distance(center, pt1), ads_angle(center,pt1), ads_angle(center, pt2));
poly.AppendNode(pt1, arcSeg.Bulge());
}
if (j == listLen - 2)
{
poly.AppendNode(pt2);
poly.SetFlag(0);
}
}
}
}