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

427 lines
7.5 KiB
C++

#ifndef _XCURVEINLINE_H__
#define _XCURVEINLINE_H__
#ifndef _XLINE_H_
#include "XLine.h"
#endif
#ifndef _XCURVESEGMENT_H_
#include "XCurveSegment.h"
#endif
#ifndef _XCIRCLE_H_
#include "XCircle.h"
#endif
#ifndef _XPOLY2D_H_
#include "XPoly2D.h"
#endif
#ifndef _XPOLY_H_
#include "XPoly.h"
#endif
#ifndef _POINTLIST_H_
#include "PointList.h"
#endif
#include "geblok2d.h"
#include "geblok3d.h"
#ifdef _AEC_GELIB_
template <class R>
int IntersectWith(R &ln, XPoly2D &poly, PointList &pts)
{
int num = poly.TotalSegments();
XCurveSegment seg1;
for (int i = 0; i < num; i++)
{
if (poly.Nth(i, seg1) != RTNORM)
{
return -1;
}
seg1.SetLineFlag(LS_FINITE);
XPoint intPt[2];
int ptNum = seg1.Intersection(ln, intPt[0], intPt[1]);
for (int n = 0; n < ptNum; n++)
{
pts.Insert(intPt[n]);
}
}
return pts.Length() - 2;
}
#else
inline int IntersectWith(const XLine &ln, XPoly2D &poly, PointList &pts)
{
XCurveSegment seg1;
int num = poly.TotalSegments();
for (int i = 0; i < num; i++)
{
if (poly.Nth(i, seg1) != RTNORM)
{
return -1;
}
seg1.SetLineFlag(LS_FINITE);
XPoint intPt[2];
int ptNum = seg1.Intersection(ln, intPt[0], intPt[1]);
for (int n = 0; n < ptNum; n++)
{
pts.Insert(intPt[n]);
}
}
return pts.Length() - 2;
}
#endif
inline int operator &(const XPoint &pt0, const XArc &aArc)
{
//zjq 2009-08-31 直接取值计算
const XPoint& pt = pt0;
XPoint cenpt = aArc.m_ptCenter;
ads_real rad = aArc.m_dRadius;
ads_real ang1 = aArc.m_dstartAngle;
ads_real ang2 = aArc.m_dendAngle;
ads_real ang;
int tag;
ads_point ptStart, ptEnd;
if ( fabs(pt[2]-cenpt[2]) > _DIST_SNAP || fabs(ads_distance(cenpt,pt) - rad) > _DIST_SNAP )
{
return 0;
}
ang = ads_angle(cenpt,pt);
ads_polar(cenpt, ang1, rad, ptStart);
ads_polar(cenpt, ang2, rad, ptEnd);
if (ads_distance(ptStart, pt) < _DIST_SNAP)
{
return 1;
}
if (ads_distance(ptEnd, pt) < _DIST_SNAP)
{
return 2;
}
if (ang1 < ang2 )
{
if (ang > ang1 && ang < ang2)
{
tag = 3;
}
else
{
tag = 0;
}
}
else
{
if (ang > ang1 || ang < ang2)
{
tag = 3;
}
else
{
tag = 0;
}
}
return tag;
}
// 求点和园之间的关系, 返回关系码(0~3)
inline int operator &(const XPoint &pt, const XCircle & aCircle)
{
//zjq 2009-08-31
double r = pt.Distance(aCircle.m_ptCenter) - aCircle.m_dRadius;
if (fabs(r) < XGeLib::_DIST_SNAP)
{
return PR_ONCIRCLE;
}
if (r < 0)
{
return PR_INSIDE;
}
return PR_OUTSIDE;
}
inline int operator & (const XPoint &pt, const XLine & aLine)
{
double dDist = pt.Distance(aLine.m_startPoint,aLine.m_endPoint);
if (dDist > XGeLib::_DIST_SNAP)
{
return PR_OUTSIDE;
}
double dDist1 = pt.Distance(aLine.m_startPoint);
if (dDist1 < XGeLib::_DIST_SNAP)
{
return PR_ONPT1;
}
double dDist2 = pt.Distance(aLine.m_endPoint);
if (dDist2 < XGeLib::_DIST_SNAP)
{
return PR_ONPT2;
}
double dLength = aLine.GetLength();
if (fabs(dLength - (dDist1 + dDist2)) < XGeLib::_DIST_SNAP)
{
return PR_INSIDE;
}
return PR_EXTEND;
}
inline int operator & (const XPoint &pt, XLine & aLine)
{
return pt & (const XLine&)aLine;
}
inline int operator & (const XPoint &pt, const XCurveSegment &curve)
{
if (curve.Is(CURVE_LINE))
{
return (pt & (XLine& )curve);
}
else if (curve.Is(CURVE_ARC))
{
return (pt & curve.GetArc());
}
else
{
return (pt & curve.GetCircle());
}
}
inline int operator & (const XPoint &pt, XCurveSegment &curve)
{
if (curve.Is(CURVE_LINE))
{
return (pt & (XLine& )curve);
}
else if (curve.Is(CURVE_ARC))
{
return (pt & curve.GetArc());
}
else
{
return (pt & curve.GetCircle());
}
}
inline int operator & (const XPoint &ptMe, XPoly & aPoly)
{
// Modify here to support elevation not equal 0
// if(fabs(z)>1.0E-5)
// return Point(x,y,0)&aPoly;
int len = aPoly.Length();
if (len <= 2)
{
return PR_OUTSIDE;
}
Point pt,intPt; // 避免把 射线与 poly的第一个点在同一直线上
ads_polar(&ptMe.x, ads_angle(pt, *aPoly[0]) + 0.11 * PI, 10000000.0, pt);
XLine ln(&ptMe.x, pt, LS_FINITE);
int num = 0, lastOnPt = 0;
for (int i = 0; i < len; i++)
{
XLine aLine(Point(0,0,ptMe.z), pt, LS_FINITE); // Point(0,0) is changed to Point(0,0,z)
if(aPoly.NthLine(i, aLine)!=RTNORM)
{
return PR_OUTSIDE;
}
int flag = (ptMe & aLine);
if (flag == PR_INSIDE || flag == PR_ONPT1 || flag == PR_ONPT2)
{
return PR_EDGE;
}
if (ln.Intersection(&aLine, intPt))
{
int tag = intPt & aLine;
if (tag == PR_INSIDE)
{
num++;
}
else if (tag == PR_ONPT1)
{
if (lastOnPt)
{
lastOnPt = 0; //上次的终点和这次的起点
}
else
{
ads_fail(_T("\nBad pt&poly"));
}
}
else if (tag == PR_ONPT2)
{
if (lastOnPt)
{
ads_fail(_T("\nBad pt&poly"));
}
else
{
num++;
lastOnPt = 1;
}
}
else
{
ads_fail(_T("\nBad pt&poly"));
}
}
}
if (num % 2)
{
return PR_INSIDE;
}
return PR_OUTSIDE;
}
inline int operator & (const XPoint &pt0, XPoly2D &poly)
{
int len = poly.TotalSegments();
if (len<2)
{
return PR_OUTSIDE; //可以为两段弧构成
}
ASSERT(fabs(pt0.z-poly.Head()->z)<1.0E-9);
poly.MoveToHead();
static XPoint pt,pt1;
static double dStepAng = 0.11 * PI;
static double dAngStar = 0.13 * PI;
double ang = ads_angle(pt0, *poly[0]) + dAngStar;
static XLine ln(LS_FINITE);
ln.m_nFlag = LS_FINITE;
const XPoint& orgPt = pt0;
int pos = 0,isBreak = 0,num = 0;
// 避免把 射线与 poly的第一个点在同一直线上
//XPushPrec var(1.0E-6, 1.0E-3);
int ia = 0;
for (ia = 0; ia < 6; ia++)
{
ads_polar(pt0, ang, 1.0E10, pt);
ln.SetPoints(pt0, pt);
isBreak = 1;
poly.MoveToHead();
for (int i = 0; i < poly.Length(); i++)
{
//1. 判断pt0在poly的顶点上
XPoint& ptVex = *poly[i];
if (ptVex == orgPt)
{
return PR_EDGE;
}
//2. 判断ptVex落在ln上,或端点[1.已经排除]
pos = ptVex & ln;
if (pos >= PR_ONPT1 && pos <= PR_INSIDE)//PR_ONPT1,PR_ONPT2,PR_INSIDE
{
isBreak = 0;
break;
}
}
if (isBreak)
{
break;
}
ang += dStepAng;
}
if (ia == 6)
{
XGeLib::adsout << _T("\nWarning: unfavourable case in point&poly!");
}
poly.MoveToHead();
static XCurveSegment seg(LS_FINITE);
for (int i = 0; i<len; i++)
{
seg.m_nFlag = LS_FINITE;
seg.m_dBulge = 0.0;
if (poly.Nth(i, seg) != RTNORM)
{
return PR_OUTSIDE;
}
pos = orgPt&seg;
if (pos == PR_INSIDE || pos == PR_ONPT1 || pos == PR_ONPT2)
{
return PR_EDGE;
}
if (seg.Is(CURVE_LINE) && g_bFastCalMode)
{
if (ads_inters(seg.m_startPoint, seg.m_endPoint,ln.m_startPoint, ln.m_endPoint, 1, pt) == RTNORM)
{
num += 1;
}
}
else
{
num += seg.Intersection(ln,pt, pt1);
}
}
if (num%2)
{
return PR_INSIDE;
}
return PR_OUTSIDE;
}
inline int operator & (const XPoint &pt0, const XPoly2D &poly)
{
return (pt0 & (XPoly2D& )poly);
}
inline int operator & (const XLine &ln, XPoly2D &poly)
{
XPoint mpt = ln.MidPoint();
int flg0 = ln.GetStartPoint() & poly;
int flg1 = mpt & poly;
int flg2 = ln.GetEndPoint() & poly;
PointList pts(ln.GetStartPoint(), ln.GetEndPoint(), 0.0);
if (IntersectWith(ln, poly, pts) && pts.Length() > 2)
{//出现位于线内的交点
return PR_INTERS;
}
//线内没有交点
if (flg0 == PR_EDGE && flg1 == PR_EDGE && flg2 == PR_EDGE)
{
return PR_EDGE;
}
if ((flg0 == PR_INSIDE || flg0 == PR_EDGE) &&
(flg1 == PR_INSIDE || flg1 == PR_EDGE) &&
(flg2 == PR_INSIDE || flg2 == PR_EDGE))
{
return PR_INSIDE;
}
return PR_OUTSIDE;
}
#endif