Numpy and line intersections

前端 未结 7 2011
春和景丽
春和景丽 2020-11-30 00:21

How would I use numpy to calculate the intersection between two line segments?

In the code I have segment1 = ((x1,y1),(x2,y2)) and segment2 = ((x1,

相关标签:
7条回答
  • 2020-11-30 00:50

    This is is a late response, perhaps, but it was the first hit when I Googled 'numpy line intersections'. In my case, I have two lines in a plane, and I wanted to quickly get any intersections between them, and Hamish's solution would be slow -- requiring a nested for loop over all line segments.

    Here's how to do it without a for loop (it's quite fast):

    from numpy import where, dstack, diff, meshgrid
    
    def find_intersections(A, B):
    
        # min, max and all for arrays
        amin = lambda x1, x2: where(x1<x2, x1, x2)
        amax = lambda x1, x2: where(x1>x2, x1, x2)
        aall = lambda abools: dstack(abools).all(axis=2)
        slope = lambda line: (lambda d: d[:,1]/d[:,0])(diff(line, axis=0))
    
        x11, x21 = meshgrid(A[:-1, 0], B[:-1, 0])
        x12, x22 = meshgrid(A[1:, 0], B[1:, 0])
        y11, y21 = meshgrid(A[:-1, 1], B[:-1, 1])
        y12, y22 = meshgrid(A[1:, 1], B[1:, 1])
    
        m1, m2 = meshgrid(slope(A), slope(B))
        m1inv, m2inv = 1/m1, 1/m2
    
        yi = (m1*(x21-x11-m2inv*y21) + y11)/(1 - m1*m2inv)
        xi = (yi - y21)*m2inv + x21
    
        xconds = (amin(x11, x12) < xi, xi <= amax(x11, x12), 
                  amin(x21, x22) < xi, xi <= amax(x21, x22) )
        yconds = (amin(y11, y12) < yi, yi <= amax(y11, y12),
                  amin(y21, y22) < yi, yi <= amax(y21, y22) )
    
        return xi[aall(xconds)], yi[aall(yconds)]
    

    Then to use it, provide two lines as arguments, where is arg is a 2 column matrix, each row corresponding to an (x, y) point:

    # example from matplotlib contour plots
    Acs = contour(...)
    Bsc = contour(...)
    
    # A and B are the two lines, each is a 
    # two column matrix
    A = Acs.collections[0].get_paths()[0].vertices
    B = Bcs.collections[0].get_paths()[0].vertices
    
    # do it
    x, y = find_intersections(A, B)
    

    have fun

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