判断是否在安全区

2024/08/27 Path

判断是否在安全区

目录

判断某个点是否在多边形前提:

  中心点: F
  多变形顶点: A、B、C、 D  、E
  离中心点最近半径长度为:t
  离中心点最远半径长度为:y
  当前所处于的点: K

判断步骤

1.判断当前K点到中心点F的距离 >=  y,则不在多边形内。
2.判断当前K点到中心点F的距离 <= t, 则说明在多边形内
3.迭代所有边,依次和当前点比较,判断是否都在同一侧,如果是则在多边形内,否则不在多变形内。

核心代码

/**
 * 检测点是否在多边形内
 * @param point 需要检测的点
 * @return 点是否在多边形内
 */
public boolean checkIsInside(Vector3D point) {
    if (!isEnable) {
        return false;
    }

    if (vertices.size() <= 2) {
        return false;
    }

    //判断距离
    double disToCenter = point.distance2D(center);
    if (disToCenter >= outerRadius) {
        return false;
    } else if (disToCenter <= innerRadius) {
        return true;
    }

    boolean preSide = false;

    //.迭代所有边,依次和当前点比较,判断是否都在同一侧,如果是则在多边形内,否则不在多变形内。
    for (int i = 0; i < vertices.size(); ++i) {
        Vector2D lineStart = vertices.get(i);
        //i 是当前循环迭代中的索引,表示当前处理的多边形的顶点。
        //(i + 1) % vertices.size() 计算的是下一个顶点的索引。这里使用了模运算 % vertices.size() 来确保索引不会超出顶点列表的范围,因为多边形是一个封闭的图形,最后一个顶点的下一个顶点应该是第一个顶点。
        //vertices.get((i + 1) % vertices.size()) 表示从顶点列表中获取下一个顶点的坐标,即多边形的当前边的结束点。
        Vector2D lineEnd = vertices.get((i + 1) % vertices.size());

        boolean curSide = checkIsAtLeftSide(point, lineStart, lineEnd);
        if (0 == i) {
            preSide = curSide;
        } else {
            if (preSide != curSide) {
                return false;
            }
        }
    }

    return true;
}

/**
 * 检测点是否在线段的左侧
 * @param point     需要检测的点
 * @param lineStart 线段的起点
 * @param lineEnd   线段的终点
 * @return 是否在线段的左侧
 */
private boolean checkIsAtLeftSide(Vector3D point, Vector2D lineStart, Vector2D lineEnd) {
    Vector2D vec1 = new Vector2D(point.x - lineStart.x, point.y - lineStart.y);
    Vector2D vec2 = lineEnd.sub(lineStart);

    double crossProduct = vec1.x * vec2.y - vec1.y * vec2.x;

    return crossProduct < 0;
}

Search

    Table of Contents