Equalize sizes of quadtree cells - data-structures

A graphically represented quadtree is a tessellation of a square using differently sized smaller squares. Is there a transformation that deforms the quadtree cells to achieve following 2 contrasting goals?
equalize the cell sizes by deforming them (cell size is measured by area)
close cells in the original quadtree shall be close cells in the transformed result
The final result would be a deformed quadtree where all cell sizes are as similiar in area as possible while neighborhood relationship is maintained as good as possible. In ideal case one could weigh what is more important, equal area or neighborhood.
Motivation
I have a 2d point cloud. To each point a value is associated. Geometrically close points have similar values but the gradient varies over the region. There are regions where the point values are quite constant and there are regions where the values of the points differ more with distance. The quadtree groups points of similar values, i.e. the degree of subdivision is high where the values of near points show large fluctuations. However this splitting of the original square results by definition in differently sized cells. For further processing each cell shall be represented with equal size (=equal area). So I want to shrink larger cells and expand smaller cells and keep the neighborhood relationship. This is of course not possible without loosing some other properties. So one way would be to bend the plane in the 3rd dimension or to accept compromisses, i.e. cells are more equal sized than before and some neighborhood relationships are lost. I am looking for such a solution that deals with compromisses.
Centroidal Voronoi tessellation is not applicable. It leads to equally sized cells but doesn't care about neighborhood.

Related

Dividing the plane into regions of equal mass based on a density function

Given a "density" scalar field in the plane, how can I divide the plane into nice (low moment of inertia) regions so that each region contains a similar amount of "mass"?
That's not the best description of what my actual problem is, but it's the most concise phrasing I could think of.
I have a large map of a fictional world for use in a game. I have a pretty good idea of approximately how far one could walk in a day from any given point on this map, and this varies greatly based on the terrain etc. I would like to represent this information by dividing the map into regions, so that one day of walking could take you from any region to any of its neighboring regions. It doesn't have to be perfect, but it should be significantly better than simply dividing the map into a hexagonal grid (which is what many games do).
I had the idea that I could create a gray-scale image with the same dimensions as the map, where each pixel's color value represents how quickly one can travel through the pixel in the same place on the map. Well-maintained roads would be encoded as white pixels, and insurmountable cliffs would be encoded as black, or something like that.
My question is this: does anyone have an idea of how to use such a gray-scale image (the "density" scalar field) to generate my "grid" from the previous paragraph (regions of similar "mass")?
I've thought about using the gray-scale image as a discrete probability distribution, from which I can generate a bunch of coordinates, and then use some sort of clustering algorithm to create the regions, but a) the clustering algorithms would have to create clusters of a similar size, I think, for that idea to work, which I don't think they usually do, and b) I barely have any idea if any of that even makes sense, as I'm way out of my comfort zone here.
Sorry if this doesn't belong here, my idea has always been to solve it programatically somehow, so this seemed the most sensible place to ask.
UPDATE: Just thought I'd share the results I've gotten so far, trying out the second approach suggested by #samgak - recursively subdividing regions into boxes of similar mass, finding the center of mass of each region, and creating a voronoi diagram from those.
I'll keep tweaking, and maybe try to find a way to make it less grid-like (like in the upper right corner), but this worked way better than I expected!
Building upon #samgak's solution, if you don't want the grid-like structure, you can just add a small random perturbation to your centers. You can see below for example the difference I obtain:
without perturbation
adding some random perturbation
A couple of rough ideas:
You might be able to repurpose a color-quantization algorithm, which partitions color-space into regions with roughly the same number of pixels in them. You would have to do some kind of funny mapping where the darker the pixel in your map, the greater the number of pixels of a color corresponding to that pixel's location you create in a temporary image. Then you quantize that image into x number of colors and use their color values as co-ordinates for the centers of the regions in your map, and you could then create a voronoi diagram from these points to define your region boundaries.
Another approach (which is similar to how some color quantization algorithms work under the hood anyway) could be to recursively subdivide regions of your map into axis-aligned boxes by taking each rectangular region and choosing the optimal splitting line (x or y) and position to create 2 smaller rectangles of similar "mass". You would end up with a power of 2 count of rectangular regions, and you could get rid of the blockiness by taking the centre of mass of each rectangle (not simply the center of the bounding box) and creating a voronoi diagram from all the centre-points. This isn't guaranteed to create regions of exactly equal mass, but they should be roughly equal. The algorithm could be improved by allowing recursive splitting along lines of arbitrary orientation (or maybe a finite number of 8, 16, 32 etc possible orientations) but of course that makes it more complicated.

