- UID
- 69009
- 积分
- 0
- 精华
- 贡献
-
- 威望
-
- 活跃度
-
- D豆
-
- 在线时间
- 小时
- 注册时间
- 2003-8-1
- 最后登录
- 1970-1-1
|
楼主 |
发表于 2003-8-22 17:29:45
|
显示全部楼层
根据本网站提供链接:http://www.xdcad.net/forum/showt ... d=399478#post399478
提供的算法,我写的代码如下:
/*
算法的伪代码如下:
1. count ← 0;
2. 以P为端点,作从右向左的射线L;
3, for 多边形的每条边s
4. do if P在边s上
5. then return true;
6. if s不是水平的
7. then if s的一个端点在L上且该端点是s两端点中纵坐标较大的端点
9. then count ← count+1
10. else if s和L相交
11. then count ← count+1;
12. if count mod 2 = 1
13. then return true
14. else return false;
其中做射线L的方法是:设P'的纵坐标和P相同,横坐标为正无穷大(很大的一个正数),
则P和P'就确定了射线L。这个算法的复杂度为O(n)。
*/
//判断点是否在多边形的范围内
bool IsPtInPolyline(AcDbPolyline* polyline,AcGePoint3d pt)
{
static double TOLERANCE1 =0.000001 ;//误差范围,只对本函数起作用
if(polyline==NULL)
return false ;
AcGeRay3d pRay(pt,-AcGeVector3d::kXAxis) ;//射线
AcGeTol tol;
tol.setEqualPoint(TOLERANCE1);//设置精度
int count(0) ;
int numverts = polyline->numVerts() ;
for(int i=0;i<numverts;i++)
{
if(polyline->segType(i)==AcDbPolyline::kLine)//直线
{
AcGeLineSeg3d plineseg ;
if(polyline->getLineSegAt(i,plineseg)!=Acad::eOk)
continue ;
if(plineseg.isOn(pt,tol)==Adesk::kTrue)//在此边上
return true ;
AcGeVector3d vec = plineseg.direction() ;
if(vec.isParallelTo(AcGeVector3d::kXAxis)==Adesk::kTrue)//与X轴平行
continue ;
AcGePoint3d pntSt = plineseg.startPoint() ;
AcGePoint3d pntEnd = plineseg.endPoint() ;
if(pntSt.distanceTo(pt)<TOLERANCE1&&pntSt.y>pntEnd.y)//与起点重合
count++ ;//加1
else if(pntEnd.distanceTo(pt)<TOLERANCE1&&pntEnd.y>pntSt.y)
count++ ;//加1
else if(pRay.distanceTo(plineseg)<TOLERANCE1)//和射线相交
count++ ;
}
else if(polyline->segType(i)==AcDbPolyline::kArc)//圆弧
{
AcGeCircArc3d arc;
if(polyline->getArcSegAt(i,arc)!=Acad::eOk)
continue ;
if(arc.isOn(pt,tol)==Adesk::kTrue)//在此边上
return true ;
AcGePoint3d pntSt = arc.startPoint() ;
AcGePoint3d pntEnd = arc.endPoint() ;
if(pntSt.distanceTo(pt)<TOLERANCE1&&pntSt.y>pntEnd.y)//与起点重合
count++ ;//加1
else if(pntEnd.distanceTo(pt)<TOLERANCE1&&pntEnd.y>pntSt.y)
count++ ;//加1
else if(pRay.distanceTo(arc)<TOLERANCE1)//和射线相交
count++ ;
}
}
if(count%2==1)//为奇数
return true ;
return false ;
} |
|