402 lines
7.0 KiB
C
402 lines
7.0 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"
|
|
|
|
inline int AolIntersect(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;
|
|
}
|
|
|
|
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 (AolIntersect(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
|