pnpoly算法 判断点在多边形内 java实现

pnpoly算法的原理简述:就是过一个点引一条射线,如果射线与多边形相交的点是奇数,则点在多边形中;如果是偶数,则点在多边形外。

pnpoly算法的详细解析和数学公式可以在网络上查阅,这里不做赘述。为了方便java用户使用,自己实现了一个 java的版本,如果大家有需要用到可以参考一下。


    /**
     * <p>
     * Principle of pnpoly algorithm: draw a ray from a target point,
     * and count the number of intersections between this ray and the pair of deformations.
     * If there are an odd number of intersections, the target point is inside the polygon,
     * and if there are even intersections, it is outside
     * </p>
     *
     * @param vertX polygon coordinates latitudes
     * @param vertY polygon coordinates longitudes
     * @param x     longitude
     * @param y     latitude
     * @return true indicate inside of the polygon, false indicate outside of the polygon
     */
    private static boolean pnpolyAlgorithm(List<Double> vertX, List<Double> vertY, double x, double y) {
        if (CollectionUtils.isEmpty(vertX) || CollectionUtils.isEmpty(vertY)) {
            return false;
        }
        double maxX = vertX.stream().max(Comparator.comparingDouble(Double::doubleValue)).get();
        double maxY = vertY.stream().max(Comparator.comparingDouble(Double::doubleValue)).get();
        double minX = vertX.stream().min(Comparator.comparingDouble(Double::doubleValue)).get();
        double minY = vertY.stream().min(Comparator.comparingDouble(Double::doubleValue)).get();

        if (x < minX || x > maxX || y < minY || y > maxY) {
            return false;
        }
        int i, j;
        boolean result = false;
        int n = vertX.size();
        Double[] vertx = vertX.toArray(new Double[0]);
        Double[] verty = vertY.toArray(new Double[0]);
        for (i = 0, j = n - 1; i < n; j = i++) {
            if ((verty[i] > y) != (verty[j] > y) &&
                    (x < (vertx[j] - vertx[i]) * (y - verty[i]) / (verty[j] - verty[i]) + vertx[i])) {
                result = !result;
            }
        }
        return result;
    }
  1.  if (x < minX || x > maxX || y < minY || y > maxY) :简单判断点是否在多边形内;
  2. 后面循环判断点引出的射线和两点连线相交,如果相交就取反: 偶数结果就是初始值不变(false),奇数就是false取反(true)。

为了方便大家测试,提供一些测试数据

1.多边形坐标点数据

lat(41.93280493857098).lng(-88.07128206152345)

lat(41.9011265125114).lng(-87.9531790341797)

lat(41.81572092968781).lng(-88.08707490820314)
lat(41.89141546009437).lng(-87.98957124609376)

2. 测试点的数据

  • 处于内部点的坐标:
-88.00033330966825, 41.905377402302896 
-87.99655675937528, 41.905377402302896

  •  处于外部点的坐标:
-87.83914710023897, 41.93896430313074
-88.02642583896512, 41.881354232950315
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

知始行末

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值