-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjarvisMarch.cpp
68 lines (64 loc) · 1.79 KB
/
jarvisMarch.cpp
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
/** @file */
#include "jarvisMarch.hpp"
#include <cmath>
std::vector<Point> jarvisMarch(std::vector<Point> points)
{
if (points.size() <= 2)
{
return points;
}
// Select any point of CH as origin
Point origin = points[0];
for (Point point : points)
{
if (point.x < origin.x)
{
origin = point;
}
else if (point.x == origin.x && point.y < origin.y)
{
origin = point;
}
}
std::vector<Point> convex_hull;
// Push origin to CH
convex_hull.push_back(origin);
// Keep looping till the new point is same as the 1st point in CH
while (true)
{
Point minimumAnglePoint = origin;
for (Point point : points)
{
if (point == origin)
{
continue;
}
long double area = signedTriangleArea(origin, minimumAnglePoint, point);
if (area < 0 || minimumAnglePoint == origin)
{
// area less than 0 means new point makes a smaller angle
minimumAnglePoint = point;
}
else if (area == 0)
{
// if current point is collinear to the minimum Angle point, choose the closer one
if (std::abs(origin.x - point.x) > std::abs(origin.x - minimumAnglePoint.x))
{
minimumAnglePoint = point;
}
}
}
if (convex_hull[0] == minimumAnglePoint)
{
// break if 1st point is reached again
break;
}
else
{
// push current point to CH and make this origin
convex_hull.push_back(minimumAnglePoint);
origin = minimumAnglePoint;
}
}
return convex_hull;
}