#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 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 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; }