using
System;
using
System.Collections.Generic;
using
System.Linq;
public
struct
Point
{
public
int
x, y;
}
public
class
Program
{
static
Point p0;
static
void
Main()
{
Point[] points =
new
Point[]
{
new
Point { x = 0, y = 3 },
new
Point { x = 1, y = 1 },
new
Point { x = 2, y = 2 },
new
Point { x = 4, y = 4 },
new
Point { x = 0, y = 0 },
new
Point { x = 1, y = 2 },
new
Point { x = 3, y = 1 },
new
Point { x = 3, y = 3 }
};
Console.WriteLine(
"Vertices of the convex hull:"
);
ConvexHull(points, points.Length);
}
static
int
Orientation(Point p, Point q, Point r)
{
int
val = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
if
(val == 0)
return
0;
return
(val > 0) ? 2 : 1;
}
static
int
Compare(Point p1, Point p2)
{
int
o = Orientation(p0, p1, p2);
if
(o == 0)
return
(DistSq(p0, p2) >= DistSq(p0, p1)) ? -1 : 1;
return
(o == 2) ? -1 : 1;
}
static
int
DistSq(Point p1, Point p2)
{
return
(p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y);
}
static
void
ConvexHull(Point[] points,
int
n)
{
int
ymin = points[0].y, min = 0;
for
(
int
i = 1; i < n; i++)
{
int
y = points[i].y;
if
((y < ymin) || (ymin == y && points[i].x < points[min].x))
ymin = points[i].y;
min = i;
}
var
temp = points[0];
points[0] = points[min];
points[min] = temp;
p0 = points[0];
Array.Sort(points, Compare);
int
m = 1;
for
(
int
i = 1; i < n; i++)
{
while
(i < n - 1 && Orientation(p0, points[i], points[i + 1]) == 0)
i++;
points[m] = points[i];
m++;
}
if
(m < 3)
return
;
Stack<Point> hull =
new
Stack<Point>();
hull.Push(points[0]);
hull.Push(points[1]);
hull.Push(points[2]);
for
(
int
i = 3; i < m; i++)
{
while
(hull.Count > 1 && Orientation(NextToTop(hull), hull.Peek(), points[i]) != 2)
hull.Pop();
hull.Push(points[i]);
}
while
(hull.Any())
{
Point p = hull.Peek();
Console.WriteLine(
"("
+ p.x +
", "
+ p.y +
")"
);
hull.Pop();
}
}
static
Point NextToTop(Stack<Point> S)
{
Point p = S.Pop();
Point res = S.Peek();
S.Push(p);
return
res;
}
}