I'll do my best to make my case scenario simple.
1-) Let's suppose we need to stores a lot of rectangles in some kind of array/data structure. Each rectangle are of different sizes and are positioned at various parts of the screen. Rectangles can't overlap together.
2-) Then we click on the screen with the mouse at point [x,y].
Now, we need to determine if we clicked on a part of one of the rectangles. Well, that would be insane to iterate through all the rectangles to make some kind of comparisons, especially if there is a huge number of them.
What would be the fastest technique/algorithm to do it with as little steps as possible? What would be the best data structure to use in such case?
One way would be to use a quadtree to store the rectangles: The root represents the whole area that contains all rectangles, and this area is then recursively subdivided as required.
If you want to test if a certain coordinate is within one of the rectangles, you start at the root, and walk down the tree until either you find a rectangle or not.
This can be done in O(log n) time.
Related
So I have n objects that can be dragged on a stage and I want them to snap (lock, magnet...) to each other when you drag them close enough. That means calculating the distance from dragged object to every other object on the stage on every mouse move event. Can this be optimized? Something like comparing the distance only to the closes objects but how do I know which are the closes without calculating all distances first?
Thanks
You can use a k-d tree. K-d tree has an efficient "find closest neighbor" function. Just make sure each object which is already 'in place' is in your tree, and when you move an element - find its closest neighbor, and check if it is close enough or not.
An alternative (mostly usable for grids) is using observer pattern. Whenever you place an object - draw the line where its 'influence' starts. Attach each 'cell' on this line with an observer, and when you are moving an object to a cell, if it has any observers attached to it - invoke them.
Two ideas:
You could divide your stage into 'tiles' of some size (say, 64x64 pixels?). If you knew which tiles would overlap (partially or completely) a given tile, you could limit your hit detection to those.
You could maintain a (sorted!) map which maps a given 'y' coordinate to all the object(s) on that 'y' position. Each list of objects at the y coordinate is sorted as well, giving the objects sorted by their X order. By using the lower/upper bound (which is efficient to compute on sorted sequences) you could quickly get handles to all objects within a certain bounding rect.
On classical solution to this kind of problems is to cut the space recursively into areas. You only search neigboors in close areas. A classical data structure for this is QuadTree where square are cut into four squares.
I have a collection of different sized rectangles that need to be placed on a 2D surface of a known dimension, with the condition that:
there is no overlap between the blocks,
the rectangles may not be rotated,
there is no area left blank (whole surface needs to be filled).
The rectangles are actually generated by breaking down the surface area, so they ought to fill up the area completely once you start putting everything together.
I figured there would be a dozen algorithms available for this problem, but the algorithms I find are more like best effort algorithms such as sprite generators that do not have the precondition that the whole area needs to be (can be...) filled -- which obviously is not necessary when building sprites, however, it is in my case.
I am a bit lost here, either this problem isn't as simple as I thought, or I am searching on wrong keywords.
Some topics I have found but do not fully suit my needs:
What algorithm can be used for packing rectangles of different sizes into the smallest rectangle possible in a fairly optimal way? (in my case, the area is preset)
How to arrange N rectangles to cover minimum area (in my case, minimum area must equal zero)
Is there any algorithm out there that may suit my needs?
IMHO, the most natural solution is recursive. For the form of source area is not set. And after removing a rectangle from it, we have the same task, only with smaller area and -1 rectangle.
I would start from the edges, because there the possible variants are already limited. So, simply go by spiral, trying to put rectangles along the edge. If no rectangle fits, go back. That will be the simplest and not so slow raw force method.
I am looking for a sound algorithm that would randomly place a given number of rectangles of the same size into a bigger rectangle (canvas).
I see two ways to do it:
create an empty array that will contain the rectangles already placed on canvas. start with the empty canvas. in a loop, pick a position at random for a new rectangle to be placed. check if the array has a rectangle that overlaps with the new rectangle. if it does not, put the new rectangle in to the array and repeat the loop. otherwise, pick a new position, and rerun the check again. and so on. This might never terminate (theoretically) I think. I do not like it.
use a grid and place rectangles into the cells randomly. This might still look like a grid placement. I do not like it either.
any better ways to do it? "better" meaning more efficient, or more visually "random" than the grid approach. better in any respect.
Here is a simple heuristic. It will be non-overlapping and random.
Place a rectangle randomly. Then, calculate the intersections of extensions of the the two parallel edges of the first rectangle with the edges of the canvas. You will obtain four convex empty regions. Place other rectangles in these empty regions one-by-one independently and calculate the similar divisions for placements. And try to put the remaining rectangles in empty regions.
You can try different strategies. You can try to place the rectangles close to the corners. Or, you can place them around the center of the regions. We cannot discuss optimality because you introduced randomness.
You might find Quadtrees or R-trees useful for your purpose.
I create internal room-like dungeons using the following method.
1) Scatter N points at random, but not within a few pixels of each other.
2) For each point in turn, expand if possible in all four directions. Cease
expanding if you hit another rectangle.
3) Cease the algorithm when no rooms can expand.
The result is N rectancles with just a few rectangular small spaces.
Code is in the binary image library
https://github.com/MalcolmMcLean/binaryimagelibrary/blob/master/dungeongenerator3.c
#
For a 2D game I am working on, I am using y axis sorting in a simple rectangle-based collision detection. This is working fine, and now I want to find the nearest empty rectangle at a given location with a given size, efficiently. How can I do this? Is there an algorithm?
I could think of a simple brute force grid test (with each grid the size of the empty space we're looking for) but obviously this is slow and not even a complete test.
Consider using quad-trees to store your rectangles.
See http://en.wikipedia.org/wiki/Quadtree for more information.
If you're already using axis sorting, then presumably you've computed a list of your rectangles sorted by their positions.
Perhaps I am misunderstanding, but could you not just look at the two rectangles before and after the rectangle in question, and decide which one is closer? If you're talking about finding the closest rectangle to an arbitrary point, then you could simply walk through the list until you find the first rectangle with a greater position than your arbitrary point, and use that rectangle and the one before it as the two to compare.
I'm looking for a data structure that provides indexing for Rectangles. I need the insert algorithm to be as fast as possible since the rectangles will be moving around the screen (think of dragging a rectangle with your mouse to a new position).
I've looked into R-Trees, R+Trees, kD-Trees, Quad-Trees and B-Trees but from my understanding insert's are usually slow. I'd prefer to have inserts at sub-linear time complexity so maybe someone can prove me wrong about either of the listed data structures.
I should be able to query the data structure for what rectangles are at point(x, y) or what rectangles intersect rectangle(x, y, width, height).
EDIT: The reason I want insert so fast is because if you think of a rectangle being moved around the screen, they're going to have to be removed and then re-inserted.
Thanks!
I'd use a multiscale grid approach (equivalent to quad-trees in some form).
I'm assuming you're using integer coordinates (i.e. pixels) and have plenty of space to hold all the pixels.
Have an array of lists of rectangles, one for each pixel. Then, bin two-by-two and do it again. And again, and again, and again, until you have one pixel that covers everything.
Now, the key is that you insert your rectangles at the level that is a good match for the size of the rectangle. This will be something like (pixel size) ~= min(height,width)/2. Now for each rectangle you have only a handful of inserts to do into the lists (you could bound it above by a constant, e.g. pick something that has between 4 and 16 pixels).
If you want to seek for all rectangles at x,y you look in the list of the smallest pixel, and then in the list of the 2x2 binned pixel that contains it, and then in the 4x4 etc.; you should have log2(# of pixels) steps to look through. (For larger pixels, you then have to check whether (x,y) was really in the rectangle; you expect about half of them to be successful on borders, and all of them to be successful inside the rectangle, so you'd expect no worse than 2x more work than if you looked up the pixel directly.)
Now, what about insert? That's very inexpensive--O(1) to stick yourself on the front of a list.
What about delete? That's more expensive; you have to look through and heal each list for each pixel you're entered in. That's approximately O(n) in the number of rectangles overlapping at that position in space and of approximately the same size. If you have really large numbers of rectangles, then you should use some other data structure to hold them (hash set, RB tree, etc.).
(Note that if your smallest rectangle must be larger than a pixel, you don't need to actually form the multiscale structure all the way to the pixel level; just go down until the smallest rectangle won't get hopelessly lost inside your binned pixel.)
The data structures you mention are quite a mixed bag: in particular B-Trees should be fast (cost to insert grows with the logarithm of the number of items present) but won't speed up your intersection queries.
Ignoring that - and hoping for the best - the spatial data structures come in two parts. The first part tells you how to build a tree structure from the data. The second part tells you how to keep track of information at each node that describes the items stored below that node, and how to use it to speed up queries.
You can usually pinch the ideas about keeping track of information at each node without using the (expensive) ideas about exactly how the tree should be built. For instance, you could create a key for each rectangle by bit-interleaving the co-ordinates of its points and then use a perfectly ordinary tree structure (such as a B-tree or an AVL tree or a Red-Black tree) to store it, while still keeping information at each node. This might, in practice, speed up your queries enough - although you wouldn't be able to tell that until you implemented and tested it on real data. The purpose of the tree-building instructions in most schemes is to provide performance guarantees.
Two postscripts:
1) I like Patricia trees for this - they are reasonably easy to implement, and adding or deleting entries does not disturb the tree structure much, so you won't have too much work to do updating information stored at nodes.
2) Last time I looked at a window system, it didn't bother about any of this clever stuff at all - it just kept a linear list of items and searched all the way through it when it needed to: that was fast enough.
This is perhaps an extended comment rather than an answer.
I'm a bit puzzled about what you really want. I could guess that you want a data structure to support quick answers to questions such as 'Given the ID of a rectangle, return its current coordinates'. Is that right ?
Or do you want to answer 'what rectangle is at position (x,y)' ? In that case an array with dimensions matching the height and width of your display might suffice, with each element in the array being a (presumably short) list of the rectangles on that pixel.
But then you state that you need an insert algorithm to be as fast as possible to cope with rectangles moving constantly. If you had only, say, 10 rectangles on screen, you could simply have a 10-element array containing the coordinates of each of the rectangles. Updating their positions would not then require any inserts into the data structure.
How many rectangles ? How quickly are they created ? and destroyed ? How do you want to cope with overlaps ? Is a rectangle just a boundary, or does it include the interior ?