Quadtree Performance: Square vs. Rectangular?

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.

Match housenumbers on buildings (special case of point-in-polygon-test)

Task with example
I'm working with geodata (country-size) from openstreetmap. Buildings are often polygons without housenumbers and a single point with the housenumber is placed within the polygon of the building. Buildings may have multiple housenumbers.
I want to match the housenumbers to the polygons of the buildings.
Simple solution
Foreach housenumber perform a point-in-polygon-test with each building-polygon.
Problem
Way too slow for about 50,000,000 buildings and 10,000,000 address-points.
Idea
Build and index for the building-polygons to accelerate the search for the surrounding polygon for each housenumber-point.
Question
What index or strategy would you recommend for this polygon-structure? The polygons never overlap and the area is sparsly covered.
This question is duplicated to gis.stackexchange.com. It was recommendet to post the question there.
Since it sounds like you have well-formed polygons to test against, I'd use a spatial hash with a AABB check, and then finally the full point-in-polygon test. Hopefully at that point you'll be averaging three or less point-in-polygon tests per address.
Break the area your data is over into a simple grid where a grid is a small multiple (2 to 4) of the median building size. (Maybe 100-200 meters?)
Compute the axis aligned bounding box of every polygon, add it (with its bounding box) to each grid location which the bounding box intersects. (It's pretty simple to figure out where an axis aligned bounding box overlaps regular axis aligned grid cells. I wouldn't store the grid in a simple 2D array -- I'd use a hash table that maps 2D integer grid coordinates, e.g. (1023, 301), to a list of polygons)
Then go through all your address points. Look up in your hash table what cell that point is in. Go through all the polygons in that cell and if the point is within any polygon's axis aligned bounding box do the full point-in-polygon test.
This has several advantages:
The data structures are simple -- no fancy libraries needed (other than handling polygons). With C++, your polygon library, and the std namespace this could be implemented in less than an hour.
Spatial structure isn't hierarchical -- when you're looking up the points you only have to do one O(1) lookup in the hash table.
And of course, the usual disadvantage of grids as a spatial structure:
Doesn't handle wildly varying sized polygons particularly well. However, I'm hoping since you're using map data the sizes are almost always within an order of magnitude, and probably much less.
Assuming you end up with N maximum polygons in each of grid and each polygon has P points and you've got B buildings and A addresses, you're looking at O(B*P + N*A). Since B and P are likely relatively small, especially on average, you could consider this O(B + N) -- pretty much linear.

Find rectangle in 2d space

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.

Algorithm to fit fewest rectangles to irregular shape

I have a rendering application that renders lots and lots of cubes in a 3-dimensional grid. This is inherently inefficient as each cube represents 4 vertices, and often the cubes are adjacent, creating one surface that could be represented by a single rectangle.
To populate the area I use a 3-dimensional array, where a value of 0 denotes empty space and a non-0 value denotes a block.
e.g. (where X denotes where a cube would be placed)
OOOXXXOOOO
OOXXXXXXXO
OOXXXXXXXO
OOXXXXOOOO
would currently be represented as 21 cubes, or 252 triangles, whereas it could easily be represented as (where each letter denotes a part of a rectangle)
OOOAAAOOOO
OOBAAACCCO
OOBAAACCCO
OOBAAAOOOO
which is a mere 3 rectangles, or 26 triangles.
The typical size of these grids is 128x128x128, so it's clear I would benefit from a massive performance boost if I could efficiently reduce the shapes to the fewest rectangles possible in a reasonable amount of time, but I'm stuck for ideas for an algorithm.
Using Dynamic programming - Largest square block would be one option, but it wouldn't result in an optimal answer, although if the solution is too complex to perform efficiently then this would have to be the way to go.
Eventually I will have multiple types of cubes (e.g. green, brown, blue, referenced using different non-0 numbers in the array) so if possible a version that would work with multiple categories would be very helpful.
Maybe something "octree" like:
Build a 64x64x64 grid over your 128x128x128 grid so each cell of the first grid "contains" height cells of the second.
For each cell, of the 64x64x64 grid, proceed like that:
If the height contained cells have the same value, put that value in the 64x64x64 grid.
Else draw each cell individually and put -1 in the 64x64x64 grid.
Now build a 32x32x32 grid over the 64x64x64 one and repeat.
Then 16x16x16, 8x8x8, 4x4x4, 2x2x2, 1x1x1 and you're done :)
Of course, it would be best if the octree was computed once and for all, not for each rendering operation.

Resources