Retrieve set of rectangles containing a specified point - algorithm

I can't figure out how to implement this in a performing way, so I decided to ask you guys.
I have a list of rectangles - actually atm only squares, but I might have to migrate to rectangles later, so let's stick to them and keep it a bit more general - in a 2 dimensional space. Each rectangle is specified by two points, rectangles can overlap and I don't care all too much about setup time, because the rectangles are basicly static and there's some room for precalculate any setup stuff (like building trees, sorting, precalculating additional vectors, whatever etc). Oh I am developing in JavaScript if this is of any concern.
To my actual question: given a point, how do I get a set of all rectangles that include that point?
Linear approaches do not perform well enough. So I look for something that performs better than O(n). I read some stuff, like on Bounding Volume Hierarchies and similar things, but whatever I tried the fact that rectangles can overlap (and I actually want to get all of them, if the point lies within multiple rectangles) seems to always get into my way.
Are there any suggestions? Have I missed something obvious? Are BVH even applicable to possibly overlapping bounds? If so, how do I build such a possibly overlapping tree? If not, what else could I use? It is of no concern to me if borders are inside, outside or not determined.
If someone could come up with anything helpfull like a link or a rant on how stupid I am to use BVH and not Some_Super_Cool_Structure_Perfectly_Suited_For_My_Problem I'd really appreciate it!
Edit: Ok, I played around a bit with R-Trees and this is exactly what I was looking for. Infact I am currently using the RTree implementation http://stackulator.com/rtree/ as suggested by endy_c. It performs really well and fullfills my requirements entirely. Thanks alot for your support guys!

You could look at R-Trees
Java code
there's also a wiki, but can only post one link ;-)

You can divide the space into grid, and for each grid cell have a list of rectangles (or rectangle identifiers) that exist at least partially in that grid. Search for rectangles only in corresponding grid's cell. The complexity should be O(sqrt(n)).
Another approach is to maintain four sorted arrays of x1,y1,x2,y2 values, and binary search your point within those 4 arrays. The result of each search is a set of rectangle candidates, and the final result is intersection of those 4 sets. Depending on how set intersection is implemented this should be efficient than O(n).

Related

Need help merging some rectangles

Hi, I have this mess mess on the left, it's pretty much an array of rectangles with some holes (marked in red). I'm looking for a way to combine them in a way that I'll end up with as few rectangles as possible and preferably have most of them will be as close to squares as possible. Look at the image on the right, that's the kind of thing I'm trying to accomplish, just a bit prettier and preferably a bit more automatic.
I need this for a game and it won't be done at runtime so speed isn't really a concern (unless it's extremely slow, because I have to do it on a fairly large area) but I've never had to do something like this before and I honestly have no idea where to even start.
I already tried bruteforcing my way through the array, starting from the top-left square and kind of merging until there's nothing left to merge but it really isn't that efficient since it can't consider merging rectangles 3x2, 4x3, etc..
If you can point me to any algorithms that can handle this sort of thing or have an idea of how this could be accomplished it would be much appreciated. Thanks!
You can try a greedy algorithm. Of course it won't be optimal (well, you didn't define the optimality criterion strictly). But maybe it will perform good enough for your needs.
So you can try:
Find a pair of rectangles that can be merged with maximum total area
Replace them with the new one - the result of merge operation
Repeat until you cannot find a suitable pair
If you also care for resulting rectangles being close to square you can try to maximize something like a * totalArea + (1 - a) * (min_resulting_side/max_resulting_side) with a suitable value for 0 < a < 1.

How to simplify a spline?

I have an interesting algorithmic challenge in a project I am working on. I have a sorted list of coordinate points pointing at buildings on either side of a street that, sufficiently zoomed in, looks like this:
I would like to take this zigzag and smooth it out to linearize the underlying street.
I can think of a couple of solutions:
Calculate centroids using rolling averages of six or so points, and use those.
Spline regression.
Is there a better or best way to approach this problem? (I am using Python 3.5)
Based on your description and your comments, you are looking for a line simplification algorithms.
Ramer-Doublas algorithm (suggested in the comment) is most probably the most well-known algorithm in this family, but there are many more.
For example Visvalingam’s algorithm works by removing the point with the smallest change, which is calculated by the smallest square of the triangle. This makes it super easy to code and intuitively understandable. If it is hard to read research paper, you can read this easy article.
Other algorithms in this family are:
Opheim
Lang
Zhao
Read about them, understand what are they trying to minify and select the most suitable for you.
Dali's post correctly surmises that a line simplification algorithm is useful for this task. Before posting this question I actually examined a few such algorithms but wasn't quite comfortable with them because even though they resulted in the simplified geometry that I liked, they didn't directly address the issue I had of points being on either side of the feature and never in the middle.
Thus I used a two-step process:
I computed the centroids of the polyline by using a rolling average of the coordinates of the five surrounding points. This didn't help much with smoothing the function but it did mostly succeed in remapping them to the middle of the street.
I applied Visvalingam’s algorithm to the new polyline, with n=20 points specified (using this wonderful implementation).
The result wasn't quite perfect but it was good enough:
Thanks for the help everyone!

