Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Algorithm to compute a Voronoi diagram on a sphere?

I'm looking for a simple (if exists) algorithm to find the Voronoi diagram for a set of points on the surface of a sphere. Source code would be great. I'm a Delphi man (yes, I know...), but I eat C-code too.

like image 949
stevenvh Avatar asked Feb 13 '09 13:02

stevenvh


People also ask

How do you calculate Voronoi diagram?

We start by joining each pair of vertices by a line. We then draw the perpendicular bisectors to each of these lines. These three bisectors must intersect, since any three points in the plane define a circle. We then remove the portions of each line beyond the intersection and the diagram is complete.

What is Voronoi method?

Voronoi is a method to make a partition of a plane into regions close to each of a given set of objects. Imagine we have a plane and there are some points on the plane, Voronoi's objective is to make regions where every region is closer to a particular point than the other points.

What is Voronoi diagram in Knn?

If you want the k nearest neighbors, there is something called an order-k Voronoi diagram that has a cell for each possible k nearest neighbors. But nobody uses those, for two reasons. First, the size of an order-k Voronoi diagram is O(k2n) in 2D, and worse in higher dimensions.

What is a spherical Voronoi diagram?

Spherical Voronoi Diagram CircumcirclesDelaunay triangulation A Voronoi diagramfor a set of seed points divides space into a number of regions. There is one region for each seed, consisting of all points closer to that seed than any other. In this case, the space is the surface of the globe (approximated as a sphere).

What is a Voronoi algorithm?

The simplest algorithm comes from the definition of a voronoi diagram: "The partitioning of a plane with n points into convex polygons such that each polygon contains exactly one generating point and every point in a given polygon is closer to its generating point than to any other. " definition from wolfram.

What is the most efficient way to construct a Voronoi diagram?

The most effecient algorithm to construct a voronoi diagram is Fortune's algorithm. It runs in O (n log n). Here is a link to his reference implementation in C. Personally I really like the python implementation by Bill Simons and Carson Farmer, since I found it easier to extend. Show activity on this post.

How do you find the farthest point in a Voronoi diagram?

Farthest-point Voronoi diagram. For a set of n points the ( n − 1) th -order Voronoi diagram is called a farthest-point Voronoi diagram. For a given set of points S = { p1 , p2 , ..., pn } the farthest-point Voronoi diagram divides the plane into cells in which the same point of P is the farthest point.


6 Answers

Update in July 2016:

Thanks to a number of volunteers (especially Nikolai Nowaczyk and I), there is now far more robust / correct code for handling Voronoi diagrams on the surface of a sphere in Python. This is officially available as scipy.spatial.SphericalVoronoi from version 0.18 of scipy onwards. There's a working example of usage and plotting in the official docs.

The algorithm follows quadratic time complexity. While loglinear is the theoretical optimum for Voronoi diagrams on the surfaces of spheres, this is currently the best we've been able to implement. If you'd like to find out more and help with the development effort there are some open issues related to improving the way Python handles spherical Voronoi diagrams and the related data structures:

  • Effort to improve the plotting of spherical polygons in matplotlib
  • Effort to improve the handling of spherical polygon surface area calculations in scipy

For further background on the theory / development / challenges related to this Python code and related computational geometry efforts you can also check out some talks from Nikolai and I:

  • Nikolai PyData London 2016 talk
  • Tyler PyData London 2015 talk
  • Tyler PyCon 2016 Computational Geometry tutorial

Original Answer:

I've actually recently written some open source Python code for Voronoi diagrams on the surface of a sphere: https://github.com/tylerjereddy/py_sphere_Voronoi

The usage, algorithm, and limitations are documented on readthedocs (http://py-sphere-voronoi.readthedocs.org/en/latest/voronoi_utility.html). There are some detailed examples there but I'll place one or two below as well. The module also handles the calculation of the Voronoi region surface areas, albeit with some numerical weaknesses in the current development version.

I haven't seen many well-documented open source implementations for spherical Voronoi diagrams, but there has been a bit of buzz about the JavaScript implementation on Jason Davies' website (http://www.jasondavies.com/maps/voronoi/). I don't think his code is open though. I also saw a blog post about using Python to deal with part of the problem (http://jellymatter.com/2014/01/29/voronoi-tessellation-on-the-surface-of-a-sphere-python-code/). Many of the primary literature sources cited in the above posts seemed very challenging to implement (I tried some of them) but maybe some people will find my implementation useful or even suggest ways to improve it.

Examples:

1) Produce a Voronoi diagram for a pseudo-random set of points on the unit sphere:

import matplotlib import matplotlib.pyplot as plt import matplotlib.colors as colors from mpl_toolkits.mplot3d import Axes3D from mpl_toolkits.mplot3d.art3d import Poly3DCollection import numpy as np import scipy as sp import voronoi_utility #pin down the pseudo random number generator (prng) object to avoid certain pathological generator sets prng = np.random.RandomState(117) #otherwise, would need to filter the random data to ensure Voronoi diagram is possible #produce 1000 random points on the unit sphere using the above seed random_coordinate_array = voronoi_utility.generate_random_array_spherical_generators(1000,1.0,prng) #produce the Voronoi diagram data voronoi_instance = voronoi_utility.Voronoi_Sphere_Surface(random_coordinate_array,1.0) dictionary_voronoi_polygon_vertices = voronoi_instance.voronoi_region_vertices_spherical_surface() #plot the Voronoi diagram fig = plt.figure() fig.set_size_inches(2,2) ax = fig.add_subplot(111, projection='3d') for generator_index, voronoi_region in dictionary_voronoi_polygon_vertices.iteritems():    random_color = colors.rgb2hex(sp.rand(3))    #fill in the Voronoi region (polygon) that contains the generator:    polygon = Poly3DCollection([voronoi_region],alpha=1.0)    polygon.set_color(random_color)    ax.add_collection3d(polygon) ax.set_xlim(-1,1);ax.set_ylim(-1,1);ax.set_zlim(-1,1); ax.set_xticks([-1,1]);ax.set_yticks([-1,1]);ax.set_zticks([-1,1]);  plt.tick_params(axis='both', which='major', labelsize=6) 

enter image description here

2) Calculate the surface areas of the Voronoi region polygons and verify that the reconstituted surface area is sensible:

