Python 检查一个点是否在ConvexHull中?

Python 检查一个点是否在ConvexHull中?,python,numpy,scipy,Python,Numpy,Scipy,我很难理解如何计算一个n维点是否在n维凸包内 这里提出了一个非常类似的问题(相同): 然而,这些答案让我困惑,或者似乎对我不起作用,我不知道为什么 def in_hull(p, hull): """ Copied and from the Top Original answer """ from scipy.spatial import Delaunay if not isinstance(hull,Delaunay): hull = Delaunay(

我很难理解如何计算一个n维点是否在n维凸包内

这里提出了一个非常类似的问题(相同):

然而,这些答案让我困惑,或者似乎对我不起作用,我不知道为什么

def in_hull(p, hull):
    """ Copied and from the Top Original answer """
    from scipy.spatial import Delaunay
    if not isinstance(hull,Delaunay):
        hull = Delaunay(hull)

    return hull.find_simplex(p)>=0
这个函数给了我很多关于真实数据的错误或不想要的结果,我正在使用它。然而,在调试时,我编写了一个简单的脚本来测试一些明显的期望:

如果我用一组点构造一个凸形, 当我为“会员资格”检查这组分数时,它们都应该是 “成员”

虽然这种情况很少见,但在随机生成的数据(5000个数据中有3个)上似乎失败了,但在真实数据上问题更大。我所说的失败,是指我实际上遇到了一些情况,并不是所有的点都被认为是成员

我做错什么了吗?或者完全是误解?在这一点上我相当困惑,所以我想解释一下发生了什么


最后,我想要;给定一个凸形,在前一阶段计算;能够确定点是否位于外壳内。

对于几乎平坦的单纯形(三角形),
Delaunay
对象的
find\u simplex
方法似乎是一个边情况问题

以下是一个代码,用于查找和绘制仅包含3点的故障案例:

import matplotlib.pylab as plt
from scipy.spatial import Delaunay
from scipy.spatial import delaunay_plot_2d

for _ in range(5000):
    cloud = np.random.rand(3, 2)

    tri = Delaunay(cloud)

    if np.any( tri.find_simplex(cloud)<0 ):
        print('break at', _)

        delaunay_plot_2d(tri);
        id_break = np.where(tri.find_simplex(cloud)<0)
        plt.plot( *cloud[id_break].ravel(), 'or' );
        break
将matplotlib.pylab作为plt导入
从scipy.spatial导入Delaunay
从scipy.spatical导入delaunay\u plot\u 2d
对于范围内的(5000):
cloud=np.random.rand(3,2)
tri=德洛奈(云)

如果np.any(tri.find_simplex(cloud))非常感谢!这解决了我的问题,是的,这正是边界案例。
import matplotlib.pylab as plt
from scipy.spatial import Delaunay
from scipy.spatial import delaunay_plot_2d

for _ in range(5000):
    cloud = np.random.rand(3, 2)

    tri = Delaunay(cloud)

    if np.any( tri.find_simplex(cloud)<0 ):
        print('break at', _)

        delaunay_plot_2d(tri);
        id_break = np.where(tri.find_simplex(cloud)<0)
        plt.plot( *cloud[id_break].ravel(), 'or' );
        break
hull = ConvexHull(cloud)

def point_in_hull(point, hull, tolerance=1e-12):
    return all(
        (np.dot(eq[:-1], point) + eq[-1] <= tolerance)
        for eq in hull.equations)

[ point_in_hull(point, hull) for point in cloud ]
# [True, True, True]