android 如何判断点是否在多边形内

在开发中我们经常会遇到需要监听手势动作的需求,往往这些需求会与界面的某个区域绑定。但是当该区域是一个不规则的多边形时,这就给我们的判断添加了相当大的难度。

其实在百度地图中就有判断点是否在指定区域内的功能,API中提供了相关的方法。但我们不可能在不使用地图功能的时候去特地导入BaiDuMap来实现这一功能,所以在这里我将改功能的实现提取出自定义一个工具类。

首先定义一个类Point,表示点

public class Point {
    double x;//X坐标
    double y;//y坐标
}

之后就是重头戏

/**
 * 参照百度地图的SpatialRelationUtil工具类
 */

public class SpatialRelationUtil {
    private SpatialRelationUtil() {
    }

    /**
     * 返回一个点是否在一个多边形区域内
     *
     * @param mPoints 多边形坐标点列表
     * @param point   待判断点
     * @return true 多边形包含这个点,false 多边形未包含这个点。
     */
    public static boolean isPolygonContainsPoint(List<Point> mPoints, Point point) {
        int nCross = 0;
        for (int i = 0; i < mPoints.size(); i++) {
            Point p1 = mPoints.get(i);
            Point p2 = mPoints.get((i + 1) % mPoints.size());
            // 取多边形任意一个边,做点point的水平延长线,求解与当前边的交点个数
            // p1p2是水平线段,要么没有交点,要么有无限个交点
            if (p1.getY() == p2.getY())
                continue;
            // point 在p1p2 底部 --> 无交点
            if (point.getY() < Math.min(p1.getY(), p2.getY()))
                continue;
            // point 在p1p2 顶部 --> 无交点
            if (point.getY() >= Math.max(p1.getY(), p2.getY()))
                continue;
            // 求解 point点水平线与当前p1p2边的交点的 X 坐标
            double x = (point.getY() - p1.getY()) * (p2.getX() - p1.getX()) / (p2.getY() - p1.getY()) + p1.getX();
            if (x > point.getX()) // 当x=point.x时,说明point在p1p2线段上
                nCross++; // 只统计单边交点
        }
        // 单边交点为偶数,点在多边形之外 ---
        return (nCross % 2 == 1);
    }

    /**
     * 返回一个点是否在一个多边形边界上
     *
     * @param mPoints 多边形坐标点列表
     * @param point   待判断点
     * @return true 点在多边形边上,false 点不在多边形边上。
     */
    public static boolean isPointInPolygonBoundary(List<Point> mPoints, Point point) {
        for (int i = 0; i < mPoints.size(); i++) {
            Point p1 = mPoints.get(i);
            Point p2 = mPoints.get((i + 1) % mPoints.size());
            // 取多边形任意一个边,做点point的水平延长线,求解与当前边的交点个数

            // point 在p1p2 底部 --> 无交点
            if (point.getY() < Math.min(p1.getY(), p2.getY()))
                continue;
            // point 在p1p2 顶部 --> 无交点
            if (point.getY() > Math.max(p1.getY(), p2.getY()))
                continue;

            // p1p2是水平线段,要么没有交点,要么有无限个交点
            if (p1.getY() == p2.getY()) {
                double minX = Math.min(p1.getX(), p2.getX());
                double maxX = Math.max(p1.getX(), p2.getX());
                // point在水平线段p1p2上,直接return true
                if ((point.getY() == p1.getY()) && (point.getX() >= minX && point.getX() <= maxX)) {
                    return true;
                }
            } else { // 求解交点
                double x = (point.getY() - p1.getY()) * (p2.getX() - p1.getX()) / (p2.getY() - p1.getY()) + p1.getX();
                if (x == point.getX()) // 当x=point.x时,说明point在p1p2线段上
                    return true;
            }
        }
        return false;
    }
}
我们可以直接通过静态方法  isPolygonContainsPoint 来判断点是否在区域内;

参数List<Point> mPoints 表示区域边界组成的点的列表,必须沿边界顺序添加

而第二个参数就明显表示所需要判断的点的坐标

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android Studio中,我们可以使用高德地图的API来根据经纬度计算面积并判断一个是否在圈内。 首先,我们需要导入高德地图的相关库文件,并获取一个AMap对象,用来进行地图操作。 然后,我们可以使用AMap对象中的AMapUtils类中的calculateArea()方法来计算多边形的面积。这个方法接收一个List<LatLng>类型的参数,用于传入多边形的顶经纬度坐标。返回的面积单位为平方米。 另外,要判断一个是否在圈内,我们可以使用AMap对象中的AMapUtils类中的isPolygonContainsPoint()方法。这个方法接收一个LatLng类型的坐标和一个List<LatLng>类型的多边形坐标。返回一个布尔值,表示该是否多边形内部。 具体代码如下: ``` // 导入相关库文件 import com.amap.api.maps.AMap; import com.amap.api.maps.AMapUtils; import com.amap.api.maps.model.LatLng; // 获取AMap对象 AMap aMap = mapView.getMap(); // 计算多边形面积 List<LatLng> polygonPoints = new ArrayList<>(); polygonPoints.add(new LatLng(39.90923, 116.397428)); polygonPoints.add(new LatLng(39.90823, 116.397428)); polygonPoints.add(new LatLng(39.90823, 116.398428)); polygonPoints.add(new LatLng(39.90923, 116.398428)); float area = AMapUtils.calculateArea(polygonPoints); // 判断一个是否在圈内 LatLng point = new LatLng(39.90923, 116.397428); boolean isContains = AMapUtils.isPolygonContainsPoint(point, polygonPoints); ``` 以上就是使用Android Studio中的高德地图API根据经纬度计算面积和判断一个是否在圈内的方法。注意,要在项目中正确引入高德地图的API,并在AndroidManifest.xml文件中注册相关权限和配置。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值