8

Given a list rectangles [R1, R2, R3] defined by their lower left and upper right [(x1, y1), (x2, y2)] coordinates, and a value k.

Is there an optimal way to find area where k rectangles overlap?

For example:

R1: [(1, 1), (5, 5)]
R2: [(4, 4), (7, 6)]
R3: [(3, 3), (8, 7)]

rectangles = [R1, R2, R3]
k = 2

The area which is overlapped by two rectangles is 8.

Grid Image

Brute force way to solve this is calculate the min and max of x-axis and y-axis coordinates and then used that create a grid and increment one for each cell within rectangle. At the end iterate over the grid to compute number of cells which have a value as k to find the solution.

The approach has a complexity of O(n^3), assuming each each rectangle is of size n x n and there are n rectangles.

Is there a run time optimal way to approach this problem?

Aditya Bhatia
  • 191
  • 1
  • 8
  • 1
    Your complexity statement is a bit misleading. Actually, it is `O(AT + AU)`, where `AT` is the sum of all rectangle areas and `AU` is the area of the union (or the bounding box, depending on how you do the final iteration over all grid cells). While theoretically still having the same complexity, you might get faster in practice with an auto-partitioning kd-tree. I.e., you would not record overlaps per grid cell but per tree cell, of which there might be much fewer depending on the size distribution of rectangles. – Nico Schertler Jul 25 '19 at 02:09
  • I'm going to go with "Quadtree". – 3Dave Jul 25 '19 at 02:11

2 Answers2

1

The usual way to analyze collections of rectangles is with a sweep line algorithm. Imagine a vertical line that starts at the left of the collection and scans to the right. Store a set of the rectangles that currently intersect the line, initially empty. This set needs to be updated when the line passes a vertical side of any rectangle: adding or removing a rectangle in each case. To make scanning efficient, use a sorted list of the x coordinates of the verticals.

In this case, you'll also need a way to efficiently determine the intervals of the scan line that are covered by k or more rectangles. That can be done efficiently by maintaining an interval tree.

Depending on details, efficiency ought to be roughly O(n log n) for n rectangles with maybe an additional term for the maximum overlap depth. I'll let you work out the details.

Gene
  • 46,253
  • 4
  • 58
  • 96
0

Insert the rectangles into a data structure where they are sorted by their bottom coordinate x1. Using e.g. a self-balancing binary search tree, this would have complexity O(N.LogN), and allow to traverse the tree in order in O(N), with N being the number of rectangles. In the example that would be:

[R1, R3, R2]

While inserting the rectangles into the tree, also keep a sorted list of all the unique bottom and top coordinates y1 and y2. In the example that would be:

[1, 3, 4, 5, 6, 7]  

Now we will treat each horizontal slice between two consecutive y-coordinates as a 1-dimensional problem (similar to the first method in this answer).

horizontal slices with 1-dimensional overlap counting

Iterate from the start of the rectangle tree over all the rectangles that fall in this slice (remember the rectangles are sorted by y1, so they are grouped together in the beginning), and make a sorted list of their unique x-coordinates, with a value for each to which you add 1 if it is the left coordinate, and subtract 1 when it is a right coordinate. If you encounter rectangles whose top coordinate equals the slice's top coordinate, remove them from the rectangle tree, which can be done in O(1). For the first slice in the example, with y=1~3 and height 2, that would be:

[1: +1, 5: -1]  

If we iterate over it, we find a zone of width 4 (and thus area 8) that is part of 1 rectangle.

For the second slice in the example, with y=3~4 and height 1, that would be:

[1: +1, 3: +1, 5: -1, 8, -1]  

If we iterate over it, we find a zone of width 2 (and thus area 2) that is part of 1 rectangle, a zone of width 2 (and thus area 2) that is part of 2 rectangles, and a zone of width 3 (and thus area 3) that is part of 1 rectangle. So any area that is part of k rectangles is added to a total. And so on.

Creating the rectangle tree is O(N.LogN), creating the slice list is O(N.LogN), iterating over the slices is O(N) and within each slice creating the sorted x-coordinate list is O(N.LogN), for a total of O(N2.LogN), independent of how large the rectangles are, how large the total area is, and how much overlap there is between rectangles or clusters of rectangles.