-
Notifications
You must be signed in to change notification settings - Fork 299
/
Copy pathConvexHull.cs
77 lines (58 loc) · 2.06 KB
/
ConvexHull.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
using System.Collections.Generic;
namespace Advanced.Algorithms.Geometry;
/// <summary>
/// Convex hull using jarvis's algorithm.
/// </summary>
public class ConvexHull
{
public static List<int[]> Find(List<int[]> points)
{
var currentPointIndex = FindLeftMostPoint(points);
var startingPointIndex = currentPointIndex;
var result = new List<int[]>();
do
{
result.Add(points[currentPointIndex]);
//pick a random point as next Point
var nextPointIndex = (currentPointIndex + 1) % points.Count;
for (var i = 0; i < points.Count; i++)
{
if (i == nextPointIndex) continue;
var orientation = GetOrientation(points[currentPointIndex],
points[i], points[nextPointIndex]);
if (orientation == Orientation.ClockWise) nextPointIndex = i;
}
currentPointIndex = nextPointIndex;
} while (currentPointIndex != startingPointIndex);
return result;
}
/// <summary>
/// Compute the orientation of the lines formed by points p, q and r
/// </summary>
private static Orientation GetOrientation(int[] p, int[] q, int[] r)
{
int x1 = p[0], y1 = p[1];
int x2 = q[0], y2 = q[1];
int x3 = r[0], y3 = r[1];
//using slope formula => (y2-y1)/(x2-x1) = (y3-y2)/(x3-x2) (if colinear)
// derives to (y2-y1)(x3-x2)-(y3-y2)(x2-x1) == 0
var result = (y2 - y1) * (x3 - x2) - (y3 - y2) * (x2 - x1);
//sign will give the direction
if (result < 0) return Orientation.ClockWise;
return result > 0 ? Orientation.AntiClockWise : Orientation.Colinear;
}
private static int FindLeftMostPoint(List<int[]> points)
{
var left = 0;
for (var i = 1; i < points.Count; i++)
if (points[i][0] < points[left][0])
left = i;
return left;
}
private enum Orientation
{
ClockWise = 0,
AntiClockWise = 1,
Colinear = 2
}
}