判断一个点在多边形内:crossing-ray方法
核心思想
- 过点作一条射线,与多边的交点,交点个数为奇数表明该点在多边形内部,交点个数为偶数表明该点在多边形外部。
题目及代码
- 几何计算简化如下:
点(x,y) 为坐标点,coords[x1,y1,x2,y2,x3,y3,x4,x4,…,x1,y1]为连续封闭区域坐标点。判断点(x,y)是否在多边形内部。 - 步骤1:每次遍历相邻的两点,判断给定点的射线(此处采用平行于x轴的向右不断延伸射线)是否存在交点。
- 步骤2:是否存在交点的判别条件为:利用两点式构造线段,代入给定点纵坐标y,判断x坐标值xLine是否大于给定点横坐标x,大于则存在1个交点。
- 步骤3:最终根据交点个数的奇偶,判断是否存在于封闭多边形内部。
- 代码
class Solution {
public boolean isPointInPolygon(int x, int y, int[] coords) {
int n = coords.length;
int crossPoint = 0;
for (int i = 0;i < n - 2;i += 2){
int x1 = (int)coords[i],y1 = (int)coords[i + 1];
int x2 = (int)coords[i + 2],y2 = (int)coords[i + 3];
if (y1 == y2) continue;
else if (y < Math.min(y1,y2)) continue;
else if (y >= Math.max(y1,y2)) continue;
double xLine = (y - y1) * (x2 - x1) / (y2 - y1) + x1;
if (xLine > x) {
System.out.println(x1 + "," + y1 + "--" + x2 + "," + y2);
++crossPoint;
}
}
System.out.println(crossPoint);
return crossPoint % 2 == 1;
}
}
注意
- 点必须严格在多边形内部,不在边界上。
- 射线与多边形交于多边形端点时,切记仅需计算一次。
此处等号的近取一次,避免端点重复计算。
else if (y < Math.min(y1,y2)) continue;
else if (y >= Math.max(y1,y2)) continue;