Python

时间:2016-06-01 08:38:20

标签: python numpy matplotlib intersection area

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

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

以下是2个条件的示例(A1:绿色,3个管.A2:紫色,1个管);解决方案S为红色。

Output of the code for 2 conditions

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

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

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

注意:

  • 代码还存储了行的弧长。

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

  • 这些线是参数函数(即我们不能写y = f(x),因为允许线是垂直的)。

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

编辑:

  • 我不知道怎样才能将plt.fill_between用于多个交集(我可以在这里做2个条件,但我需要代码在有太多行时自动执行眼睛判断)。

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

    < / LI>
  • 我不认为我能用sets做到这一点:以所需精度扫描整个(x,y)区域代表大约6e8点...... [线条只有1e3点由于可变步长(适应曲率),但整个问题非常大]

1 个答案:

答案 0 :(得分:5)

Shapely解决了问题!

我将每个管定义为Polygon,区域A是MultiPolygon对象,它是作为其管的并集而构建的。

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

整件事几乎是瞬间的。对于大型物体[每个管约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()

情节:

enter image description here