I have points (e.g., lat, lon pairs of cell tower locations) and I need to get the polygon of the Voronoi cells they form.
from scipy.spatial import Voronoi
tower = [[ 24.686 , 46.7081],
[ 24.686 , 46.7081],
[ 24.686 , 46.7081]]
c = Voronoi(towers)
Now, I need to get the polygon boundaries in lat,lon coordinates for each cell (and what was the centroid this polygon surrounds). I need this Voronoi to be bounded as well. Meaning that the boundaries don't go to infinity, but rather within a bounding box.
Given a rectangular bounding box, my first idea was to define a kind of intersection operation between this bounding box and the Voronoï diagram produce by
scipy.spatial.Voronoi
. An idea not necessarily great, since this requires to code a large number of basic functions of computational geometry.However, here is the second idea (hack?) that came to my mind: the algorithms to compute the Voronoï diagram of a set of
n
points in the plane have a time complexity ofO(n ln(n))
. What about adding points to constraint the Voronoï cells of the initial points to lie in the bounding box?Solution for a bounded Voronoï diagram
A picture is worth a great speech:
What I did here? That's pretty simple! The initial points (in blue) lie in
[0.0, 1.0] x [0.0, 1.0]
. Then I get the points (in blue) on the left (i.e.[-1.0, 0.0] x [0.0, 1.0]
) by a reflection symmetry according tox = 0.0
(left edge of the bounding box). With reflection symmetries according tox = 1.0
,y = 0.0
andy = 1.0
(other edges of the bounding box), I get all the points (in blue) I need to do the job.Then I run
scipy.spatial.Voronoi
. The previous image depicts the resulting Voronoï diagram (I usescipy.spatial.voronoi_plot_2d
).What to do next? Just filter points, edges or faces according to the bounding box. And get the centroid of each face according to the well-known formula to compute centroid of polygon. Here is an image of the result (centroids are in red):
Some fun before showing code
Great! It seems to work. What if after one iteration I try to re-run the algorithm on the centroids (in red) rather than the initial points (in blue)? What if I try it again and again?
Step 2
Step 10
Step 25
Cool! Voronoï cells tend to minimize their energy...
Here is the code