docs: def _convexhull(P):
      """ Private function that calculate the convex hull of a set of points
      The algorithm was taken from [1].
      http://code.activestate.com/recipes/66527-finding-the-convex-hull-of-a-set-of-2d-points/
  
      References
      ----------
  
      .. [1] Alex Martelli, Anna Ravenscroft, David Ascher, 'Python Cookbook', O'Reilly Media, Inc., 2005.
      """
  
      def mydet(p, q, r):
          """Calc. determinant of a special matrix with three 2D points.
  
          The sign, "-" or "+", determines the side, right or left,
          respectivly, on which the point r lies, when measured against
          a directed vector from p to q.
          """
  
          # We use Sarrus' Rule to calculate the determinant.
          # (could also use the Numeric package...)
          sum1 = q[0] * r[1] + p[0] * q[1] + r[0] * p[1]
          sum2 = q[0] * p[1] + r[0] * q[1] + p[0] * r[1]
  
          return sum1 - sum2
  
  
      def isrightturn(p, q, r):
          "Do the vectors pq:qr form a right turn, or not?"
  
          assert p != q and q != r and p != r
  
          if mydet(p, q, r) < 0:
              return 1
          else:
              return 0
  
      # Get a local list copy of the points and sort them lexically.
      points = copy.copy(P)
      points.sort()
  
      # Build upper half of the hull.
      upper = [points[0], points[1]]
      for p in points[2:]:
          upper.append(p)
          while len(upper) > 2 and not isrightturn(upper[-3:][0],upper[-3:][1],upper[-3:][2]):
              del upper[-2]
  
      # Build lower half of the hull.
      points.reverse()
      lower = [points[0], points[1]]
      for p in points[2:]:
          lower.append(p)
          while len(lower) > 2 and not isrightturn(lower[-3:][0],lower[-3:][1],lower[-3:][2]):
              del lower[-2]
  
      # Remove duplicates.
      del lower[0]
      del lower[-1]
  
      # Concatenate both halfs and return.
      return tuple(upper + lower)