views:

569

answers:

3

I am looking for a way to calculate the common areas covered by multiple overlapping polygons. The polygons are all right-angled, if that helps makes things easier.

So for example:

   BBBBB
   BBBBB
AAA---BB
AAA---BB
AAAAAA
AA--AA
AA--AA
  LL
  LL
  LLLLLL
  LLLLLL

I would like to find the common area covered by A, B and L, which would equal: B = 5x4 = 20 + A = 6x5 = 30 + L = 4x2 + 6x2 = 20 = 70 minus overlapping areas: - 10 = 60 (common area covered by all polygons)

I need to be able to cater for situations where 3 or more polygons occupy the same area. Is there a suitable algorithm for this, which could take arrays of arrays of x/y co-ordinates as inputs? (sample Java source code would be very welcome).

A: 

Another way to do it would be to calculate area using a contour integral. Walk around the perimeter of the area and calculate area using Green's theorem and numerical quadrature. Easy peasy.

duffymo
The problem with this approach is that finding the perimeter is not an easier task than finding the area.
Camille
Interior nodes are shared by four polygons if they're all quadrilaterals. A perimeter node is shared by one, two, or three polygons. You can identify the perimeter nodes and start your walk at any point by transitioning to the next perimeter node. Integrate along that edge and then find the next one.
duffymo
I do not see why interior nodes should be shared by four polygons. Take for example two overlapping rectangles (each of them covering one corner of the other one). You also have to identify nodes of the perimeter that are not nodes of the original polygons.Of course you can identify the boundary of the union, but you will have to resort to some kind of sweep algorithm anyway for that task, hence my comment.
Camille
A: 

If you can represent the polygons as 2D int or bool arrays (A[i][j] == 1 if the ijth slot is contained in the polygon, 0 otherwise) then you can create the union of the polygons on a larger 2D "bounding" array.

The algorithm is something like this:

// get your polygons, each represented by a 2D array as described above

// create a "bounding" array B that can contain all polygons (watch out for
// sparsely spaced polygons in which case B could be large)

// populate B s.t. B[i][j] == 1 if ijth slot is contained in 
// the union of all polygons

// count all slots in B where B[i][j] == 1 (this will be the "common" area)

Thinking about the run time and space requirements: need to traverse every slot of every polygon. Need to traverse every slot of the bounding array B. Worst case for space is when the intersection of all polygons is empty (and perhaps they are sparsely spaced). Might be worthwhile to check the empty intersection case first... then if the intersection is empty the "common" area is just the sum of the individual areas.

MrDatabase
+1  A: 

A classical way of computing such an area is to use a sweep algorithm. You can have a look at question Area of overlapping rectangles to get a description of the algorithm in the simpler case of rectangles.

Then you can either decompose your polygons into rectangles, or adapt the sweep algorithm so that this decomposition is done implicitly during the sweep.

Camille