Algorithm improvement for tidy up

Suppose you have a rectangle surface and some round/rectangle objects (different size).
I want to write an algorithm that will tidy up those objects on the surface.
I have to put a maximum objects on the same surface.
I think i will have to put biggest objects first and smallest then.
Do you know if there is a specific algorithm in order to optimize this ?
It is a kind of tetris resolution but i can choose order of pieces.
Thanks
Since you want maximise the number of objects you are going to place, a greedy algorithm might work well in most of the cases:
Sort boxes according to length(ascending order).
Start from the smallest box:
for every box :
try to place it in a already occupied row
if not possible place it in a new row.
if not possible to place - break; //since anything bigger than would not fit.
If you are considering height also, this is called Packing Problem.
You can check related algorithms here
This is called the Knapsack problem
EDIT:
It's actually a subtype of the Knapsack problem: Bin Packing Problem

Algorithm similar to bin packing

I have been experimenting with bin packing algorithms for data visualizations, but none are quite doing what I want to accomplish. Essentially, I am trying to think of an algorithm to represent a set of numbers by a weighted grid. For example, given a set of numbers [25,25,25,25] you could represent this in a rectangle or square by like this-
However, given a set like this [10,1,1,1], it would look similar to this.
I am trying to wrap my head around this problem with non-even numbers, and it feels similar to bin packing, but in my case I don't necessarily care about the size of the child objects, I just care about them fitting inside the square or rectangle, and keeping their proportions to the other elements. Does this make sense? The problem seems similar to a the Android UI property weight..
I know it is probably simple, I am just not seeing the forest through the trees..
Treemapping is what I was looking for. Thanks Eugen!

Simple k-nearest-neighbor algorithm for euclidean data with variable density?

An elaboration on this question, but with more constraints.
The idea is the same, to find a simple, fast algorithm for k-nearest-neighbors in 2 euclidean dimensions. The bucketing grid seems to work nicely if you can find a grid size that will suitably partition your data. However, what if the data is not uniformly distributed, but has areas with both very high and very low density (for example, the US population), so that no fixed grid size could guarantee both enough neighbors and efficiency? Can this method still be salvaged?
If not, other suggestions would be helpful, though I hope for answers less complex than moving to kd-trees, etc.
If you don't have too many elements, just compare each with all the others. This can be a lot faster than you'd think; today's machines are fast. Unfortunately, the square factor will catch you sooner or later; I figure a linear search of a million objects won't take tooo long, so you may be okay with up to 1000 elements. Using a grid, or even stripes, might boost that number substantially.
But I think you're stuck with a quadtree (a specific form of k-d tree). Your whole map is one block, which can contain four subblocks (upper left, upper right, lower left, lower right). When a block fills up with more elements than you want to do a linear search on, break it into smaller ones and transfer the elements. (Only leaf nodes have elements.) It's easy to search within a given radius of a given point. Start at the top and if a part of a block is within range of the point, check out it's subblocks the same way if it has them. If it doesn't, check its elements.
(When searching for "closest", take care. The square grid means a nearer object might be in a farther block. You have to get everything within a given radius, then check 'em all. If you want the 10 closest and your radius of 20 only picked up 5, you need to try a larger radius. You may have a rejected item that proved to be 30 away and think you should grab it and a few others to make up your 10. However, there may be a few items at 25 away whose whole blocks were rejected, and you want them instead. There ought to be a better solution for this, but I haven't figured it out yet. I just make a guess at the radius and double it till I get enough.)
Quadtrees are fun. If you can set up your data and then access it, it's easy. The problems come when your mapped elements appear, disappear, and move while you are trying to figure out who's near what.
Have you looked at this?
http://www.cs.sunysb.edu/~algorith/major_section/1.4.shtml
kd-trees are quite simple to implement, there are standard java/c implementations.
Also:
You may want to post your question here:
https://cstheory.stackexchange.com/?as=1

Resources