Algorithm 球面上Voronoi图的计算算法?
我正在寻找一个简单的(如果存在的话)算法来找到球面上一组点的Voronoi图。源代码将是伟大的。我是一个Delphi人(是的,我知道…),但我也吃C代码。有一个很好的Voronoi图表示例程序(包括Delphi 5/6的源代码) 我认为“球体表面上的点”意味着首先必须将它们重新映射到2D坐标,创建Voronoi图,然后将它们重新映射到球体表面坐标。这两个公式在这里有效吗 还请注意,Voronoi图的拓扑结构将错误(它位于矩形内,并且不会“环绕”),在这里,它可以帮助将所有点从(0,0)-(x,y)复制到(0,-y*2)-(x,0)上方、下方(0,y)-(x,y*2)、左侧(-x,0)-(0,y)和右侧(x,0)-(x*2,y)的相邻区域。我希望你知道我的意思,请随便问:)这是一篇关于 或者,如果你摸索Fortran(荒凉!),那就有了Algorithm 球面上Voronoi图的计算算法?,algorithm,math,geometry,computational-geometry,voronoi,Algorithm,Math,Geometry,Computational Geometry,Voronoi,我正在寻找一个简单的(如果存在的话)算法来找到球面上一组点的Voronoi图。源代码将是伟大的。我是一个Delphi人(是的,我知道…),但我也吃C代码。有一个很好的Voronoi图表示例程序(包括Delphi 5/6的源代码) 我认为“球体表面上的点”意味着首先必须将它们重新映射到2D坐标,创建Voronoi图,然后将它们重新映射到球体表面坐标。这两个公式在这里有效吗 还请注意,Voronoi图的拓扑结构将错误(它位于矩形内,并且不会“环绕”),在这里,它可以帮助将所有点从(0,0)-(x,y
原始链接(死):正在开发“球形内核”包,该包允许精确计算此类内容。不幸的是,尚未发布,但可能会在下一版本中发布,因为它们已经发布了我认为每个点的Voronoi平面都可以使用非欧几里德几何构造。通常是二维平面上的一条线,现在是球体上的一个“大圆”(参见维基百科:)。通过简单地旋转球体,使得分割的大圆是赤道,然后它是另一个半球上的所有点,而不是构建Voronoi平面的点,很容易找到两点之间任何大圆的错边
这不是完整的答案,但这是我要开始的地方。如果你的点在一个半球内,你可以做一个从球面坐标到平面坐标的gnomonic投影,然后三角化,因为大圆变成了距离最短的直线。简言之,试试看。我写道。注意,球面上的Delaunay三角剖分就是凸包。 因此,您可以计算3D凸包(例如,使用CGAL)
并从参考资料中引用双引号。 要计算球面上点的Delaunay三角剖分,请计算它们的凸包。如果球体是原点处的单位球体,则镶嵌面法线是输入的Voronoi顶点
INRIA有一篇关于球面上点的Delaunay三角剖分(DT)的论文:他们在这篇文章中讨论了一个在中的实现 本文介绍了DT算法的各种可用实现 引述该报的话: 一个简单而标准的答案在于计算三维凸包 这是出了名的等价点 对于凸壳的计算,本文建议:
CdAL的DC++类具有获得Voronoi图的方法。</P>
根据Monique Teillaud(上述论文的作者之一)的说法,在我看来,2012年11月的实现还没有准备好。这个问题已经有一段时间没有得到回答,但我发现有两篇论文在球体表面实现了(效率O(N lg N),内存O(N))。也许未来的观众会发现这些信息很有用
- Dinis和Mamede在2010年科学与工程Voronoi图国际研讨会上发表的《扫球》。可于
- Zheng等人的“球面Voronoi细分的平面扫描算法”。我不确定该算法是否因第一个算法而出版,但日期为2011年12月13日。可在以下网址免费获取:
0.18
版本开始,该版本正式以scipy.spatial.sphereicalvoronoi提供。在官方网站上有一个使用和绘图的工作示例
该算法遵循二次时间复杂度。虽然对数线性是球体表面Voronoi图的理论最佳值,但这是目前我们能够实现的最佳值。如果您想了解更多信息并帮助开发工作,那么与改进Python处理球形Voronoi图和相关数据结构的方式相关的一些未决问题如下:
有关与此Python代码相关的理论/开发/挑战以及相关计算几何工作的进一步背景,您还可以查看Nikolai和I的一些谈话:
原始答复:
实际上,我最近为球体表面上的Voronoi图编写了一些开源Python代码:
用法,阿尔戈
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)
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