package com.dsh.activity.util;
|
|
import java.util.ArrayList;
|
import java.util.List;
|
|
public class GeoFenceChecker {
|
|
/**
|
* 判断点是否在多边形内
|
* @param polygon 多边形顶点坐标列表
|
* @param point 待检测的点
|
* @return true表示在多边形内,false表示在多边形外
|
*/
|
public static boolean isPointInPolygon(List<Point> polygon, Point point) {
|
int intersectCount = 0;
|
int vertexCount = polygon.size();
|
|
for (int i = 0; i < vertexCount; i++) {
|
Point p1 = polygon.get(i);
|
Point p2 = polygon.get((i + 1) % vertexCount);
|
|
// 检查水平向右的射线是否与边相交
|
if (rayIntersectsSegment(p1, p2, point)) {
|
intersectCount++;
|
}
|
}
|
|
// 交点为奇数表示点在多边形内
|
return intersectCount % 2 == 1;
|
}
|
|
/**
|
* 判断射线是否与线段相交
|
* @param p1 线段端点1
|
* @param p2 线段端点2
|
* @param point 测试点
|
* @return 是否相交
|
*/
|
private static boolean rayIntersectsSegment(Point p1, Point p2, Point point) {
|
// 确保p1的y坐标小于等于p2的y坐标
|
if (p1.y > p2.y) {
|
Point temp = p1;
|
p1 = p2;
|
p2 = temp;
|
}
|
|
// 如果点的y坐标在线段y坐标范围之外,则不相交
|
if (point.y < p1.y || point.y > p2.y) {
|
return false;
|
}
|
|
// 水平线情况特殊处理
|
if (p1.y == p2.y) {
|
return false;
|
}
|
|
// 计算交点的x坐标
|
double xIntersection = (point.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x;
|
|
// 如果交点在测试点的右边,则相交
|
return point.x < xIntersection;
|
}
|
|
/**
|
* 坐标点类
|
*/
|
public static class Point {
|
public double x;
|
public double y;
|
|
public Point(double x, double y) {
|
this.x = x;
|
this.y = y;
|
}
|
}
|
|
|
}
|