Convex Hull

Convex Hull (Graham's Scan)
Let point P be the leftmost bottommost point. That is, the point with lowest y-coordinate, with ties broken by lowest x-coordinate.

Sort all other points, Q, by increasing angle from the x-axis to PQ, with ties broken by farther away points first.

Go through all points adding them to a stack as long as you make a left-hand turn to get to them (positive cross-product). If you make a right-hand turn, backtrack until you make a left-hand turn.

Runtime = O(n log n) to sort +  O(n) to scan = O(n log n)

Java
import java.util.*; import java.awt.*; public class Main { 	static Comparator cmp = new Comparator { 		public int compare(Point p, Point q) 		{ double tp = Math.atan2(p.y-a[0].y, p.x-a[0].x); double tq = Math.atan2(q.y-a[0].y, q.x-a[0].x); if(tp < tq) return -1; else if(tp > tq) return 1; double dp = dist(p, a[0]); double dq = dist(q, a[0]); if(dp > dq) return -1; else if(dp < dq) return 1; return 0; } 	}; 	static Point[] a; 	public static void main(String args[]) throws Throwable { 		// Assuming that a is prepopulated // Get leftmost bottommost point and put it to the front // Then sort for Graham's Scan int cur = 0; for(int i=1;i < n;i++) if(a[i].y < a[cur].y || (a[i].y == a[cur].y && a[i].x < a[cur].x)) cur = i; 		Point tmp = a[cur]; a[cur] = a[0]; a[0] = tmp; Arrays.sort(a, 1, n, cmp); //Graham's Scan Stack s = new Stack; s.push(a[0]); s.push(a[1]); for(int i=2;i < n;i++) { 			while(cp(s.elementAt(s.size-2), s.peek, a[i]) < 0) s.pop; if(cp(s.elementAt(s.size-2), s.peek, a[i]) > 0) //Change this to >= if you want collinear points as well s.push(a[i]); } 		Point[] h = new Point[s.size]; //Hull for(int i=0;i < h.length;i++) h[i] = s.pop; } 	public static double dist(Point p, Point q) 	{ return Math.hypot(p.x - q.x, p.y - q.y); } 	public static double cp(Point p, Point q, Point r) 	{ double pqx = q.x - p.x; 		double pqy = q.y - p.y; 		double qrx = r.x - q.x; 		double qry = r.y - q.y; 		return pqx*qry - pqy*qrx; } }