判断一个多边形是否在另一个多边形内部,Java代码

该博客介绍了一个Java方法,用于判断一个二维平面上的多边形是否完全位于另一个多边形内部。通过检查多边形的每个点是否在另一个多边形内,以及两多边形的边是否有交点来实现。提供了详细的代码实现和示例测试。

import java.awt.geom.Point2D;
import java.awt.geom.GeneralPath;
import java.util.Arrays;
import java.util.List;


public class MyUtil {

    /**
     * 判断多边形1是否在多边形2内部。true在内部,false不在内部
     *
     * @param polygon1 多边形1
     * @param polygon2 多边形2
     * @return
     */
    public static boolean isPolygonInPolygon(List<Point2D.Double> polygon1, List<Point2D.Double> polygon2) {
        // 如果多边形1的某一个点不在多边形2内部,则多边形1不在多边形2内部
        for (Point2D.Double pointPolygon1 : polygon1) {
            if (!isPointInPoly(pointPolygon1, polygon2)) {
                return false;
            }
        }

        // 如果多边形1和多边形2的某条边有交点,则多边形1不在多边形2内部
        for (int i = 0; i < polygon1.size(); i++) {
            // p1-p2多边形1的一条边
            Point2D.Double p1 = polygon1.get(i);
            Point2D.Double p2;
            if (i < polygon1.size() - 1) {
                p2 = polygon1.get(i + 1);
            } else {
                p2 = polygon1.get(0);
            }

            // p3-p4多边形2的一条边
            for (int j = 0; j < polygon2.size(); j++) {
                Point2D.Double p3 = polygon2.get(j);
                Point2D.Double p4;
                if (j < polygon2.size() - 1) {
                    p4 = polygon2.get(j + 1);
                } else {
                    p4 = polygon2.get(0);
                }

                if (isIntersect(p1, p2, p3, p4)) {
                    return false;
                }
            }
        }

        return true;
    }


    /**
     * 返回p1-p2,p3-p4两条线段是否有交点。true有,false没有
     *
     * @param p1
     * @param p2
     * @param p3
     * @param p4
     * @return
     */
    public static boolean isIntersect(Point2D.Double p1, Point2D.Double p2, Point2D.Double p3, Point2D.Double p4) {
        boolean flag = false;
        double d = (p2.getX() - p1.getX()) * (p4.getY() - p3.getY())
                - (p2.getY() - p1.getY()) * (p4.getX() - p3.getX());
        if (d != 0) {
            double r = ((p1.getY() - p3.getY()) * (p4.getX() - p3.getX())
                    - (p1.getX() - p3.getX()) * (p4.getY() - p3.getY())) / d;
            double s = ((p1.getY() - p3.getY()) * (p2.getX() - p1.getX())
                    - (p1.getX() - p3.getX()) * (p2.getY() - p1.getY())) / d;
            if ((r >= 0) && (r <= 1) && (s >= 0) && (s <= 1)) {
                flag = true;
            }
        }
        return flag;
    }


    /**
     * 返回一个点是否在一个多边形区域内。true在,false不在。如果点位于多边形的顶点或边上,不算做点在多边形内,返回false
     *
     * @param point   点
     * @param polygon 多边形
     * @return
     */
    public static boolean isPointInPoly(Point2D.Double point, List<Point2D.Double> polygon) {
        assertParams(point, polygon);

        GeneralPath p = new GeneralPath();
        Point2D.Double first = polygon.get(0);
        p.moveTo(first.x, first.y);
        int size = polygon.size();
        for (int i = 1; i < size; i++) {
            Point2D.Double pa = polygon.get(i);
            p.lineTo(pa.x, pa.y);
        }
        p.lineTo(first.x, first.y);
        p.closePath();
        return p.contains(point);
    }


    private static void assertParams(Point2D.Double point, List<Point2D.Double> polygon) {
        if (null == point || null == polygon) {
            throw new IllegalArgumentException("参数不能为空");
        }
        if (polygon.size() < 3) {
            throw new IllegalArgumentException("多边形点数需要大于等于3");
        }

    }

