I have set of rectangles of various sizes in 2D space. Number of rectangles may be changed dynamically from 10 to 100 000, their position, as well as their sizes are often updated.
Which spatial structure would you recommend to find rectangle at given point (x,y)? Assuming that search operation also performed very often (on mouse move for example). If you could give a reference to various spatial indexing algorithms comparison or compare their search/build/update performance here - that would be lovely.
I would suggest R-Tree. It is primarily designed for rectangles (or N-dimensional axis aligned cubes).
Use a quadtree (http://en.wikipedia.org/wiki/Quadtree).
Determine all possible X and Y values at which rectangles start and end. Then build a quadtree upon these values. In each leaf of the quadtree, store which rectangles overlap with the coordinate-ranges of the leaf. Finding which rectangles overlap is then just a matter of finding the leaf containing the coordinate.
Related
For a game I am writing, I am using a quadtree on a non-square map. The quadtree is used to look up neighboring units for collision detection, enemies to attack, nearest bases etc. within a given max. radius (circle).
What I wonder is, if there is a performance issue for having a quadtree made of rectangles rather than squares? Instead of dividing a square map into squares, a rectangular map is divided into rectangles of equal size in the quadtree.
Square Quadtree on Rectangular Map: a quadtree will be created filling the whole map but with empty/non used areas to the left or bottom depending on the orientation of the map (horizontal vs. vertical). This will require more squares for padding (?) and might have an impact on performance also during search?
Rectangular Quadtree matching the Rectangular Map: the quadtree will perfectly fill the map. However, will performance be impacted doing so? Given we search is using a radius which will fit into a square rather than a rectangle, it might result in slower searches? Also, both width & height have to be stored in each quadtree node as they are non-square.
Question:
Is it better to covert the quadtree to square form? I think using a rectangular squadtree might be OK but I am not sure?
Screenshot (Rectangular Quadtree):
I'm sure both options are okay. From you example it also look like your data set is rather small, only a few dozen entries, maybe 100?
Some things to consider:
As you mentioned: Rectangles require separate 'length' for x and y. The effect may be small but every additional bit of information slows down the structure because more data has to be move to and through the CPU.
If you are storing objects in the quadtree that are (often) directly on rectangle borders, you need to be careful to implement the quadtree correctly:
Insertion: Inserting an item on the corner of four quadtrants, in which does it get inserted?
Queries/lookup: Inverse to insertion, any search that ends on the border may (unnecessarily, search all bordering qaudrants, which can be expensive.
In summary, the question is probably less about square/rectangular quadtrees but one should be careful when data is often on the quadrant borders.
For example we have two rectangles and they overlap. I want to get the exact range of the union of them. What is a good way to compute this?
These are the two overlapping rectangles. Suppose the cords of vertices are all known:
How can I compute the cords of the vertices of their union polygon? And what if I have more than two rectangles?
There exists a Line Sweep Algorithm to calculate area of union of n rectangles. Refer the link for details of the algorithm.
As said in article, there exist a boolean array implementation in O(N^2) time. Using the right data structure (balanced binary search tree), it can be reduced to O(NlogN) time.
Above algorithm can be extended to determine vertices as well.
Details:
Modify the event handling as follows:
When you add/remove the edge to the active set, note the starting point and ending point of the edge. If any point lies inside the already existing active set, then it doesn't constitute a vertex, otherwise it does.
This way you are able to find all the vertices of resultant polygon.
Note that above method can be extended to general polygon but it is more involved.
For a relatively simple and reliable way, you can work as follows:
sort all abscissas (of the vertical sides) and ordinates (of the horizontal sides) independently, and discard any duplicate.
this establishes mappings between the coordinates and integer indexes.
create a binary image of size NxN, filled with black.
for every rectangle, fill the image in white between the corresponding indexes.
then scan the image to find the corners, by contour tracing, and revert to the original coordinates.
This process isn't efficient as it takes time proportional to N² plus the sum of the (logical) areas of the rectangles, but it can be useful for a moderate amount of rectangles. It easily deals with coincidences.
In the case of two rectangles, there aren't so many different configurations possible and you can precompute all vertex sequences for the possible configuration (a small subset of the 2^9 possible images).
There is no need to explicitly create the image, just associate vertex sequences to the possible permutations of the input X and Y.
Look into binary space partitioning (BSP).
https://en.wikipedia.org/wiki/Binary_space_partitioning
If you had just two rectangles then a bit of hacking could yield some result, but for finding intersections and unions of multiple polygons you'll want to implement BSP.
Chapter 13 of Geometric Tools for Computer Graphics by Schneider and Eberly covers BSP. Be sure to download the errata for the book!
Eberly, one of the co-authors, has a wonderful website with PDFs and code samples for individual topics:
https://www.geometrictools.com/
http://www.geometrictools.com/Books/Books.html
Personally I believe this problem should be solved just as all other geometry problems are solved in engineering programs/languages, meshing.
So first convert your vertices into rectangular grids of fixed size, using for example:
MatLab meshgrid
Then go through all of your grid elements and remove any with duplicate edge elements. Now sum the number of remaining meshes and times it by the area of the mesh you have chosen.
I have an area which was already partitioned into tens of sub-areas (think like a country divided into states).
Now I have a point coordinate, what is the best algorithm to tell me which state the point in?
Of course I can match sub-area by sub-area but that's stupid because I have to search through half of them in average right?
Is there an algorithm to determine how to group several adjacent sub-area together to facilitate search, so as to optimize the number of search?
I would start by eliminating all areas that cannot have the point inside of them.
Let's assume that you have a 2D Cartesian coordinate system, you have a point as a 2D-vector and the areas are described as a collection of their boundary points.
Then you can sort the areas by their smallest and largest x and y coordinate (in total 4 ways of sorting). You can eliminate all areas which have their smallest x coordinate bigger than the x coordinate of your point etc.
After that, you can check the remaining polygons with a simple ray-casting algorithm and you should be good.
This is very efficient if you have a structure which keeps the areas sorted in all the different directions because you can eliminate the areas in logarithmic time.
I have a binary blob (see image), and I want to fit a rectangle of known width and height over it.
How can I find the optimal fitting rectangle, i.e. the one where the maximum of foreground pixels are inside and the maximum amount of background pixels are outside?
(This is my preliminary definition of best-fit, I am open to other suggestions)
I am looking for rectangles of a known size, but if there is a solution for arbitrary sizes, that would be great too.
Example blobs:
I want to find these rectangles:
My ideas so far included
start with the minimum enclosing rectangle; but that is not a good match for these blobs
maximum enclosed rectangle; same problem, plus I do not have an algorithm for that
find rectangle sides with hough transform; the data is too noisy for that.
I realize that there could be multiple rectangles for the same blob that fit my criteria, ideally I would want some algorithm that can find all candidates (thought since that is probably harder, I'd be happy with a way to find only one candidate):
I am using mostly opencv and cvBlobLib to process my data, but I am open for any general solution.
I have seen a thesis on a similar subject (circle covering on a RGB plane), based on an evolutionary approach.
The objective function was clearly defined (How many squares? How big?
Can they overlap? You'd probably want to penalize small or
overlapping squares).
You may start by running the k-means
algorithm to preprocess the data, i.e. find potential center points of the squares.
As I recall, SGA, CGA and eCGA were compared (CGA started with initial, k-means-based covering), with SGA outperforming the others. They were ran on a per-image basis. There were around 30 individuals and 20 generations with runtimes around a couple of minutes.
As for the SGA, the crossover operator would take two parents at a time and pair up the closes/most similar circles from both of the parents. Then, for each pair, it would draw a children circle somewhere in between with a radius also in between that of the two circles'. (Though I would suggest not to take values exactly between those of the parents', but allow +/- 15% outside the range. It would keep the population from the premature convergence).
With rectangles, you'd have to slightly modify the approach; each rectangle could be a tuple (x, y, width, height, rotation), with x and y being the coordinates of the center.
I was wondering if there is a good data structure to hold a list of axis-aligned non overlapping discrete space rectangles. Thus each rectangle could be stored as the integers x, y, width, and height. It would be easy to just store such a list but I also want to be able to query if a given x,y coordinate is inside any other rectangle.
One easy solution would be to create a hash and fill it with the hashed lower left coordinates of the start of each rectangle. This would not allow me to test a given x,y coordinate because it would hit an empty space in the middle. Another answer is to create a bunch of edges into the hash table that cover the entire rectangle with unit squares. This would create too many needless entries for a rectangle of say 100 by 100.
R-Tree is the can be used. R-trees are tree data structures used for spatial access methods, i.e., for indexing multi-dimensional information such as geographical coordinates, rectangles or polygons. The information of all rectangles can be stored in tree form so searching will be easy
Wikipedia page, short ppt and the research paper will help you understand the concept.