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