def points_in_triangle_2d(pts, triangle):
    """
    pts: * x 2
    triangle: 3 x 2

    Returns a binary mask of which points fall inside the 2D triangle
    """

    def sign(pts, v0, v1):
        return (pts[..., 0] - v1[0]) * (v0[1] - v1[1]) - (v0[0] - v1[0]) * (
            pts[..., 1] - v1[1])

    d1 = sign(pts, triangle[0, :], triangle[1, :])
    d2 = sign(pts, triangle[1, :], triangle[2, :])
    d3 = sign(pts, triangle[2, :], triangle[0, :])
    has_neg = (d1 < 0) | (d2 < 0) | (d3 < 0)
    has_pos = (d1 > 0) | (d2 > 0) | (d3 > 0)
    return ~(has_neg & has_pos)