How can I group an array of rectangles into “Islands” of connected regions?

前端 未结 8 2038
难免孤独
难免孤独 2021-02-04 08:12

The problem

I have an array of java.awt.Rectangles. For those who are not familiar with this class, the important piece of information is that they provid

8条回答
  •  太阳男子
    2021-02-04 08:49

    Alright, I think I got it. This algorithm is rather inefficient, O(n^3) by wich's calculation, but it does seem to work.

    I used Set instead of List in getIntersections() to keep from counting the same rectangle twice (although I don't think this is actually necessary). I guess your final result could even be a Set> but the algorithm should be about the same. I also used Lists everywhere instead of arrays because I think arrays are ugly, but it's easy enough to convert back if you need to. The set newRectanglesToBeAdded lets us decide whether we need to keep looping or not, and also keeps us from adding to a list while we're iterating over it (which is just as bad as trying to remove things from a list while we're iterating over it). I don't think it's the most elegant solution, but it seems to work (at least for the test data you provided).

      public static Set getIntersections(List list,
          Rectangle r) {
        Set intersections = new HashSet();
        intersections.add(r);
    
        Set newIntersectionsToBeAdded = new HashSet();
    
        do {
          newIntersectionsToBeAdded.clear();
          for (Rectangle r1 : list) {
            for (Rectangle r2 : intersections) {
              if (!intersections.contains(r1) && r2.intersects(r1)) {
                newIntersectionsToBeAdded.add(r1);
              }
            }
          }
          intersections.addAll(newIntersectionsToBeAdded);
        } while (!newIntersectionsToBeAdded.isEmpty());
        return intersections;
      }
    
      public static List> mergeIntersectingRects(List allRects) {
        List> grouped = new ArrayList>();
        while (!allRects.isEmpty()) {
          Set intersections = getIntersections(allRects, allRects.get(0));
          grouped.add(intersections);
          allRects.removeAll(intersections);
        }
        return grouped;
      }
    

提交回复
热议问题