public static MyPoint[] convexhull(MyPoint[] pts) { // Отсортировать точки по увеличению (x, y) int N = pts.Length; Polysort.Quicksort <MyPoint>(pts); MyPoint left = pts[0], right = pts[N - 1]; // Разделить на список нижних граней и верхних граней CDLL <MyPoint> lower = new CDLL <MyPoint>(left), upper = new CDLL <MyPoint>(left); for (int i = 0; i < N; i++) { double det = MyPoint.Area2(left, right, pts[i]); if (det > 0) { upper = upper.Append(new CDLL <MyPoint>(pts[i])); } else if (det < 0) { lower = lower.Prepend(new CDLL <MyPoint>(pts[i])); } } lower = lower.Prepend(new CDLL <MyPoint>(right)); upper = upper.Append(new CDLL <MyPoint>(right)).Next; // Устранить точки не на многоуголнике eliminate(lower); eliminate(upper); // Устранить повторяющиеся точки try { if (lower.Prev.val.Equals(upper.val)) { lower.Prev.Delete(); } if (upper.Prev.val.Equals(lower.val)) { upper.Prev.Delete(); } } catch { // DO NOTHING!!! JUST SKIP ERROR } // Соединяем нижние и верхние грани MyPoint[] res = new MyPoint[lower.Size() + upper.Size()]; lower.CopyInto(res, 0); upper.CopyInto(res, lower.Size()); return(res); }
public static Vec2d[] GetConvexHull(Vec2d[] pts) { // Sort points lexicographically by increasing (x, y) int N = pts.Length; quicksort(pts); Vec2d left = pts[0], right = pts[N - 1]; // Partition into lower hull and upper hull CDLL <Vec2d> lower = new CDLL <Vec2d>(left), upper = new CDLL <Vec2d>(left); for (int i = 0; i < N; i++) { double det = area2(left, right, pts[i]); if (det > 0) { upper = upper.Append(new CDLL <Vec2d>(pts[i])); } else if (det < 0) { lower = lower.Prepend(new CDLL <Vec2d>(pts[i])); } } lower = lower.Prepend(new CDLL <Vec2d>(right)); upper = upper.Append(new CDLL <Vec2d>(right)).Next; // Eliminate points not on the hull eliminate(lower); eliminate(upper); // Eliminate duplicate endpoints if (lower.Prev.val.Equals(upper.val)) { lower.Prev.Delete(); } if (upper.Prev.val.Equals(lower.val)) { upper.Prev.Delete(); } // Join the lower and upper hull Vec2d[] res = new Vec2d[lower.Size() + upper.Size()]; lower.CopyInto(res, 0); upper.CopyInto(res, lower.Size()); return(res); }