【问题标题】:Area intersection in PythonPython中的区域交集
【发布时间】:2016-09-30 12:26:30
【问题描述】:

我有一个将条件 C 作为输入的代码,并将我的问题的解决方案计算为 (x,y) 空间上的“允许区域”A。这个区域由几个“管子”组成,它们由两条永远不能交叉的线定义。

我要找的最终结果必须满足k个条件{C1, .., Ck},因此是k个区域{A1, .. , Ak}的交集S。

这是一个有 2 个条件的示例(A1:绿色,3 个管子。A2:紫色,1 个管子);溶液 S 为红色。

当我处理 4 个区域,每个区域大约 10 个管子时,如何找到 S? (最后的情节很糟糕!)

我需要能够绘制它,并找到 S 中点的平均坐标和方差(每个坐标的方差)。 [如果有一种有效的方法可以知道点 P 是否属于 S,我将使用蒙特卡罗方法。

理想情况下,我还希望能够实现从 S 中移除的“禁止管”[这可能比将 S 与禁止区域外部相交更复杂,因为两个管来自同一个区域可以交叉(即使定义管的线永远不会交叉)]。


注意:

  • 代码还存储了线条的弧长。

  • 这些线存储为点数组(每条线大约 1000 个点)。定义管的两条线不一定具有相同数量的点,但 Python 可以在 1 秒内根据它们的弧长对所有这些点进行插值。

  • 线条是参数函数(即我们不能写 y = f(x),因为线条可以是垂直的)。

  • 使用绘图编辑了绘图以得到右侧的结果...效率不高!


编辑:

  • 不知道怎么用plt.fill_between来做多重交集(我这里可以做2个条件,但是需要代码在眼睛判断线太多的时候自动做)。

  • 现在我只生成线条。我没有写任何东西来寻找最终的解决方案,因为我绝对不知道哪种结构最适合这个。 [然而,以前版本的代码能够找到 2 个不同管的线之间的交点,我打算将它们作为多边形传递给 shapely,但这意味着其他几个问题..]

  • 我不认为我可以用 sets 做到这一点:以所需精度扫描整个 (x,y) 区域表示大约 6e8 点... [由于变量,这些线只有 1e3 点步长(适应曲率),但整个问题相当大]

【问题讨论】:

  • 最后一点 - 您可以使用 plt.fill_between(或 plt.fill)完成此操作
  • 您能否在问题中添加一些代码,以显示您在实施过程中的哪些方面,以便那些愿意帮助获得更具体的想法的人,您可能遇到的困难以及他们所知道的最匹配的地方?那很好啊。谢谢。
  • 只是一个想法,无需仔细观察,如果您可以将每个管计算为点的set,那么您可以在每对管之间进行set 交叉,以获得对您的预期有帮助的东西结果。
  • 查看有助于解决此类问题的 Shapely 库pypi.python.org/pypi/Shapely

标签: python numpy matplotlib intersection area


【解决方案1】:

Shapely 解决了问题!

我将每个管子定义为Polygon,而区域 A 是一个 MultiPolygon 对象,构建为它的管子的联合体。

intersection 方法然后计算我正在寻找的解决方案(所有区域之间的重叠)。

整个过程几乎是瞬间完成的。我不知道 shapely 对大型物体的效果如此好[每个管大约 2000 个点,每个区域 10 个管,4 个区域]。

感谢您的帮助! :)

编辑:

一个工作示例。

import matplotlib.pyplot as plt
import shapely
from shapely.geometry import Polygon
from descartes import PolygonPatch
import numpy as np

def create_tube(a,height):
    x_tube_up = np.linspace(-4,4,300)
    y_tube_up = a*x_tube_up**2 + height
    x_tube_down = np.flipud(x_tube_up)          #flip for correct definition of polygon
    y_tube_down = np.flipud(y_tube_up - 2)

    points_x = list(x_tube_up) + list(x_tube_down)
    points_y = list(y_tube_up) + list(y_tube_down)

    return Polygon([(points_x[i], points_y[i]) for i in range(600)])

def plot_coords(ax, ob):
    x, y = ob.xy
    ax.plot(x, y, '+', color='grey')


area_1 = Polygon()          #First area, a MultiPolygon object
for h in [-5, 0, 5]:
    area_1 = area_1.union(create_tube(2, h))

area_2 = Polygon()
for h in [8, 13, 18]:
    area_2 = area_2.union(create_tube(-1, h))

solution = area_1.intersection(area_2)      #What I was looking for

##########  PLOT  ##########

fig = plt.figure()
ax = fig.add_subplot(111)

for tube in area_1:
    plot_coords(ax, tube.exterior)
    patch = PolygonPatch(tube, facecolor='g', edgecolor='g', alpha=0.25)
    ax.add_patch(patch)

for tube in area_2:
    plot_coords(ax, tube.exterior)
    patch = PolygonPatch(tube, facecolor='m', edgecolor='m', alpha=0.25)
    ax.add_patch(patch)

for sol in solution:
    plot_coords(ax, sol.exterior)
    patch = PolygonPatch(sol, facecolor='r', edgecolor='r')
    ax.add_patch(patch)

plt.show()

还有剧情:

【讨论】:

  • 您可以发布您的解决方案的工作示例吗?顺便说一句,您可以选择您的答案作为解决方案。
猜你喜欢
  • 2016-03-07
  • 1970-01-01
  • 1970-01-01
  • 2016-12-27
  • 2021-02-17
  • 2021-10-09
  • 1970-01-01
  • 2023-03-24
相关资源
最近更新 更多