3

One critical piece of code on my application involves enumerating all rectangles on a 2-D surface. The rectangles do not intersect each other and I must be able to enumerate all rectangles within a given rectangular boundary.

I already have a function to return the rectangle for a given coordinate, if it exists

GetRectangle( int row, int col )

Here is how I would call the resulting code.

foreach( var rect in GetRectangles( row, col, rowCount, colCount ) ) {
   //..  my processing code here
}

Obviously, I could call the function GetRectangle() for each of the points in the surface. I can also skip the width of the rectangle that was returned from the previous call as I know that they do not intersect. But, this is still not efficient enough.

Are you aware of such an algorithm?

UPDATE: The surface is not necessarily covered by rectangles but it can be for some special cases. So, the function GetRectangle( int row, int col ) might return null.

Think of the surface as a bitmap filled with random rectangles (which don't intersect). The task is to return all rectangles on that surface that falls within (i.e. intersects) a given frame. Hope this will clarify the question.

Thanks

3
  • Can the rectangles be rotated? edit: Ok, this is already implicitly answered, sorry. Commented Mar 13, 2012 at 10:52
  • 2
    Hi Kemal, could you be a bit more descriptive? Perhaps provide a diagram of what you mean by enumerating all rectangles on a 2D surface? Commented Mar 13, 2012 at 10:52
  • Why can't you keep track of the rectangles as they are added to the surface? What am I missing? Commented Mar 13, 2012 at 17:19

1 Answer 1

3

For best results, organize your collection of rectangles into a spatial lookup structure. In this case it sounds as though a R-tree would be a good bet. But if you can't do that, and GetRectangle is all you've got, then here is what I'd do:

The plan is to maintain a list of integers xj for 0 ≤ j < rowCount, where xj is the leftmost point on row j for which I have not yet found a rectangle covering it.

  1. Start by initializing xj := 0 for all j.

  2. If xj = colCount for all j, we are done. Stop.

  3. Let J = min(j | xj = min(xi)). Then xJ is the topmost leftmost point that I have not yet found a rectangle that covers it.

  4. Call GetRectangle(xJ, J). If this does not return a rectangle, then the point is uncovered. Set xJ := xJ + 1 and go to step 2.

  5. Otherwise, we have a rectangle with top left corner at (xJ, J). Call its width w and height h. For Jj < J + h, set xj := xj + w. Go to step 2.

Here's an example run of this algorithm. The list of xj is shown by the numbers at the left, with the topmost leftmost highlighted in bold. The orange rectangle is the one that's discovered at that step of the algorithm.

The algorithm finds seven rectangles in seven steps

For efficient discovery of the minimum at step 3, you might want to keep the list of xj in a heap.

Sign up to request clarification or add additional context in comments.

1 Comment

Hi Gareth, I am afraid, your example run was not pasted into your answer correctly. Could you please re-do the paste. Thank you

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.