【问题标题】:Detecting touching polygons检测接触多边形
【发布时间】:2013-05-29 23:15:25
【问题描述】:

作为我正在处理的一个小项目的一部分,我正在使用 Polygon 类,但我在处理“接触”而不是正确相交的多边形时遇到了困难。

例如,在我有两个多边形的情况下:

Polygon a = new Polygon(new int[] {0,0,3,3}, new int[] {0,1,0,1}, 4);
Polygon b = new Polygon(new int[] {1,1,2,2}, new int[] {1,2,1,2}, 4);

我使用 contains 方法检查每个点与另一个多边形,但是代码:

System.out.print(a.contains(1,1));
System.out.print(a.contains(2,1));

两次返回 false。

有什么方法可以检测这些“刚接触”的多边形吗?

【问题讨论】:

标签: java awt polygon contains java-2d


【解决方案1】:

如果您可以接受误差范围,请尝试polygon.intersects()

http://docs.oracle.com/javase/6/docs/api/java/awt/Polygon.html#intersects%28double,%20double,%20double,%20double%29

它需要一个矩形作为参数,但是如果你把矩形做得很小,你可以得到相同的结果。除此之外,Polygon 类似乎并不完全符合您的要求。另一方面,我能想到的应用程序很少有指定的误差范围不会更好......

【讨论】:

    【解决方案2】:

    我找到了一个解决方案来检查 2 个多边形是否相交,即使它们没有公共区域。为此,我正在使用 math.geom2D 库 (http://sourceforge.net/apps/mediawiki/geom-java/index.php?title=Main_Page)。我个人喜欢它,因为 Polygons2D 类允许您相对轻松地处理剪辑、交集和联合等操作。

    该方法使用 2 个 SimplePolygon2D 对象作为输入,可以使用 addVertex(Point2D point) 从您的数据构造。

    在某些情况下,此方法可能不起作用,但我会在找到解决方法后立即发布更多信息。

    public static boolean checkShapeAdjacency(SimplePolygon2D polygon1, SimplePolygon2D polygon2) {
        // Buffer distance. Depends on scale / data
        final float bufferDistance = 0.2f;
    
        if (polygon1 == polygon2) {
            return false;
        }
    
        List<Point2D> intersectingPoints = new ArrayList<Point2D>();
    
        if (polygon1.area() > 0 && polygon2.area() > 0) {
    
            try {
                // Make a buffer of one polygon
                CirculinearDomain2D bufferDomain = polygon1
                        .buffer(bufferDistance);
                /*               
                 * Iterate through the points of the other polygon and see if they
                 * are contained within the buffer
                 */
                for (Point2D p : polygon2.vertices()) {
                    if (bufferDomain.contains(p)) {
                        // Increase the intersecting point count
                        if (!intersectingPoints.contains(p)) {
                            intersectingPoints.add(p);
                        }
                    }
                }
            } catch (Exception e) {
                // Try/Catch to avoid degenerated line exceptions (common with math.geom2d)s
                e.printStackTrace();
                return false;
            }
        }
    
        // Check against the number of intersecting points
        if (intersectingPoints.size() >= 2) {
    
            /*
             * It is safe enough to assume that with 2 intersecting points,
             * the shape are adjacent. It will not work in the case of bad
             * geometry though. There are other methods of cleaning bad
             * geometry up.
             */
            return true;
        } else if (intersectingPoints.size() == 1) {
            /*
             * It gets tricky in the case of 1 intersecting point as one line may
             * be longer than the other. Check to see if one edge is entirely
             * in the other polygon.
             */
            for (LineSegment2D edge1 : polygon1.edges()) {
                if (polygon2.distance(edge1.firstPoint()) < 0.001 
                        && polygon2.distance(edge1.lastPoint()) < 0.001
                        && edge1.length() > 1) {
    
                    return true;
                }
            }
            for (LineSegment2D edge2 : polygon2.edges()) {
                if (polygon1.distance(edge2.firstPoint()) < 0.001 
                        && polygon1.distance(edge2.lastPoint()) < 0.001
                        && edge2.length() > 1) {
    
                    return true;
                }
            }
            // One common point and no common edge returns false
            return false;
        } else {
            return false;
        }
    }
    

    如果您遇到任何问题,请告诉我,我会尽我所能解决。

    谢谢!

    【讨论】:

    • 如果polygon2 与polygon1 相邻,但它的相邻边在两端都超出了polygon1,这不会失败吗?
    猜你喜欢
    • 1970-01-01
    • 2015-07-24
    • 2016-11-22
    • 1970-01-01
    • 2012-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多