using System;
using System.Collections.Generic;
using System.Linq;
namespaceConvexHull{
publicclassPoint {
publicint X { get; set; }
publicint Y { get; set; }
}
publicstaticclassConvexHull {
privatestaticintCrossProduct(Point o, Point a, Point b) {
return (a.X - o.X) * (b.Y - o.Y) - (a.Y - o.Y) * (b.X - o.X);
}
publicstatic List<Point> GetConvexHull(List<Point> points) {
if (points.Count <= 1)
return points;
var sortedPoints = points.OrderBy(p => p.X).ThenBy(p => p.Y).ToList();
var lower = new List<Point>();
for (var i = 0; i < sortedPoints.Count; i++)
{
while (lower.Count >= 2 && CrossProduct(lower[lower.Count - 2], lower[lower.Count - 1], sortedPoints[i]) <= 0)
lower.RemoveAt(lower.Count - 1);
lower.Add(sortedPoints[i]);
}
var upper = new List<Point>();
for (var i = sortedPoints.Count - 1; i >= 0; i--)
{
while (upper.Count >= 2 && CrossProduct(upper[upper.Count - 2], upper[upper.Count - 1], sortedPoints[i]) <= 0)
upper.RemoveAt(upper.Count - 1);
upper.Add(sortedPoints[i]);
}
upper.RemoveAt(0);
lower.RemoveAt(lower.Count - 1);
return lower.Concat(upper).ToList();
}
}
classProgram {
staticvoidMain(string[] args) {
/* Example usage: */var points = new List<Point>()
{
new Point { X = 1, Y = 1 },
new Point { X = 2, Y = 3 },
new Point { X = 3, Y = 2 },
new Point { X = 4, Y = 4 },
new Point { X = 5, Y = 1 },
new Point { X = 6, Y = 3 },
new Point { X = 7, Y = 2 },
new Point { X = 8, Y = 4 },
new Point { X = 9, Y = 1 },
};
var convexHull = ConvexHull.GetConvexHull(points);
foreach (var point in convexHull)
{
Console.WriteLine($"({point.X}, {point.Y})");
}
}
}
}