Imagine a simple 2D grid; the objects on the grid can occupy more then one cell (but the points are always connected). Consider the following example, where I use letters A and B just to distinguish the objects (it is useful since the objects may be placed near each other):
0 1 2 3 4 5 6 7 8 9 10
1 . . . . . . . . . .
2 . . . . . . . . . .
3 . . . A . . . . . .
4 . . A A A . . B B .
5 . . . A . . . B B .
6 . . . . . . . . . .
I need an algorithm for the insertion of new objects that would position them on the grid and make sure they do not overlap. Thus, if I would like to embed a new object (denoted with C) and the coordinates of any of its cells would already be occupied, the algorithm should find the closest free region (i.e., list of points) to allocate the new object. Lets try to insert the object C at the coordinate (4, 3) which is already occupied by a cell from A:
0 1 2 3 4 5 6 7 8 9 10
1 . . . . . . . . . .
2 . C C . . . . . . .
3 . C C A . . . . . .
4 . . A A A . . B B .
5 . . . A . . . B B .
6 . . . . . . . . . .
As you can see, the object was moved to fit near the object A. I assume that the search should start around the occupied cell with the order (given in directions): N, E, S, W and after this in the middle directions: NE, SE, etc.
How would you suggest to implement this algorithm?
Update: The object position is the upper left point. And the closest point is obtained from the distance that is evaluated between the initial requested position and the surrounding free points.
You want to iterate over possible displacements (i.e. shifts) in order of increasing distance. As all displacements are integers, the squared displacements need to be sums of two squares. The following python code keeps track of the next possible y displacement for each x displacement. It generates lists of pairs. Each pair denotes displacement coordinates. All elements in a single list have the same distance from the origin, whereas elements from later lists will have greater distance. So it doesn’t matter in what order you traverse the inner lists, at least in terms of distances. You might even want to randomize those.
The first lines of output look like this:
For distances up to 400 (i.e. passing 400 as the
maxrargument), you’d get 502,625 lines for 37,556 different distances, so you want to generate these on the fly, not hard-code them into the application. You may however use these numbers to check your implementation, in case one of us made an error.If you are concerned about performance, you can use a priority queue instead of an array, and write it like this:
In this case, the queue contains individual displacements, and the result will print individual displacements of the same distance in arbitrary (and probably implementation-defined) order, without collecting them into a list. Only the mirror images of a given displacement will be printed immediately. The code here employs full 8-fold symmetry, so the number of elements stored in the queue at any single time is even less than the maximal distance generated so far, except at the very beginning.