Algorithm to compute a Voronoi diagram on a sphere?
Asked Answered
T

11

40

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.

Trevino answered 13/2, 2009 at 13:14 Comment(0)
S
12

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

Selfcontradiction answered 13/2, 2009 at 13:34 Comment(4)
For me, there's a download link for the paper here: citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.19.6737 - it is not that helpful though...Compress
There is a great paper from 2011 describing a plane sweep algorithm (based on Fortune's algorithm for the plane): e-lc.org/tmp/Xiaoyu__Zheng_2011_12_05_14_35_11.pdfChingchinghai
The Fortran page doesn't load, nor does it on WayBack Machine. Does anyone know where I can find this content?Shifra
@ThomasHodges: I followed a similar path and it appears that the author updated his website, which broke the original link. Looking on his updated site, it appears that this link: people.sc.fsu.edu/~jburkardt/f_src/sphere_voronoi/… is the new one. I've updated the link in the post. I hope this helps (although it's over a year late)!Rapscallion
D
26

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:

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:


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
Directorial answered 27/11, 2014 at 12:29 Comment(6)
It seems to me that your Voronoi_Sphere_Surface accepts points expressed in a three dimensional Cartesian coordinate system, am I right? Maybe accepting points expressed in spherical coordinate (just longitude and latitude) could make your code easier to use in case of points that are geographical locations.Kelcy
I suppose I could add a flag to allow spherical coordinates. To be fair, my voronoi_utility module does already provide the function convert_spherical_array_to_cartesian_array(), which could be used easily enough prior to running the Voronoi code.Directorial
In most projections the earth is not a sphere but an ellipsoid. Any thoughts on that?Contractual
@RutgerHofste True, and even if we assume a perfect sphere it is a challenging problem; I know there are some efforts in the GIS world to handle the ellipsoid in various ways but my focus was just to see if we can get things to work on a sphere well initially.Directorial
Is there already a C++ port for this?Chaparajos
@Chaparajos Not sure, but certainly the algorithm in SciPy has been improving over the years. It is certainly not pure Python--many sections are abstracted to Cython for compilation, or offloaded to linear algebra libraries, etc.Directorial
S
12

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

Selfcontradiction answered 13/2, 2009 at 13:34 Comment(4)
For me, there's a download link for the paper here: citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.19.6737 - it is not that helpful though...Compress
There is a great paper from 2011 describing a plane sweep algorithm (based on Fortune's algorithm for the plane): e-lc.org/tmp/Xiaoyu__Zheng_2011_12_05_14_35_11.pdfChingchinghai
The Fortran page doesn't load, nor does it on WayBack Machine. Does anyone know where I can find this content?Shifra
@ThomasHodges: I followed a similar path and it appears that the author updated his website, which broke the original link. Looking on his updated site, it appears that this link: people.sc.fsu.edu/~jburkardt/f_src/sphere_voronoi/… is the new one. I've updated the link in the post. I hope this helps (although it's over a year late)!Rapscallion
N
8

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.

Nonparticipation answered 20/12, 2012 at 10:32 Comment(1)
concerning special sphere package, it is not yet ready. Hopefully in CGAL 4.3Nonparticipation
P
3

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

Part answered 19/3, 2012 at 5:32 Comment(0)
K
3

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.

Kelcy answered 20/6, 2013 at 20:25 Comment(0)
T
3

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.

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.

Telespectroscope answered 23/9, 2013 at 0:50 Comment(0)
D
2

I think the Voronoi plane for each point can be constructed using non-Euclidian geometry. What was normally a line on a 2d plane, is now a 'great circle' on the sphere (see Wikipedia:elliptic geometry). It is easy to find which points are on the wrong side of any great circle between two points, by simply rotating the sphere such that the dividing great circle is the equator, and then it's all points on the other hemisphere than the point you're constructing the Voronoi plane for.

This is not the entire answer, but this is where I'd start..

Decrement answered 23/6, 2009 at 21:4 Comment(0)
C
1

There's a nice Voronoi diagram example program here (including source code for Delphi 5/6).

I think "points on the surface of a sphere" means that you first have to remap them to 2D-coordinates, create the Voronoi diagram and then remap them to sphere surface coordinates. Are the two formulas from Wikipedia UV mapping article working here?

Also notice that the Voronoi diagram will have the wrong topology (it is inside a rectangle and does not "wrap around"), here it could help to copy all the points from (0,0)-(x, y) to the neighbour regions above (0, -y * 2)-(x, 0), below (0, y)-(x, y * 2), left (-x, 0)-(0, y) and right (x, 0)-(x*2, y). I hope you know what I mean, feel free to ask :)

Compress answered 13/2, 2009 at 13:20 Comment(3)
I thought about remapping to a 2D plane but that doesn't work; AFAIK there's no sphere-to-plane mapping which preserves distance. Simple example: distances between any pair of vertices a regular tetrahedron are the same, but you can't draw this in a 2D plane. Thanks for your reply anyway.Trevino
@stevenvh: The Delaunay triangulation seems to work as is after mapping the sphere to a plane (with eg polar projection: great circles go to circles, and being inside circumscribed circle will work equally for spherical and planar triangles). Then you go back to the sphere and dualize the graph. This would probably work.Overlong
@stevenh: Technically you don't have to preserve distances, you just have preserve the ordering of all distances. Of course, I don't think even this is possible.Tebet
P
1

CGAL is working on the "spherical kernel" package, which would allow to compute exactly these kind of things. Unfortunately, is not released yet, but maybe it will be in their next release, since they already mentioned it in a google tech talk in march

Peipus answered 19/6, 2009 at 12:11 Comment(1)
Has it accomplished by now?Chingchinghai
M
1

If your points are within one hemisphere, you could do a gnomonic projection from spherical to planar coordinates, and then triangulate, since great-circles become straight lines of shortest distance.

Memnon answered 15/4, 2011 at 18:28 Comment(0)
C
1

Quoting from this reference: http://www.qhull.org/html/qdelaun.htm

To compute the Delaunay triangulation of points on a sphere, compute their convex hull. If the sphere is the unit sphere at the origin, the facet normals are the Voronoi vertices of the input.

Consist answered 1/4, 2013 at 5:35 Comment(1)
Generally, the convex hull is different problem than the Delaunay triangulation. But QHull's algorithm for the convex hull delivers also the Delaunay triangulation which in is dual to the Voronoi diagram.Chingchinghai

© 2022 - 2024 — McMap. All rights reserved.