'Return True if p is enclosed by (is inside of) self.
Notes
Being on the border of self is considered False.
Parameters
p : Point
Returns
encloses_point : True, False or None
See Also
sympy.geometry.point.Point, sympy.geometry.ellipse.Ellipse.encloses_point
Examples
>>> from sympy import Polygon, Point
>>> from sympy.abc import t
>>> p = Polygon((0, 0), (4, 0), (4, 4))
>>> p.encloses_point(Point(2, 1))
True
>>> p.encloses_point(Point(2, 2))
False
>>> p.encloses_point(Point(5, 5))
False
References
[1] http://paulbourke.net/geometry/polygonmesh/#insidepoly'

def encloses_point(self, p):

    p = Point(p, dim=2)
    if ((p in self.vertices) or any(((p in s) for s in self.sides))):
        return False
    lit = []
    for v in self.vertices:
        lit.append((v - p))
        if lit[(-1)].free_symbols:
            return None
    poly = Polygon(*lit)
    args = poly.args
    indices = list(range((- len(args)), 1))
    if poly.is_convex():
        orientation = None
        for i in indices:
            a = args[i]
            b = args[(i + 1)]
            test = (((- a.y) * (b.x - a.x)) - ((- a.x) * (b.y - a.y))).is_negative
            if (orientation is None):
                orientation = test
            elif (test is not orientation):
                return False
        return True
    hit_odd = False
    (p1x, p1y) = args[0].args
    for i in indices[1:]:
        (p2x, p2y) = args[i].args
        if (0 > min(p1y, p2y)):
            if (0 <= max(p1y, p2y)):
                if (0 <= max(p1x, p2x)):
                    if (p1y != p2y):
                        xinters = ((((- p1y) * (p2x - p1x)) / (p2y - p1y)) + p1x)
                        if ((p1x == p2x) or (0 <= xinters)):
                            hit_odd = (not hit_odd)
        (p1x, p1y) = (p2x, p2y)
    return hit_odd
