Data structures for arranging rectangles¶
Say you were writing a program that would take a bunch of rectangles and try arranging them in different ways. (An example of where this is used is in designing computer chips.) How would you keep track of where each rectangle is, and when you move of one of them, how would you know where the others end up?
If you think about physically laying out blocks and moving them around, it doesn’t seem like a difficult problem. You can see where every block is, and physics keeps you from putting two blocks in the same space. If you model that directly in a program, figuring out which blocks to move where when a collision would occur takes a good bit of calculation. And when you’re iterating over lots of possible layouts, that’s not what you want. Maybe describing where the blocks are relative to each other could make things easier.
The O-tree¶
How could you describe this layout without giving the exact coordinates of any of the blocks? You could start by telling which blocks are furthest to the left. (Or furthest to any of the four sides, but conventionally the left is chosen.) So, at the very left of this layout, from bottom to top, there’s 3, then 6, then 8. That’s the first level of the tree. Any blocks immediately to the right of one of those is a child to that block, and so on. [1]
Now, this should be all you need to unambiguously describe this particular layout:
It looks a lot easier to manipulate than what we were imagining before, so let’s see if it works.
From O-tree to layout¶
If you gave the O-tree and list of block sizes to someone else, how could they accurately recreate your layout? First, they should know how to choose what block to place next: by a preorder traversal of the tree. [1]
Next, they should know where to place it. The first block should be put in the lower left corner. Any block’s child goes immediately to the right of it, and each branch of the tree builds a layer on top of the previous one.
This gives us an identical layout to what we started with! But the whole point of this was to make it easy to calculate, right? Let’s see how a program would do it.
The contour¶
Finding the x position of any block is easy: the root’s children are at the very left, and any block’s child is directly to its right. To find the y positions, we’ll keep a list of which blocks currently form the top layer. [1] Let’s build the list for the first three blocks, and see how to use it to find the next block’s height.
Since the new block is a child of 6 in the tree, let’s look at the block that currently comes after 6 in the list. It’s x range is from 0 to 3, and it has a height of 5. Since the new block’s x range goes past 3, let’s look at the next block in the list to see if it’s any taller. We see that the next block has a height of 3, and since our new block doesn’t go past it horizontally, our search is done. The tallest block the new one is going on top of has height 5. And since block 3 is completely covered now that we’ve placed the new one, we can remove it from the list.
Generating alternate layouts¶
Now that we know how to place blocks according to an O-tree, moving a block to see if it improves the layout is just a matter of moving its node to another position in the tree. [2]
The sequence pair¶
The question of how to represent a layout for rectangle packing is very well researched, and several methods have been devised. Some are more similar than others; one that’s quite different on the surface from the O-tree is called a sequence pair.
Todo
Illustration for generating alternate O-tree layouts
Write sequence pair section
The creators of this method [3] describe it rather differently than I’ve heard elsewhere? But it is the nature of these things that you can think of it one way and then later find out that some simpler way is equivalent.
Compare the representations–can a sequence pair ever be more efficient than an O-tree?
References