425 lines
7.7 KiB
C++
425 lines
7.7 KiB
C++
#ifndef _TGGECURVEINLINE_H__
|
|
#define _TGGECURVEINLINE_H__
|
|
|
|
#ifndef _TGGELINE_H_
|
|
#include "TGGeLine.h"
|
|
#endif
|
|
|
|
#ifndef _TGGECURVESEGMENT_H_
|
|
#include "TGGeCurveSegment.h"
|
|
#endif
|
|
|
|
#ifndef _TGGECIRCLE_H_
|
|
#include "TGGeCircle.h"
|
|
#endif
|
|
|
|
#ifndef _TGGEPOLY2D_H_
|
|
#include "TGGePoly2D.h"
|
|
#endif
|
|
|
|
#ifndef _TGGEPOLY_H_
|
|
#include "TGGePoly.h"
|
|
#endif
|
|
|
|
#ifndef _TPOINTLIST_H_
|
|
#include "TPointList.h"
|
|
#endif
|
|
|
|
#include "geblok2d.h"
|
|
#include "geblok3d.h"
|
|
|
|
#ifdef _TCH_GELIB_
|
|
template <class R>
|
|
int Intersect(R &ln, TGGePoly2D &poly, TPointList &pts)
|
|
{
|
|
int num = poly.TotalSegments();
|
|
TGGeCurveSegment seg1;
|
|
for (int i = 0; i < num; i++)
|
|
{
|
|
if (poly.Nth(i, seg1) != RTNORM)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
seg1.SetLineFlag(LS_FINITE);
|
|
TADSGePoint3d 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 Intersect(const TGGeLine &ln, TGGePoly2D &poly, TPointList &pts)
|
|
{
|
|
TGGeCurveSegment seg1;
|
|
int num = poly.TotalSegments();
|
|
for (int i = 0; i < num; i++)
|
|
{
|
|
if (poly.Nth(i, seg1) != RTNORM)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
seg1.SetLineFlag(LS_FINITE);
|
|
TADSGePoint3d 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 TADSGePoint3d &pt0, const TGGeArc &aArc)
|
|
{
|
|
//lfy 2010-08-31 直接取值计算
|
|
const TADSGePoint3d& pt = pt0;
|
|
TADSGePoint3d 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 TADSGePoint3d &pt, const TGGeCircle & aCircle)
|
|
{
|
|
//lfy 2010-08-31
|
|
double r = pt.Distance(aCircle.m_ptCenter) - aCircle.m_dRadius;
|
|
if (fabs(r) < TchGeLib::_DIST_SNAP)
|
|
{
|
|
return PR_ONCIRCLE;
|
|
}
|
|
|
|
if (r < 0)
|
|
{
|
|
return PR_INSIDE;
|
|
}
|
|
|
|
return PR_OUTSIDE;
|
|
}
|
|
|
|
inline int operator & (const TADSGePoint3d &pt, const TGGeLine & aLine)
|
|
{
|
|
double dDist = pt.Distance(aLine.m_startPoint,aLine.m_endPoint);
|
|
if (dDist > TchGeLib::_DIST_SNAP)
|
|
{
|
|
return PR_OUTSIDE;
|
|
}
|
|
|
|
double dDist1 = pt.Distance(aLine.m_startPoint);
|
|
if (dDist1 < TchGeLib::_DIST_SNAP)
|
|
{
|
|
return PR_ONPT1;
|
|
}
|
|
|
|
double dDist2 = pt.Distance(aLine.m_endPoint);
|
|
if (dDist2 < TchGeLib::_DIST_SNAP)
|
|
{
|
|
return PR_ONPT2;
|
|
}
|
|
|
|
double dLength = aLine.GetLength();
|
|
if (fabs(dLength - (dDist1 + dDist2)) < TchGeLib::_DIST_SNAP)
|
|
{
|
|
return PR_INSIDE;
|
|
}
|
|
|
|
return PR_EXTEND;
|
|
}
|
|
|
|
inline int operator & (const TADSGePoint3d &pt, TGGeLine & aLine)
|
|
{
|
|
return pt & (const TGGeLine&)aLine;
|
|
}
|
|
|
|
inline int operator & (const TADSGePoint3d &pt, const TGGeCurveSegment &curve)
|
|
{
|
|
if (curve.Is(CURVE_LINE))
|
|
{
|
|
return (pt & (TGGeLine& )curve);
|
|
}
|
|
else if (curve.Is(CURVE_ARC))
|
|
{
|
|
return (pt & curve.GetArc());
|
|
}
|
|
else
|
|
{
|
|
return (pt & curve.GetCircle());
|
|
}
|
|
}
|
|
|
|
inline int operator & (const TADSGePoint3d &pt, TGGeCurveSegment &curve)
|
|
{
|
|
if (curve.Is(CURVE_LINE))
|
|
{
|
|
return (pt & (TGGeLine& )curve);
|
|
}
|
|
else if (curve.Is(CURVE_ARC))
|
|
{
|
|
return (pt & curve.GetArc());
|
|
}
|
|
else
|
|
{
|
|
return (pt & curve.GetCircle());
|
|
}
|
|
}
|
|
|
|
inline int operator & (const TADSGePoint3d &ptMe, TGGePoly & 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);
|
|
TGGeLine ln(&ptMe.x, pt, LS_FINITE);
|
|
|
|
int num = 0, lastOnPt = 0;
|
|
for (int i = 0; i < len; i++)
|
|
{
|
|
TGGeLine 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 TADSGePoint3d &pt0, TGGePoly2D &poly)
|
|
{
|
|
int len = poly.TotalSegments();
|
|
if (len<2)
|
|
{
|
|
return PR_OUTSIDE; //可以为两段弧构成
|
|
}
|
|
ASSERT(fabs(pt0.z-poly.Head()->z)<1.0E-9);
|
|
|
|
poly.MoveToHead();
|
|
|
|
static TADSGePoint3d pt,pt1;
|
|
static double dStepAng = 0.11 * PI;
|
|
static double dAngStar = 0.13 * PI;
|
|
|
|
double ang = ads_angle(pt0, *poly[0]) + dAngStar;
|
|
|
|
static TGGeLine ln(LS_FINITE);
|
|
ln.m_nFlag = LS_FINITE;
|
|
const TADSGePoint3d& 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的顶点上
|
|
TADSGePoint3d& 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 TGGeCurveSegment 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 TADSGePoint3d &pt0, const TGGePoly2D &poly)
|
|
{
|
|
return (pt0 & (TGGePoly2D& )poly);
|
|
}
|
|
|
|
inline int operator & (const TGGeLine &ln, TGGePoly2D &poly)
|
|
{
|
|
TADSGePoint3d mpt = ln.MidPoint();
|
|
int flg0 = ln.GetStartPoint() & poly;
|
|
int flg1 = mpt & poly;
|
|
int flg2 = ln.GetEndPoint() & poly;
|
|
|
|
TPointList 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;
|
|
}
|
|
|
|
#endif |