grahamScan = p => {
  if (p.length <= 3) {
    return p;
  }
  preprocessing(p);
  const convexHull = [p[0], p[1]];
  for (let i = 2; i < p.length; i++) {
    let j = convexHull.length;
    while (
      j >= 2 &&
      !vectorOp.isCounterClockwise(convexHull[j - 2], convexHull[j - 1], p[i])
    ) {
      convexHull.pop();
      j--;
    }
    convexHull.push(p[i]);
  }
  return convexHull;
}
Given an array p with N points on a two dimensional space,
the function grahamScan calculates the convex hull of p
in O(N * log(N)) time and using O(N) space.
Implemented algorithm: Graham's Scan.

@param An array p with N points, each point should be a literal,
example: {x:0,y:0}.
@return An array p' with N' points which belongs to the convex hull of p.

Note: If exists a subset S of p that contains only collinear points
which are present on the convex hull of p, then only the pair with
the largest distance will be present on p'.