PYTHON-返回给定x的多边形路径的y坐标

2022-04-11 00:00:00 python matplotlib polygon

问题描述

我有一个不规则多边形,其周长由笛卡尔坐标数组定义。

我正在寻找一种方法,在给定x坐标的情况下找到最小和最大y坐标,该坐标适用于从x-min到x-max的连续范围。

我想一种方法是定义每个点之间的直线方程,然后应用其中的两个方程,其范围由给定的x坐标满足。

有没有更快的计算/实施方法?或者有没有什么模块可以让我轻松做到这一点?

我一直在使用matplotlib.Path绘制多边形--或许这个类可以提供帮助?

谢谢


解决方案

根据@tCaswell的建议,shapely使这一点变得相当容易。特别是,方法是计算您的多边形边界与您选择的x位置处的垂直线之间的.intersection(即重叠)。

这里需要注意的关键一点是,形状整齐的多边形是填充对象,因此计算这些多边形与直线的重叠将返回该多边形内部的线段。因此,要获得垂直线与多边形边相交的点,最简单的方法可能是计算面的.boundary属性和垂直线之间的交集。

实现

以下是一个函数,用于返回输入多边形与指定x值处的垂直线的交点:

import shapely.geometry as sg

def polygon_intersect_x(poly, x_val):
    """
    Find the intersection points of a vertical line at
    x=`x_val` with the Polygon `poly`.
    """
    if x_val < poly.bounds[0] or x_val > poly.bounds[2]:
        raise ValueError('`x_val` is outside the limits of the Polygon.')
    if isinstance(poly, sg.Polygon):
        poly = poly.boundary
    vert_line = sg.LineString([[x_val, poly.bounds[1]],
                               [x_val, poly.bounds[3]]])
    pts = [pt.xy[1][0] for pt in poly.intersection(vert_line)]
    pts.sort()
    return pts

用法示例

首先创建一个示例shapely.geometry.Polygon

p = sg.Polygon([(0, 0),
                (10, 0),
                (30, 10),
                (70, -50),
                (80, 30),
                (40, 40),
                (60, 80),
                (50, 100),
                (15, 20),
                (0, 0)])
请注意,您还可以通过以下方式创建形状对象: A)wrapping NumPy arrays to shapely types, B)将MPL路径转换为形状良好的多边形,如下所示:p = sg.Polygon(my_path.vertices)

现在可以使用上面的函数计算最小/最大交点:

x_val = 45
points = polygon_intersect_x(p, x_val)
minmax = [points[0], points[-1]]  # The values are already sorted
print minmax
# [-12.5, 88.5714286]

这里有一个简单的图表,演示了该方法:

import matplotlib.pyplot as plt

ax = plt.gca()

ax.fill(*p.boundary.xy, color='y')
ax.axvline(x_val, color='b')

ax.plot([x_val, ] * len(points), points, 'b.')
ax.plot([x_val, ] * 2, minmax, 'ro', ms=10)

相关文章