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

2024-06-16 10:30:04 发布

您现在位置:Python中文网/ 问答频道 /正文

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

我在寻找一种方法,求出最小和最大的y坐标,给定一个x坐标,在x-min到x-max的连续范围内有效

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

有没有更快的方法来计算/实现?或者有没有一个模块可以让我很容易地做到这一点?在

我一直在使用matplotlib.path绘制多边形-也许这个类可以帮助你?在

谢谢


Tags: 模块path方法定义matplotlib绘制数组min
2条回答

下面是一个快速而肮脏的插值示例:

def y_on_line(x, pos1, pos2):
    if(x < min(pos1[0], pos2[0])) or (x > max(pos1[0], pos2[0])):
        return None
    else:
        if(pos1[0] == pos2[0]):
            return pos1[1]
        else:
            return pos1[1] + (pos2[1] - pos1[1]) * (x - pos1[0]) / (pos2[0] - pos1[0])

def min_max_y(x, array):
    miny = None
    maxy = None
    for i in range(len(array)):
        y = y_on_line(x, array[i], array[(i+1)%len(array)])
        if(y is None):
            continue
        if(y < miny) or (miny is None):
            miny = y
        if(y > maxy) or (maxy is None):
            maxy = y
    return [miny, maxy]

print min_max_y(0.5, [[0,0],[0,2],[1,1]])

output: [0.5,1.5]

请注意,如果多边形是凹的,那么(x, miny)-(x,maxy)都包含在其中,以防重要。在

根据@tcaswell的建议,shapely使得这一点相当简单。具体来说,该方法是计算多边形边界和所选x位置的垂直线之间的^{}(即重叠)。在

这里需要注意的一点是,shapely多边形是填充对象,因此计算这些多边形与直线的重叠将返回多边形内部的直线段。因此,要得到垂直线与多边形边缘相交的点,计算多边形的^{}属性与垂直线的交集可能是最简单的。在

实施

以下函数返回输入多边形与指定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

^{pr2}$

请注意,还可以通过以下方式创建shapely对象: a) wrapping NumPy arrays to shapely types, b) 将MPL路径转换为shapely多边形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)

Example Figure: Red dots are the 'minmax' values, blue dots are the other intersections.

相关问题 更多 >