前言 📝
射线法即从P点引出一条射线,看这条射线和多边形相交的次数。假如P点在多边形外,那么P点射线和多边形相交情况一定是:穿入 -> …(中间可能有N次穿入穿出)… ->穿出,即穿入穿出的次数是偶数次,交点是偶数个。假如P点在多边形内,那么P点射线和多边形相交的情况一定是:穿出 -> …(后面可能有N次穿入穿出)…,总之最后一定是穿出,交点是奇数个。是不是不明白,懵逼的你和我一起看一下图。
本网站的图片截图于:https://blog.csdn.net/qq_23447231/article/details/121920282
1. 一般情况
1.1 P点在多边形外

结论: 要么一个相交点也没有,要么是双数个
1.2 P点在多边形内

结论:相交点总共是1个或者奇数个
2. 特殊情况(不考虑)
因为所有方向的射线都是一样的,所以为了分析方便,我们使用从P点开始的一条水平线作为射线来分析。 然而还有特殊情况:
2.1 P点在多边形顶点

2.2 P点和多边形的交点是顶点

2.3 P点在多边形线段上

2.4 P点的射线刚好经过多边形的一条边

2.5 P点的射线刚好经过多边形一条边,并且P点在这条边上

3. 编程思路
如果我们采用左射线的方法,那是不是直接相反,当交叉数量是奇数的时候,说明我们的点在多边形内。反之则在外面。
为什么要采用左射线的方法呢,我感觉容易理解一点。我们先看一下思路,我们采用左射线的情况思路:
我们先一条线一条线的判断,比如说我们的(x1,y1),(x2,y2)组成的一条线,如果说我们的P点不在两个点之间,则不可能会有交点。继续判断下一条边。如果说在中间的情况下,P点的左射线可能会和我们的线段有交点。然后我们可以利用几何方法得到P点的水平直线与该边交点的x坐标。然后判断交点的X坐标是在P点的左侧还是右侧。左侧则相交数量+1,右侧则继续判断下一条线段。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| function IsPtInPoly(aLat, aLon, pointList) {
var iSum = 0 var iCount = pointList.length
if(iCount < 3) { return false } var y = aLat var x = aLon for(var i = 0; i < iCount; i++) { var y1 = pointList[i].latitude var x1 = pointList[i].longitude if(i == iCount - 1) { var y2 = pointList[0].latitude var x2 = pointList[0].longitude } else { var y2 = pointList[i + 1].latitude var x2 = pointList[i + 1].longitude } if (((y >= y1) && (y < y2)) || ((y >= y2) && (y < y1))) { if (Math.abs(y1 - y2) > 0) { var x_intersect = x1 - ((x1 - x2) * (y1 - y)) / (y1 - y2); if(x_intersect < x) { iSum += 1 } } } } if(iSum % 2 != 0) { return true }else { return false } } module.exports = { IsPtInPoly: IsPtInPoly, };
|
