Area intersection in Python

后端 未结 1 792
滥情空心
滥情空心 2021-01-18 16:43

I have a code that takes a condition C as an input, and computes the solution to my problem as an \'allowed area\' A on the (x,y) space. This area is made of several \'tube

1条回答
  •  [愿得一人]
    2021-01-18 17:47

    Problem solved with Shapely!

    I defined each tube as a Polygon, and an area A is a MultiPolygon object built as the union of its tubes.

    The intersection method then computes the solution I was looking for (the overlap between all areas).

    The whole thing is almost instantaneous. I didn't know shapely was so good with large objects [around 2000 points per tube, 10 tubes per area, 4 areas].

    Thank you for your help! :)

    Edit:

    A working example.

    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()
    

    And the plot :

    0 讨论(0)
提交回复
热议问题