这是你的子问题的答案:
即使不使用线条(仅从点列表中查找凸壳),对于该问题的良好Python实现也将非常有用。
您可以使用alphashape。棘手的部分是选择适合您需求的alpha
。 Alphashape
带有一个函数,可找到最佳alpha值。基本上,它从0
(=凸包)开始增加alpha值,直到开始失去点。从此最优值中我们取95%,这当然是一种相当任意的解决方案,但在许多情况下,它会给您一个很好的近似值。
import alphashape
import matplotlib.pyplot as plt
from descartes import PolygonPatch
points = [(17, 158),(15, 135),(38, 183),(43, 19),(93, 88),(96, 140),(149, 163),(128, 248),(216, 265),(248, 210),(223, 167),(256, 151),(331, 214),(340, 187),(316, 53),(298, 35),(182, 0),(121, 42)]
alpha = 0.95 * alphashape.optimizealpha(points)
hull = alphashape.alphashape(points, alpha)
hull_pts = hull.exterior.coords.xy
fig, ax = plt.subplots()
ax.scatter(hull_pts[0], hull_pts[1], color='red')
ax.add_patch(PolygonPatch(hull, fill=False, color='green'))
一种可能的解决方案是将每条线插值到20个点,然后找出所有创建点的凸多边形。
这不会给您所需的输出,因为凸多边形将跟随这些额外(虚假)点,并且比使用原始点更加凸出。
我认为整个问题的最佳解决方案是从通过optimizealpha
获得的最佳 alpha 的点的凸多边形开始,然后逐渐减小它,直到您的凸多边形不与任何线相交,如 @sgillen 所建议的那样。可以类似于使用一个二分循环来找到最佳 alpha,测试any([polygon.crosses(line) for line in lines])
。
alphashape
仅支持Python 3。 - zyy
O(n log n)
凸包算法,但连接n
个点的线的数量可能高达O(n^2)
(理论最大值为n(n-1)/2
)- 即使是创造这些线本身的行为在渐近意义下也可能比直接从点计算凸包更昂贵。 - meowgoesthedog