import math dictionary_voronoi_polygon_surface_areas = voronoi_instance.voronoi_region_surface_areas_spherical_surface() theoretical_surface_area_unit_sphere = 4 * math.pi reconstituted_surface_area_Voronoi_regions = sum(dictionary_voronoi_polygon_surface_areas.itervalues()) percent_area_recovery = round((reconstituted_surface_area_Voronoi_regions / theoretical_surface_area_unit_sphere) * 100., 5) print percent_area_recovery 97.87551 #that seems reasonable for now 
like image 131
treddy Avatar answered Sep 18 '22 09:09

treddy


Here's a paper on spherical Voronoi diagrams.

Or if you grok Fortran (bleah!) there's this site.

Original link (dead): https://people.sc.fsu.edu/~jburkardt/f_src/sxyz_voronoi/sxyz_voronoi.html

like image 22
Jason S Avatar answered Sep 20 '22 09:09

Jason S


Notice that Delaunay triangulation on a sphere is just the convex hull. Thus you can compute the 3D convex hull (e.g. using CGAL) and take the dual.

like image 37
olivier Avatar answered Sep 19 '22 09:09

olivier


In short, try cssgrid from NCAR Graphics. I wrote a longer answer for a similar question at codereview.stackexchange.com.

like image 31
minopret Avatar answered Sep 20 '22 09:09

minopret


There is a paper from INRIA about the Delaunay Triangulation (DT) of points lying on a sphere: CAROLI, Manuel, et al. Robust and Efficient Delaunay triangulations of points on or close to a sphere. 2009. where they talk about an implementation in CGAL.

The paper refers to various available implementation of DT algorithms.

Quoting from the paper:

An easy and standard answer consists in computing the 3D convex hull of the points, which is notoriously equivalent.

for computing the convex hull the paper suggests:

  1. Hull, a program for convex hulls.
  2. Qhull.
  3. Three-dimensional convex hulls. in FORTRAN.Three-dimensional convex hulls.
  4. STRIPACK in FORTRAN.

The DT C++ class of CGAL has the method dual to get the Voronoi Diagram.

According to this post by Monique Teillaud (one of the author of the above mentioned paper) it seems to me that in November 2012 the implementation was not still ready.

like image 35
Alessandro Jacopson Avatar answered Sep 20 '22 09:09

Alessandro Jacopson


It's been a while since the question has been answered, but I've found two papers that implement Fortune's algorithm (efficiency O(N lg N), memory O(N)) over the surface of the sphere. Maybe a future viewer will find this information useful.

  • "Sweeping the Sphere" by Dinis and Mamede, published in the 2010 International Symposium on Voronoi Diagrams in Science and Engineering. Can be purchased at http://dx.doi.org/10.1109/ISVD.2010.32
  • "A Plane Sweep Algorithm for the Voronoi Tessellation of the Sphere" by Zheng et al. I'm not sure it was published because of the first one, but it is dated 13 December 2011. It is available for free at http://www.e-lc.org/tmp/Xiaoyu__Zheng_2011_12_05_14_35_11.pdf

I'm working through them myself at the moment, so I can't explain it well. The basic idea is that Fortune's algorithm works on the surface of the sphere so long as you calculate the points' bounding parabolas correctly. Because the surface of the sphere wraps, you can also use a circular list to contain the beach line and not worry about handling cells at the edge of rectangular space. With that, you can sweep from the north pole of the sphere to the south and back up again, skipping to sites that introduce new points to the beach line (adding a parabola to the beach line) or the introduction of cell vertices (removing a parabola from the beach line).

Both papers expect a high level of comfort with linear algebra to understand the concepts, and they both keep losing me at the point they start explaining the algorithm itself. Neither provide source code, unfortunately.

like image 31
sadakatsu Avatar answered Sep 21 '22 09:09

sadakatsu