Python - Return 给定 x 的多边形路径的 y 坐标
Python - Return y coordinates of polygon path given x
我有一个不规则多边形,其周长由笛卡尔坐标数组定义。
我正在寻找一种方法来找到给定 x 坐标的最小和最大 y 坐标,该 x 坐标适用于从 x-min 到 x-max 的连续范围。
我想这样做的一种方法是定义每个点之间的直线方程,然后应用给定 x 坐标满足范围的其中两个方程。
有没有更快的方法calculate/implement?或者是否有一个模块可以让我轻松地做到这一点?
我一直在使用 matplotlib.path 绘制多边形 - 也许这个 class 可以帮助?
谢谢
这是插值的一个简单粗暴的例子:
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 makes this fairly easy. In particular, the approach is to compute the .intersection
(即重叠)多边形边界与所选 x 位置的垂直线之间。
这里要注意的一个关键点是形状多边形是填充对象,因此计算这些多边形与一条线的重叠将 return 多边形内的线段。因此,要获得垂直线穿过多边形边缘的点,最简单的方法可能是计算多边形的 .boundary
属性与垂直线之间的交点。
实施
这是一个函数 returns 输入多边形与垂直线在指定 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)])
请注意,您还可以通过以下方式创建形状优美的对象:
一) wrapping NumPy arrays to shapely types,
b) 将 MPL 路径转换为 p = sg.Polygon(my_path.vertices)
.
形状的多边形
上面的函数现在可以用来计算 min/max 个交点:
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)
我有一个不规则多边形,其周长由笛卡尔坐标数组定义。
我正在寻找一种方法来找到给定 x 坐标的最小和最大 y 坐标,该 x 坐标适用于从 x-min 到 x-max 的连续范围。
我想这样做的一种方法是定义每个点之间的直线方程,然后应用给定 x 坐标满足范围的其中两个方程。
有没有更快的方法calculate/implement?或者是否有一个模块可以让我轻松地做到这一点?
我一直在使用 matplotlib.path 绘制多边形 - 也许这个 class 可以帮助?
谢谢
这是插值的一个简单粗暴的例子:
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 makes this fairly easy. In particular, the approach is to compute the .intersection
(即重叠)多边形边界与所选 x 位置的垂直线之间。
这里要注意的一个关键点是形状多边形是填充对象,因此计算这些多边形与一条线的重叠将 return 多边形内的线段。因此,要获得垂直线穿过多边形边缘的点,最简单的方法可能是计算多边形的 .boundary
属性与垂直线之间的交点。
实施
这是一个函数 returns 输入多边形与垂直线在指定 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)])
请注意,您还可以通过以下方式创建形状优美的对象:
一) wrapping NumPy arrays to shapely types,
b) 将 MPL 路径转换为 p = sg.Polygon(my_path.vertices)
.
上面的函数现在可以用来计算 min/max 个交点:
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)