我在使用scipy的Voronoi函数时遇到了麻烦。我遵循了2d示例,但是当我在3d中执行类似示例时,并非所有ridge_points都会被计算。我的数据是[0,2] x [0,2] x [0,2]中的27个点的框:
points = np.array([
# bottom plane
[0,2,0], [1,2,0], [2,2,0],
[0,1,0], [1,1,0], [2,1,0],
[0,0,0], [1,0,0], [2,0,0],
# middle plane
[0,2,1], [1,2,1], [2,2,1],
[0,1,1], [1,1,1], [2,1,1],
[0,0,1], [1,0,1], [2,0,1],
# top plane
[0,2,2], [1,2,2], [2,2,2],
[0,1,2], [1,1,2], [2,1,2],
[0,0,2], [1,0,2], [2,0,2]
])
vor = Voronoi(points)
print vor.ridge_points
# outputed
array([[ 4, 7],
[ 4, 5],
[ 4, 3],
[ 4, 1],
[ 4, 13],
[ 3, 12],
[ 7, 16],
[15, 12],
[15, 16],
[ 9, 12],
[ 9, 10],
[ 1, 10],
[12, 21],
[12, 13],
[23, 14],
[23, 22],
[14, 17],
[14, 11],
[14, 5],
[14, 13],
[22, 19],
[22, 21],
[22, 13],
[22, 25],
[17, 16],
[11, 10],
[25, 16],
[16, 13],
[13, 10],
[19, 10], dtype=int32)
我注意到了拐角处的要点:
points[0] = array([0, 2, 0])
points[2] = array([2, 2, 0])
points[6] = array([0, 0, 0])
points[8] = array([2, 0, 0])
points[18] = array([0, 2, 2])
points[20] = array([2, 2, 2])
points[24] = array([0, 0, 2])
points[26] = array([2, 0, 2])
没有任何山脊点。我会假设(像2D情况一样)角会具有脊点。例如,我假设点[6] = [0,0,0]的脊点分别为[1,0,0],[0,1,0]和[0,0,1]。这是不可能用scipy计算的,还是我一直在考虑这个错误?
最佳答案
Scipy将Qhull用于Delaunay / Voronoi / Convexhull计算。 ridge_points
中包含的数据是qvoronoi Fv
报告的,尽管不一定以相同的顺序列出这些脊。 (作为检查:https://gist.github.com/pv/2f756ec83cdf242ce691)Fv
(http://www.qhull.org/html/qh-optf.htm#Fv2)的Qhull文档提到了一个警告,在这里似乎很相关:
选项“ Fv”不列出需要多个中点的山脊。例如,共球点的Voronoi图列出了零个脊(例如,“ rbox 10 s | qvoronoi Fv Qz”)。其他示例是矩形网格的Voronoi图(例如,“ rbox 27 M1,0 | qvoronoi Fv”)或带有矩形角的点集(例如,“ rbox P4,4,4 P4,2,4 P2,4” ,4 P4,4,2 10 | qvoronoi Fv')。两种情况都错过了角落的无边射线。要确定这些山脊,请用大立方体包围这些点(例如,“ rbox 10 s c G2.0 | qvoronoi Fv Qz”)。多维数据集必须足够大以绑定原始点集的所有Voronoi区域。请报告任何其他遗漏的情况。如果您可以正式描述这些情况或编写代码来处理它们,请发送电子邮件至[email protected]。
文本中提到的rbox 27 M1,0
与示例中的点完全相同(顺序不同)。
通常,Qhull在处理几何退化时会遇到问题,例如在矩形网格中。一个通用的解决方法是设置qhull_options="QJ"
,它告诉它向数据点添加随机扰动,直到解决退化为止。通常,这会生成带有多个其他简化符号/凸脊的细分/ voronoi图,但可以解决此类问题。