In [1]:
__author__ = "Víctor Adolfo Gallego Alcalá, Ana María Martínez Gómez"
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np

class Point:
    
    """ This class represents a point in the plane.
    
    __author__ = "Víctor Adolfo Gallego Alcalá, Ana María Martínez Gómez"
    
    __________
    Attributes
    __________
    
    x : float
        x-coordinate of the point
    y : float
        y-coordinate of the point
    name : string
        contains its coordinates
    """
    
    def __init__(self, x=None, y=None):
        """ Initialize the point by giving it its x and y coordinates
        """
        self.x = x
        self.y = y
        self.name = "( " + str(x) + ", " + str(y) + " )"
    
    def __repr__(self):
        """ Returns its name
        """
        return self.name
    
    def __le__(self, p):
        """ Method for <=
        """
        return self.x <= p.x
    
    def __lt__(self, p):
        """ Method for <
        """
        return self.x < p.x
    
    def isLeft(self, p2, p3):
        """ Returns 1 iff self is to the left of the segment p2p3, 0 iff it is
        collinear and -1 iff it is to the right. It computes the sign of the determinant of
        
        self.x self.y 1
         p2.x p2.y 1
         p3.x p3.y 1
        """
        return np.sign(-p2.x*self.y + p3.x*self.y + self.x*p2.y - p3.x*p2.y - self.x*p3.y + p2.x*p3.y)

In [5]:
P = [Point(20*np.random.rand() - 10,20*np.random.rand() - 10) for i in range(50)]
for p in P:
    plt.plot(p.x, p.y, 'ok')



In [6]:
def rightTurn(P):
    """ Helper function. Returns true iff the list of
    three points P is a turn to the right
    """
    return P[-1].isLeft(P[-3], P[-2]) == -1

def convexHull(P):
    """ Convex hull implemented using Graham's algorithm
    """
    P.sort()
    Lupper = P[:2]
    for p in P[2:]:
        Lupper.append(p)
        while len(Lupper)>2 and not rightTurn(Lupper[-3:]):
            del Lupper[-2]

    P.reverse()
    Llower = P[:2]
    for p in P[2:]:
        Llower.append(p)
        while len(Llower)>2 and not rightTurn(Llower[-3:]):
            del Llower[-2]
    del Llower[0]
    del Llower[-1]
    Lupper += Llower
    return Lupper

In [7]:
L = convexHull(P)
L.append(L[0])
plt.hold(True)
for i in range(len(L)-1):
    plt.plot([L[i].x, L[i+1].x], [L[i].y, L[i+1].y], 'r')
    
for p in P:
    plt.plot(p.x, p.y, 'ok')



In [ ]: