featuremapper/analysis/pinwheels.py
def find_intersections(self, contour1, contour2):
        """
        Vectorized code to find intersections between contours. All
        successive duplicate vertices along the input contours must be
        removed to help avoid division-by-zero errors.

        There are cases were no intersection exists (eg. parallel lines)
        where division by zero and invalid value exceptions occur. These
        exceptions should be caught as warnings: these edge cases are
        unavoidable with this algorithm and do not indicate that the
        output is erroneous.
        """
        # Elementwise min selection
        amin = lambda x1, x2: np.where(x1 < x2, x1, x2)
        # Elementwise max selection
        amax = lambda x1, x2: np.where(x1 > x2, x1, x2)
        # dstacks, checks True depthwise
        aall = lambda abools: np.dstack(abools).all(axis=2)
        # Uses delta (using np.diff) to find successive slopes along path
        slope = lambda line: (lambda d: d[:, 1] / d[:, 0])(np.diff(line, axis=0))
        # Meshgrids between both paths (x and y). One element sliced off end/beginning
        x11, x21 = np.meshgrid(contour1[:-1, 0], contour2[:-1, 0])
        x12, x22 = np.meshgrid(contour1[1:, 0], contour2[1:, 0])
        y11, y21 = np.meshgrid(contour1[:-1, 1], contour2[:-1, 1])
        y12, y22 = np.meshgrid(contour1[1:, 1], contour2[1:, 1])
        # Meshgrid of all slopes for both paths
        m1, m2 = np.meshgrid(slope(contour1), slope(contour2))
        m2inv = 1 / m2 # m1inv was not used.
        yi = (m1 * (x21 - x11 - m2inv * y21) + y11) / (1 - m1 * m2inv)
        xi = (yi - y21) * m2inv + x21 # (xi, yi) is intersection candidate
        # Bounding box type conditions for intersection candidates
        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)]

        Vectorized code to find intersections between contours. All
        successive duplicate vertices along the input contours must be
        removed to help avoid division-by-zero errors.

        There are cases were no intersection exists (eg. parallel lines)
        where division by zero and invalid value exceptions occur. These
        exceptions should be caught as warnings: these edge cases are
        unavoidable with this algorithm and do not indicate that the
        output is erroneous.
        
Vectorized code to find intersections between contours. All
successive duplicate vertices along the input contours must be
removed to help avoid division-by-zero errors.

There are cases were no intersection exists
where division by zero and invalid value exceptions occur. These
exceptions should be caught as warnings: these edge cases are
unavoidable with this algorithm and do not indicate that the
output is erroneous.
Vectorized code to find intersections between contours . All successive duplicate vertices along the input contours must be removed to help avoid division - by - zero errors . There are cases were no intersection exists where division by zero and invalid value exceptions occur . These exceptions should be caught as warnings : these edge cases are unavoidable with this algorithm and do not indicate that the output is erroneous .
def find_intersections(self, contour1, contour2):
        amin = lambda x1, x2: np.where(x1 < x2, x1, x2)
        amax = lambda x1, x2: np.where(x1 > x2, x1, x2)
        aall = lambda abools: np.dstack(abools).all(axis=2)
        slope = lambda line: (lambda d: d[:, 1] / d[:, 0])(np.diff(line, axis=0))
        x11, x21 = np.meshgrid(contour1[:-1, 0], contour2[:-1, 0])
        x12, x22 = np.meshgrid(contour1[1:, 0], contour2[1:, 0])
        y11, y21 = np.meshgrid(contour1[:-1, 1], contour2[:-1, 1])
        y12, y22 = np.meshgrid(contour1[1:, 1], contour2[1:, 1])
        m1, m2 = np.meshgrid(slope(contour1), slope(contour2))
        m2inv = 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)]
def find_intersections ( self , contour1 , contour2 ) : amin = lambda x1 , x2 : np . where ( x1 < x2 , x1 , x2 ) amax = lambda x1 , x2 : np . where ( x1 > x2 , x1 , x2 ) aall = lambda abools : np . dstack ( abools ) . all ( axis = 2 ) slope = lambda line : ( lambda d : d [ : , 1 ] / d [ : , 0 ] ) ( np . diff ( line , axis = 0 ) ) x11 , x21 = np . meshgrid ( contour1 [ : - 1 , 0 ] , contour2 [ : - 1 , 0 ] ) x12 , x22 = np . meshgrid ( contour1 [ 1 : , 0 ] , contour2 [ 1 : , 0 ] ) y11 , y21 = np . meshgrid ( contour1 [ : - 1 , 1 ] , contour2 [ : - 1 , 1 ] ) y12 , y22 = np . meshgrid ( contour1 [ 1 : , 1 ] , contour2 [ 1 : , 1 ] ) m1 , m2 = np . meshgrid ( slope ( contour1 ) , slope ( contour2 ) ) m2inv = 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 ) ]
Vectorized code to find intersections between contours.
Vectorized code to find intersections between contours .
"""
        Vectorized code to find intersections between contours. All
        successive duplicate vertices along the input contours must be
        removed to help avoid division-by-zero errors.

        There are cases were no intersection exists (eg. parallel lines)
        where division by zero and invalid value exceptions occur. These
        exceptions should be caught as warnings: these edge cases are
        unavoidable with this algorithm and do not indicate that the
        output is erroneous.
        """ # Elementwise min selection # Elementwise max selection # dstacks, checks True depthwise # Uses delta (using np.diff) to find successive slopes along path # Meshgrids between both paths (x and y). One element sliced off end/beginning # Meshgrid of all slopes for both paths # m1inv was not used. # (xi, yi) is intersection candidate # Bounding box type conditions for intersection candidates
self
contour1
contour2