407 lines
7.5 KiB
C++
407 lines
7.5 KiB
C++
#pragma once
|
|
#include "globalfunc.h"
|
|
#include "GeLine.h"
|
|
#include "GeCurveSegment.h"
|
|
#include "GeCircle.h"
|
|
#include "GePoly2D.h"
|
|
#include "GePoly.h"
|
|
#include "PointList.h"
|
|
#include "geblok2d.h"
|
|
#include "geblok3d.h"
|
|
|
|
#define SHGE
|
|
|
|
#ifdef SHGE
|
|
template <class R>
|
|
int _Intersect_(R &ln, GePoly2D &poly, PointList &pts)
|
|
{
|
|
int num = poly.TotalSegments();
|
|
GeCurveSegment seg1;
|
|
for (int i = 0; i < num; i++)
|
|
{
|
|
if (poly.Nth(i, seg1) != RTNORM)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
seg1.SetLineFlag(LS_FINITE);
|
|
ADSGePoint3d 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
|
|
int Intersect(const GeLine &ln, GePoly2D &poly, PointList &pts)
|
|
{
|
|
GeCurveSegment seg1;
|
|
int num = poly.TotalSegments();
|
|
for (int i = 0; i < num; i++)
|
|
{
|
|
if (poly.Nth(i, seg1) != RTNORM)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
seg1.SetLineFlag(LS_FINITE);
|
|
ADSGePoint3d 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 ADSGePoint3d &pt0, const GeArc &aArc)
|
|
{
|
|
//lfy 2010-08-31 直接取值计算
|
|
const ADSGePoint3d& pt = pt0;
|
|
ADSGePoint3d 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]) > g_Option::instance()._DIST_SNAP || fabs(ads_distance(cenpt,pt) - rad) > g_Option::instance()._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) < g_Option::instance()._DIST_SNAP)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
if (ads_distance(ptEnd, pt) < g_Option::instance()._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 ADSGePoint3d &pt, const GeCircle & aCircle)
|
|
{
|
|
//lfy 2010-08-31
|
|
double r = pt.Distance(aCircle.m_ptCenter) - aCircle.m_dRadius;
|
|
if (fabs(r) < g_Option::instance()._DIST_SNAP)
|
|
{
|
|
return PR_ONCIRCLE;
|
|
}
|
|
|
|
if (r < 0)
|
|
{
|
|
return PR_INSIDE;
|
|
}
|
|
|
|
return PR_OUTSIDE;
|
|
}
|
|
|
|
inline int operator & (const ADSGePoint3d &pt, const GeLine & aLine)
|
|
{
|
|
double dDist = pt.Distance(aLine.m_startPoint,aLine.m_endPoint);
|
|
if (dDist > g_Option::instance()._DIST_SNAP)
|
|
{
|
|
return PR_OUTSIDE;
|
|
}
|
|
|
|
double dDist1 = pt.Distance(aLine.m_startPoint);
|
|
if (dDist1 < g_Option::instance()._DIST_SNAP)
|
|
{
|
|
return PR_ONPT1;
|
|
}
|
|
|
|
double dDist2 = pt.Distance(aLine.m_endPoint);
|
|
if (dDist2 < g_Option::instance()._DIST_SNAP)
|
|
{
|
|
return PR_ONPT2;
|
|
}
|
|
|
|
double dLength = aLine.GetLength();
|
|
if (fabs(dLength - (dDist1 + dDist2)) < g_Option::instance()._DIST_SNAP)
|
|
{
|
|
return PR_INSIDE;
|
|
}
|
|
|
|
return PR_EXTEND;
|
|
}
|
|
|
|
inline int operator & (const ADSGePoint3d &pt, GeLine & aLine)
|
|
{
|
|
return pt & (const GeLine&)aLine;
|
|
}
|
|
|
|
inline int operator & (const ADSGePoint3d &pt, const GeCurveSegment &curve)
|
|
{
|
|
if (curve.Is(CURVE_LINE))
|
|
{
|
|
return (pt & (GeLine& )curve);
|
|
}
|
|
else if (curve.Is(CURVE_ARC))
|
|
{
|
|
return (pt & curve.GetArc());
|
|
}
|
|
else
|
|
{
|
|
return (pt & curve.GetCircle());
|
|
}
|
|
}
|
|
|
|
inline int operator & (const ADSGePoint3d &pt, GeCurveSegment &curve)
|
|
{
|
|
if (curve.Is(CURVE_LINE))
|
|
{
|
|
return (pt & (GeLine& )curve);
|
|
}
|
|
else if (curve.Is(CURVE_ARC))
|
|
{
|
|
return (pt & curve.GetArc());
|
|
}
|
|
else
|
|
{
|
|
return (pt & curve.GetCircle());
|
|
}
|
|
}
|
|
|
|
inline int operator & (const ADSGePoint3d &ptMe, GePoly & 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);
|
|
GeLine ln(&ptMe.x, pt, LS_FINITE);
|
|
|
|
int num = 0, lastOnPt = 0;
|
|
for (int i = 0; i < len; i++)
|
|
{
|
|
GeLine 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 ADSGePoint3d &pt0, GePoly2D &poly)
|
|
{
|
|
int len = poly.TotalSegments();
|
|
if (len<2)
|
|
{
|
|
return PR_OUTSIDE; //可以为两段弧构成
|
|
}
|
|
ASSERT(fabs(pt0.z-poly.Head()->z)<1.0E-9);
|
|
|
|
poly.MoveToHead();
|
|
|
|
static ADSGePoint3d pt,pt1;
|
|
static double dStepAng = 0.11 * PI;
|
|
static double dAngStar = 0.13 * PI;
|
|
|
|
double ang = ads_angle(pt0, *poly[0]) + dAngStar;
|
|
|
|
static GeLine ln(LS_FINITE);
|
|
ln.m_nFlag = LS_FINITE;
|
|
const ADSGePoint3d& orgPt = pt0;
|
|
|
|
int pos = 0,isBreak = 0,num = 0;
|
|
|
|
// 避免把 射线与 poly的第一个点在同一直线上
|
|
//TPushPrec var(1.0E-6, 1.0E-3);
|
|
|
|
for (int 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的顶点上
|
|
ADSGePoint3d& 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)
|
|
//{
|
|
// TchGeLib::adsout << _T("\nWarning: unfavourable case in point&poly!");
|
|
//}
|
|
|
|
poly.MoveToHead();
|
|
static GeCurveSegment 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_Option::instance().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 ADSGePoint3d &pt0, const GePoly2D &poly)
|
|
{
|
|
return (pt0 & (GePoly2D& )poly);
|
|
}
|
|
|
|
inline int operator & (const GeLine &ln, GePoly2D &poly)
|
|
{
|
|
ADSGePoint3d 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 (_Intersect_(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;
|
|
}
|