    public static void main(String[] args) {
        Point2D.Double p2 = new Point2D.Double(0, 0);
        Point2D.Double p3 = new Point2D.Double(1, 0);
        Point2D.Double p4 = new Point2D.Double(1, 1);
        Point2D.Double p5 = new Point2D.Double(2, 1);
        Point2D.Double p6 = new Point2D.Double(2, 0);
        Point2D.Double p7 = new Point2D.Double(3, 0);
        Point2D.Double p8 = new Point2D.Double(3, 3);
        Point2D.Double p9 = new Point2D.Double(0, 3);

        Point2D.Double p11 = new Point2D.Double(0.3, 1.3);
        Point2D.Double p12 = new Point2D.Double(2.8, 1.3);
        Point2D.Double p13 = new Point2D.Double(2.8, 0.8);
        Point2D.Double p14 = new Point2D.Double(0.3, 0.8);

		// false
        System.out.println(ShieldUtil.isPolygonInPolygon
                (Arrays.asList(p11, p12, p13, p14), Arrays.asList(p2, p3, p4, p5, p6, p7, p8, p9)));
    }
}

### 判断经纬度点是否多边形区域内 在地理信息系统(GIS)中,判断一个是否位于多边形区域内是一个常见的问题。可以通过射线法(Ray Casting Algorithm)或积法来实现。以下是使用 Java 实现的一个简单版本,不依赖任何第三方库。 #### 数据结构定义 首先定义一个 `Point` 类来表示经纬度点: ```java class Point { double x; // 经度 double y; // 纬度 public Point(double x, double y) { this.x = x; this.y = y; } } ``` #### 判断是否多边形内 下一个基于射线法的实现,用于判断给定的点是否位于多边形内部: ```java public class PolygonUtils { /** * 判断是否多边形内部 * @param point 要判断的点 * @param polygon 多边形的顶点列表 * @return true 如果点在多边形内部,否则 false */ public static boolean isPointInPolygon(Point point, Point[] polygon) { int n = polygon.length; boolean inside = false; for (int i = 0, j = n - 1; i < n; j = i++) { if ((polygon[i].y > point.y) != (polygon[j].y > point.y) && (point.x < (polygon[j].x - polygon[i].x) * (point.y - polygon[i].y) / (polygon[j].y - polygon[i].y) + polygon[i].x)) { inside = !inside; } } return inside; } public static void main(String[] args) { // 定义一个多边形 Point[] polygon = { new Point(100.0, 0.0), new Point(101.0, 0.0), new Point(101.0, 1.0), new Point(100.0, 1.0) }; // 定义一个点 Point point = new Point(100.5, 0.5); // 判断是否多边形内部 boolean result = isPointInPolygon(point, polygon); System.out.println("点是否多边形内部: " + result); } } ``` #### 代码说明 - **射线法**:该算法的基本思想是从给定点向任意方向(通常是向右)发射一条射线,统计该射线与多边形边界的交点数量。如果交点数量为奇数,则点在多边形内部;如果为偶数,则点在多边形外部。 - **边界条件处理**:为了处理多边形的闭合性,每次循环时会将当前顶点与下一个顶点进行比较,最后一个顶点与第一个顶点进行比较。 - **交叉点计算**:通过判断是否在两个顶点之间的水平线段上,并且是否在该线段的左侧来确定射线是否与其相交。 #### 注意事项 - **多边形顺序**:多边形的顶点应按照顺时针或逆时针顺序排列,不能随意排序,否则可能导致判断错误。 - **性能优化**:对于大规模多边形数据,可以考虑使用更高效的算法或数据结构,如四叉树或网格索引。 #### 示例输出 运行上述代码后,控制台将输出: ``` 点是否多边形内部: true ``` 这表明该点位于多边形内部。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值