如果凸包是完美矩形(python 3),如何获得构成凸包的所有点?
打开图像查看下面代码的结果如果凸包是完美矩形(python 3),如何获得构成凸包的所有点?,python,convex-hull,convex-polygon,qhull,Python,Convex Hull,Convex Polygon,Qhull,打开图像查看下面代码的结果 import numpy as np from scipy.spatial import ConvexHull import matplotlib.pyplot as plt points = np.array([[1,1],[1,2],[1,3],[1,4],[2,1],[2,2],[2,3],[2,4],[3,1],[3,2],[3,3],[3,4],[4,1],[4,2],[4,3],[4,4]]) hull = ConvexHull(points) pl
import numpy as np
from scipy.spatial import ConvexHull
import matplotlib.pyplot as plt
points = np.array([[1,1],[1,2],[1,3],[1,4],[2,1],[2,2],[2,3],[2,4],[3,1],[3,2],[3,3],[3,4],[4,1],[4,2],[4,3],[4,4]])
hull = ConvexHull(points)
plt.plot(points[:,0], points[:,1], 'o')
for simplex in hull.simplices:
plt.plot(points[simplex, 0], points[simplex, 1], 'k-')
plt.plot(points[simplex,0], points[simplex,1], 'ro', alpha=.25, markersize=20)
我想得到凸包上的点的坐标索引(黑色+线上的点)。我选择矩形只是为了得到一个极端情况
hull.points只能给出标记为红色的点(仅矩形的角点)
如果您确定凸包是一个完美的矩形,其边与x轴和y轴对齐,那么查找所有边界点的索引非常简单。要做到这一点,根本不需要计算凸包。这个描述符合你的例子。下面是一些代码,在这种情况下可以实现您想要的功能。此代码的时间复杂度为
O(n)
,其中n
是总点数
# Find the indices of all boundary points, in increasing index order,
# assuming the hull is a rectangle aligned with the axes.
x_limits = (min(pt[0] for pt in points), max(pt[0] for pt in points))
y_limits = (min(pt[1] for pt in points), max(pt[1] for pt in points))
boundary_indices = [idx for idx, (x, y) in enumerate(points)
if x in x_limits or y in y_limits]
然而,这种情况似乎很简单。下面是更通用的代码,适用于所有二维情况,尤其是当点具有积分坐标时。这是因为,如果精度不精确,则查找点是否正好位于线段上是很困难的。此代码以时间复杂度O(n*m)
运行,其中n
是点的数量,m
是凸包中的顶点数量
# Find the indices of all boundary points, in increasing index order,
# making no assumptions on the hull.
def are_collinear2d(pt1, pt2, pt3):
"""Return if three 2-dimensional points are collinear, assuming
perfect precision"""
return ((pt2[0] - pt1[0]) * (pt3[1] - pt1[1])
- (pt2[1] - pt1[1]) * (pt3[0] - pt1[0])) == 0
vertex_pairs = list(zip(vertices, vertices[1:] + vertices[0:1]))
boundary_indices = []
for idx, pt in enumerate(points):
for v1, v2 in vertex_pairs:
if are_collinear2d(pt, v1, v2):
boundary_indices.append(idx)
break
您可以连接连续的“红色”标记点以创建凸多边形。然后,对于每个点,您可以检查它是否位于任何一侧。@RoryDaulton是的,我想返回凸包边界上的所有点。有一个输入错误,应该是hull.points。我的凸面外壳不是矩形,但有几个点位于直线上,当我使用hull.points时,这些点被排除在外。我制作了一个小程序只是为了举例说明那里的情况。@RishitSanmukhani我有一个凸面外壳,我使用红点只是为了表示调用hull.points时得到的点。“但我想要边界上的所有点。”桑克查布尔,这就是我写的。“红色”标记点==外壳点。使用hull.points创建凸多边形。