2013-06-03 55 views
1

作爲我正在研究的一個小型項目的一部分,我正在使用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); 

我所用的含有方法檢查對其它多邊形的每個點,但代碼:

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

返回false兩次。

有沒有辦法檢測這些「剛觸摸」的多邊形?

+0

看看[基於形狀的碰撞檢測](http://stackoverflow.com/a/14575043/418556)。 –

回答

0

我發現了一個解決方案,檢查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; 
    } 
} 

請讓我知道如果您遇到任何問題,我會盡我所能解決他們。

謝謝!