【问题标题】:How to get all points constituting convex hull,if convex hull is perfect rectangle(python 3)?如果凸包是完美的矩形(python 3),如何获得构成凸包的所有点?
【发布时间】:2018-11-26 01:33:48
【问题描述】:

打开图片查看以下代码的结果

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只能给出标记为红色的点(只有矩形的角点)。

result of code

【问题讨论】:

  • 您可以连接连续的“红色”标记点来创建凸多边形。然后对于每个点,您可以检查它是否位于任何一侧。
  • @RoryDaulton 是的,我想返回凸包边界上的所有点。有一个错字,应该是 hull.points 。我的凸包不是矩形,但有几个点在直线上,当我使用 hull.points 时被排除在外。我做了一个小程序来举例说明这种情况在那里。
  • @RishitSanmukhani 我有一个凸包,我使用红点来表示我调用 hull.points 时得到的点。但我想要边界上的所有点。
  • @SanketChafle 这就是我写的。 “红色”标记点 == hull.points。使用 hull.points 创建凸多边形。

标签: python convex-hull convex-polygon qhull


【解决方案1】:

如果您确定凸包是一个完美的矩形,其边与 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

【讨论】:

    猜你喜欢
    • 2012-08-04
    • 1970-01-01
    • 2012-07-17
    • 2018-07-13
    • 2020-03-23
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    相关资源
    最近更新 更多