static ListDualStack <int> ConvexHullGrahamScan2(Point[] points) { var hull = new ListDualStack <int>(); var sortedIndeces = Enumerable.Range(0, points.Length) .OrderBy(x => points[x].Y) .ToArray(); hull.Add(sortedIndeces[0]); hull.Add(sortedIndeces[1]); for (int i = 2; i < sortedIndeces.Length; ++i) { while (hull.Count > 1) { var area = DirectedArea( points[hull.SecondLast], points[hull.Last], points[sortedIndeces[i]]); if (area > Epsillon) { break; } hull.RemoveLast(); } hull.Add(sortedIndeces[i]); } for (int i = sortedIndeces.Length - 2; i >= 0; --i) { while (hull.Count > 1) { var area = DirectedArea( points[hull.SecondLast], points[hull.Last], points[sortedIndeces[i]]); if (area > Epsillon) { break; } hull.RemoveLast(); } hull.Add(sortedIndeces[i]); } hull.RemoveLast(); return(hull); }
static ListDualStack <int> ConvexHullGrahamScan(Point[] points) { var hull = new ListDualStack <int>(); var firstIndex = 0; for (int i = 1; i < points.Length; ++i) { if (points[firstIndex].Y > points[i].Y) { firstIndex = i; } } hull.Add(firstIndex); var firstPoint = points[firstIndex]; var sortedPoints = new int[points.Length - 1]; for (int i = 0; i < sortedPoints.Length; ++i) { if (i == firstIndex) { sortedPoints[i] = points.Length - 1; } else { sortedPoints[i] = i; } } Array.Sort(sortedPoints, (ia, ib) => { var a = points[ia]; var b = points[ib]; var area = DirectedArea(firstPoint, a, b); if (area < -Epsillon) { return(1); } if (area > Epsillon) { return(-1); } return(0); }); hull.Add(sortedPoints[0]); for (int i = 1; i < sortedPoints.Length; ++i) { var currIndex = sortedPoints[i]; while (true) { var area = DirectedArea( points[hull.SecondLast], points[hull.Last], points[currIndex]); if (area > Epsillon) { break; } hull.RemoveLast(); } hull.Add(currIndex); } while (true) { var area = DirectedArea( points[hull.SecondLast], points[hull.Last], points[hull.First]); if (area > Epsillon) { break; } hull.RemoveLast(); } return(hull); }