检查点是不是位于凸包内

Posted

技术标签:

【中文标题】检查点是不是位于凸包内【英文标题】:Check if points lies inside a convex hull检查点是否位于凸包内 【发布时间】:2015-10-02 23:22:44 【问题描述】:

我正在使用scipy.spatial 包http://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.ConvexHull.html#scipy.spatial.ConvexHull 制作凸包

我尝试过搜索,但还不知道是否有一种简单的方法可以找到凸包内是否有任何点(纬度/经度)。有什么建议吗?

【问题讨论】:

【参考方案1】:

我之前使用的方法是使用Pathmatplotlib。这有一个 contains_point 方法可以做到这一点。还有一个contains_points,它允许您查询点数组。

要使用它,你会这样做

from scipy.spatial import ConvexHull
from matplotlib.path import Path

hull = ConvexHull( points )

hull_path = Path( points[hull.vertices] )

print hull_path.contains_point((1,2)) # Is (1,2) in the convex hull?

【讨论】:

【参考方案2】:

matplotlib 路径方法有效,但仅适用于二维数据。适用于任意维度的一般方法是使用半空间方程来计算船体的各个面。

import numpy as np
from scipy.spatial import ConvexHull

# Assume points are shape (n, d), and that hull has f facets.
hull = ConvexHull(points)

# A is shape (f, d) and b is shape (f, 1).
A, b = hull.equations[:, :-1], hull.equations[:, -1:]

eps = np.finfo(np.float32).eps

def contained(x):
  # The hull is defined as all points x for which Ax + b <= 0.
  # We compare to a small positive value to account for floating
  # point issues.
  #
  # Assuming x is shape (m, d), output is boolean shape (m,).
  return np.all(np.asarray(x) @ A.T + b.T < eps, axis=1)

# To test one point:
print('Point (2,1) is in the hull?', contained([[2, 1]]))

【讨论】:

我不确定这是否能正常工作。我将用于构建船体的相同点输入contained 并发现其中一些未被归类为包含。我以为那是因为我使用的是&lt; 而不是&lt;=,但是在更改为非严格不等式后,我仍然发现没有包含点。 可能只是浮点精度问题。在评估不等式之前减去np.finfo(np.float32).eps 可以得到&lt;= 0 比较所需的结果。 好的,谢谢!我在我一直使用的代码中发现了同样的东西,但忘了更新这个答案。现在将 eps 添加到比较中。

以上是关于检查点是不是位于凸包内的主要内容,如果未能解决你的问题,请参考以下文章

POJ 1584 /// 判断圆(点)在多边形内 判断凸包

检查点是不是在多边形内

Rails 谷歌地图检查点是不是在一定半径内

检查点是否位于m维矩形内

检查 IP 地址是不是在范围/子网内的标准/安全方法

检查用户位置是不是在颤动的2个地理点的区域内