一、问题
在 GIS、无人机巡检、电子围栏、地图系统等场景中,经常需要判断:
一个点是否位于某个多边形区域内?
关于这一问题,可以使用射线法判断。
二、射线法核心思想
- 从待判断的点出发,向右画一条水平射线;
- 统计这条射线与多边形边的交点个数;
- 如果交点数为奇数 → 点在多边形内部;
- 如果交点数为偶数 → 点在多边形外部。
三、代码实现
- /** * 判断一个点是否在一个区域中 * @param point * @param polygon * @return */ public static boolean isPointInPolygon(Point point, List 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坐标
复制代码 表示:
交点是否在点的右侧。
如果满足条件,则说明发生了一次有效相交。
每遇到一次相交:进行一次布尔翻转。
- 第 1 次相交 → true
- 第 2 次相交 → false
- 第 3 次相交 → true
最终得到奇偶结果。
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |