I am projecting images on a Voronoi diagram. For each non-black pixel of the image, I find the corresponding polygon in the diagram and color it. (The site, to get an idea what I mean.) With a few hundred polygons, a brute force approach is feasible. With a few thousands, it's not.
My question: How can I efficiently search a number of polygons for the ones containing a point? I am interested in the general case, without making assumptions about the polygons distribution or size.
Two existing answers (that I found) relate:
Finding out if a point is inside a voronoi cell It elegantly leverages the fact that Voronoi polygons are convex. Hence, the polygon, whose center is nearest, must also be the containing polygon. Unfortunately, to determine the minimum, still all polygons are searched. That's what does not scale.
Finding the polygon in a 2D mesh which contains a point It mentions a 2d interval tree. (According to these slides on the topic it should be a segment tree.) One property of Voronoi diagrams, however, is that the polygons are non-overlapping, while segment trees don't make that assumption. Hence, if indeed these trees are the best option(?), is there an approach that includes this assumption, enabling it to be more efficient?
I am building this as JavaScript purely client-side, using D3, so I am interested in an algorithm, a library or a change of modeling. A spatial database such as MySQL or MongoDB, for example, does not help me.
What I tried so far: I built a sufficiently efficient index for exactly my use case that relies on assumptions I can make, see below.
The solution for my specific case is basically a hash of the polygons' center point.
Building the index:
When searching for the polygon that contains a given point:
This works, because I make a few assumptions:
So, while this works for exactly my use case, I would like to loosen some restrictions. This question is about discarding assumptions 1 and 3, if possible. (2 and 4 are given for a Voronoi diagram, as I understand it.)
If this is not purely geometrical problem then I would go for the lookup bitmap. Just paint all the polygons in a secondary bitmap (canvas) using integer ids for color. To find poly's id you just check the pixels color on the corresponding position. One position - one fetch. It should be ultra fast yet not geometrically perfect. Note that you can scale the lookup bitmap to increase accuracy.