scipy voronoi 3d - 并非显示所有脊点

时间:2014-09-09 21:53:57

标签: python numpy scipy voronoi

我在使用scipy的Voronoi功能时遇到了麻烦。我已经按照第二个例子,但是当我在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计算或我一直在考虑这个错误?

2 个答案:

答案 0 :(得分:1)

Scipy使用Qhull进行Delaunay / Voronoi / Convexhull计算。 ridge_points中包含的数据是qvoronoi Fv报告的数据,尽管脊不一定按相同的顺序列出。 (作为支票:https://gist.github.com/pv/2f756ec83cdf242ce691

Fvhttp://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区域。请报告任何其他错过的案例。如果您可以正式描述这些案例或编写代码来处理它们,请发送电子邮件至qhull@qhull.org。

文本中提到的rbox 27 M1,0与示例中的点集完全相同(按不同顺序)。

通常,Qhull在处理几何退化方面存在问题,例如在矩形网格中发生。一般的解决方法是设置qhull_options="QJ",它告诉它在数据点添加随机扰动,直到解析退化。这通常会产生tesselations / voronoi图表,其中包含几个额外的单纯形/脊,但可能会解决此类问题。

答案 1 :(得分:0)

我也遇到了同样的问题。然后我使用 Delaunay 获取 3D 中的所有 rigde 点。如下:

def find_neighbors(tess):
"""
Parameters
----------
tess : Delaunay

Returns
-------
neighbors : neighbors in defaultdict type

"""

neighbors = defaultdict(set)

for simplex in tess.simplices:
    for idx in simplex:
        other = set(simplex)
        other.remove(idx)
        neighbors[idx] = neighbors[idx].union(other)
return neighbors

import scipy.spatial
from collections import defaultdict

x_list = np.random.random(8)
y_list = np.random.random(8)
z_list = np.random.random(8)

tri = scipy.spatial.Delaunay(np.array([[x,y,z] for x,y,z in zip(x_list, y_list, z_list)])) # create the Delaunay triangles
print(find_neighbors(tri))