/// <summary> /// Uses the Andrew variant of the Graham formula for calculating /// convex hulls. /// </summary> /// <param name="points"></param> /// <returns></returns> public Point[] CalculateConvexHull(Point[] points) { if (points.Length < 3) { return(points); } // TODO: Implement a quicksort algorithm, and find cut off point for switching algorithms. points = BubblesortPoints(points); List <Point> upper = new List <Point>(); upper.Add(points[0]); upper.Add(points[1]); for (int i = 2; i < points.Length; i++) { upper.Add(points[i]); while (upper.Count > 2 && !ExtraMath.IsRightTurn(upper[upper.Count - 3], upper[upper.Count - 2], upper[upper.Count - 1])) { upper.RemoveAt(upper.Count - 2); } } List <Point> lower = new List <Point>(); lower.Add(points[points.Length - 1]); lower.Add(points[points.Length - 2]); for (int i = points.Length - 3; i >= 0; i--) { lower.Add(points[i]); while (lower.Count > 2 && !ExtraMath.IsRightTurn(lower[lower.Count - 3], lower[lower.Count - 2], lower[lower.Count - 1])) { lower.RemoveAt(lower.Count - 2); } } Point[] retPoints = new Point[upper.Count + lower.Count]; for (int i = 0; i < upper.Count; i++) { retPoints[i] = upper[i]; } for (int i = 0; i < lower.Count; i++) { retPoints[i + upper.Count] = lower[i]; } return(retPoints); }