判断点是否在一个区域内

这篇博客介绍了如何判断一个经纬度坐标点是否位于由其他坐标点围成的多边形区域内。通过将区域放入x-y坐标轴,绘制射线并与区域边线交点计数,若交点数为奇数则点在区域内。文章详细阐述了判断过程,包括检查点坐标范围、使用直线公式求交点,并提供了相应的Java代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题是给定一个经纬度坐标点A,以及坐标围成的区域坐标数组,判断该点在不在此区域。

思路是这样的:

将区域放入x-y坐标轴中,取A的x或者y坐标,向一个方向画射线,若是与区域的交点为奇数时,则A点在该区域(这个的前提A点的x或者y坐标就在区域的范围内,要排除A在区域的边界上或者顶点上

若是A点非要在顶点上或者边界上,为了避免问题就要在判断A点x或者y轴范围的时候取一个实点一个虚点,例如:[4,5)。然后利用直线公式获取交点的y或者x轴坐标,然后判断点是否在射线的那个方向(画的x轴射线现在就获取y坐标,画的用y轴射线现在就获取x坐标)这样如果交点的数量还是奇数就说明A点在区域内。

1.把区域放入x-y坐标轴中,就是这样:

手绘的不要太在意细节。

2.判断A点x或者y坐标就在区域的范围内

这样两边都比较一下是因为不能够确定点集合中的点位大小是不是按顺序排列的。

ALat >= dLat1) && (ALat < dLat2)) || ((ALat >= dLat2) && (ALat < dLat1)

3.利用公式获取A点的y或者x坐标

直线公式:(y-y1)/(y2-y1)=(x-x1)/(x2-x1)

4.判断是否在所选的一侧

这一步比较大小就好了,应该都明白。

付一下代码:

 /**
     * 判断某个点是否在一个经纬度围成的多边形中
     * @param ALon 经度
     * @param ALat 纬度
     * @param ps 点集合
     * @return
     */
public boolean isPtInPoly (double ALon , double ALat , Ponits[] ps) {
        int iSum, iCount, iIndex;
        double dLon1 = 0, dLon2 = 0, dLat1 = 0, dLat2 = 0, dLon;
        if (ps.length < 3) {
            return false;
        }
        iSum = 0;
        iCount = ps.length;

        for (iIndex = 0; iIndex<iCount;iIndex++) {

            //按顺序取出数组中的两个点,若是最后一个点就与第一个点组合
            if (iIndex == iCount - 1) {
                dLon1 = ps[iIndex].getX();
                dLat1 = ps[iIndex].getY();
                dLon2 = ps[0].getX();
                dLat2 = ps[0].getY();
            } else {
                dLon1 = ps[iIndex].getX();
                dLat1 = ps[iIndex].getY();
                dLon2 = ps[iIndex + 1].getX();
                dLat2 = ps[iIndex + 1].getY();
            }


            //判断A点是否在边的两端点的水平平行线之间
            if (((ALat >= dLat1) && (ALat < dLat2)) || ((ALat >= dLat2) && (ALat < dLat1))) {
                if (Math.abs(dLat1 - dLat2) > 0) {

                    //得到 A点向左射线与边的交点的x坐标:
                    dLon = dLon1 - ((dLon1 - dLon2) * (dLat1 - ALat) ) / (dLat1 - dLat2);

                    // 如果交点在A点左侧(说明是做射线与边的交点)则交点数加一:
                    if (dLon < ALon) {
                        iSum++;
                    }
                }
            }
        }


        //判断能否被2 整除,是否为奇数
        if ((iSum % 2) != 0) {
            return true;
        }

        return false;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值