def pip_cn(p, poly):
    """2D point inclusion: returns True if point is inside polygon (uses crossing number algorithm).

    arguments:
       p (numpy array, tuple or list of at least 2 floats): xy point to test for inclusion in polygon
       poly (2D numpy array, tuple or list of tuples or lists of at least 2 floats): the xy points
          defining a polygon

    returns:
       boolean: True if point is within the polygon

    note:
       if the polygon is represented by a closed resqpy Polyline, pass Polyline.coordinates as poly
    """

    # p should be a tuple-like object with first two elements x, y
    # poly should be a numpy array with first axis being the different vertices
    #    and the second starting x, y

    crossings = 0

    for edge in range(len(poly)):
        v1 = poly[edge - 1]
        v2 = poly[edge]
        if ((v1[0] > p[0] or v2[0] > p[0]) and ((v1[1] <= p[1] and v2[1] > p[1]) or (v1[1] > p[1] and v2[1] <= p[1]))):
            if v1[0] > p[0] and v2[0] > p[0]:
                crossings += 1
            elif p[0] < v1[0] + (v2[0] - v1[0]) * (p[1] - v1[1]) / (v2[1] - v1[1]):
                crossings += 1

    return bool(crossings & 1)