判断坐标是否在电子围栏区域内

/**
     * 判断该点是否在区域内
     * 说明:该点出发的射线模拟为向左射出的水平射线
     * @param pointList 电子围栏的坐标点集合
     * @param point   坐标点
     * @return
     */
    public static Boolean isInArea(List<Point2D.Double> pointList, Point2D.Double point) {
        Point2D.Double p1, p2;
        Integer across = 0; //穿越次数
        double precision = 2e-10; //浮点类型计算时候的比较容差

        for (int i = 0; i < pointList.size(); i++) {
            p1 = pointList.get(i);
            //下一个点  如果是最后一个点 则是第一个点的坐标
            p2 = pointList.get((i + 1) >= pointList.size() ? 0 : (i + 1));
            // 1、在点上返回true
            if (p1.equals(point) || p2.equals(point)) {
                return true;
            }

            // 2、判断维度在范围内
            if (point.y <= Math.max(p1.y, p2.y) && point.y >= Math.min(p1.y, p2.y)) {

                // 3、判断精度在范围内(并且 压线)
                if (point.x <= Math.max(p1.x, p2.x) && point.x >= Math.min(p1.x, p2.x)) {
                    // 其一:水平线 压线
                    if (p1.y == p2.y&&point.y == p1.y) {
                        return true;
                    }
                    // 其二:垂直线 压线
                    if (p1.x == p2.x&&point.x == p1.x) {
                        return true;
                    }
                    // 其三:压斜线
                    double xianShangY = p1.y + (point.x - p1.x) * (p2.y - p1.y) / (p2.x - p1.x);
                    if (Math.abs(xianShangY - point.y) < precision) {
                    // 在线上
                        return true;
                    }
                }

                // 4、精度压线  或在范围外
                if (point.x <= Math.min(p1.x, p2.x)) {
                    continue;
                }
                /*
                  该点位于两个端点之间,判断是否穿过顶点(穿过顶点时,顶点按照在射线上部处理)
                   穿过顶点时,只有两个端点在射线两侧的才按照穿越处理
                */
                if (p1.y != p2.y && point.y != Math.min(p1.y, p2.y)) {
                    across++;
                }
            }
        }
        if (across % 2 == 0) {
            // 偶数,在外部
            return false;
        }
        return true;
    }

判断依据是 坐标点 任意延伸一条线  如果穿插0 偶数条线 则在坐标以外  奇数条线则在坐标以内

只支持二维区域 (不要画这种莫比乌斯环克莱因瓶这样的奇奇怪怪的圈)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值