如何用射线法判断某点是否位于多边形区域内?

摘要:一、问题 在 GIS、无人机巡检、电子围栏、地图系统等场景中,经常需要判断: 一个点是否位于某个多边形区域内? 关于这一问题,可以使用射线法判断。 二、射线法核心思想 从待判断的点出发,向右画一条水平射线; 统计这条射线与多边形边的交点个数
一、问题 在 GIS、无人机巡检、电子围栏、地图系统等场景中,经常需要判断: 一个点是否位于某个多边形区域内? 关于这一问题,可以使用射线法判断。 二、射线法核心思想 从待判断的点出发,向右画一条水平射线; 统计这条射线与多边形边的交点个数; 如果交点数为奇数 → 点在多边形内部; 如果交点数为偶数 → 点在多边形外部。 三、代码实现 /** * 判断一个点是否在一个区域中 * @param point * @param polygon * @return */ public static boolean isPointInPolygon(Point point, List<Point> polygon) { boolean inside = false; int n = polygon.size(); for (int i = 0, j = n - 1; i < n; j = i++) { double xi = polygon.get(i).getLongitude(); double yi = polygon.get(i).getLatitude(); double xj = polygon.get(j).getLongitude(); double yj = polygon.get(j).getLatitude(); boolean intersect = ((yi > point.getLatitude()) != (yj > point.getLatitude())) && (point.getLongitude() < (xj - xi) * (point.getLatitude() - yi) / (yj - yi) + xi); if (intersect) { inside = !inside; } } return inside; } 四、代码说明 这段代码的核心在于判断: 射线是否与当前边产生一次有效交点。 关键逻辑如下: ((yi > point.getLatitude()) != (yj > point.getLatitude())) 这一步用于判断: 边的两个端点是否一个在点的上方,一个在点的下方。 如果两个端点都在射线同一侧,则一定不会相交。 (xj - xi) * (point.getLatitude() - yi) / (yj - yi) + xi 这一公式用于计算: 射线与当前边的交点的 x 坐标。 其推导来自线性插值公式: x = xi + (xj - xi) * (y - yi) / (yj - yi) 最后比较: point.getLongitude() < 交点x坐标 表示: 交点是否在点的右侧。 如果满足条件,则说明发生了一次有效相交。 每遇到一次相交: inside = !inside; 进行一次布尔翻转。 第 1 次相交 → true 第 2 次相交 → false 第 3 次相交 → true 最终得到奇偶结果。