private void sortToHandleCollinear(Point[] points, Point start) {
        Arrays.sort(points, (p1, p2) -> {
            if (p1 == start) {
                return -1;
            }
            if (p2 == start) {
                return 1;
            }
            int cp = crossProduct(start, p1, p2);
            if (cp == 0) {
                return distance(start, p1, p2);
            } else {
                return -cp;
            }
        });

        //make sure last collinear points are in reverse order of distance.
        Point p = points[0], q = points[points.length - 1];
        int i = points.length - 2;
        while (i >= 0 && crossProduct(p, q, points[i]) == 0) {
            i--;
        }

        // reverse sort order of collinear points in the end positions
        for (int l = i + 1, h = points.length - 1; l < h; l++, h--) {
            Point tmp = points[l];
            points[l] = points[h];
            points[h] = tmp;
        }
    }
@author Tushar Roy
Date 10/11/2107

Convex hull or convex envelope of a set X of points in the Euclidean plane or in a Euclidean space
(or, more generally, in an affine space over the reals) is the smallest convex set that contains X.

Graham scan finds all vertices of the convex hull ordered along its boundary.

Time complexity O(nlogn)
Space complexity O(n)

References
https://leetcode.com/problems/erect-the-fence/description/
https://en.wikipedia.org/wiki/Convex_hull
https://en.wikipedia.org/wiki/Graham_scan
https://discuss.leetcode.com/topic/89336/java-graham-scan-with-adapted-sorting-to-deal-with-collinear-points
src/com/interview/geometry/GrahamScanConvexHull.java