forked from algorithm-archivists/algorithm-archive
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjarvis_march.cpp
77 lines (63 loc) · 1.71 KB
/
jarvis_march.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
69
70
71
72
73
74
75
76
77
#include <vector>
#include <iostream>
#include <algorithm>
struct Point
{
double x, y;
bool operator==(const Point& b) const
{
return x == b.x && y == b.y;
}
bool operator!=(const Point& b) const
{
return !(*this == b);
}
};
std::vector<Point> jarvis_march(const std::vector<Point>& points)
{
std::vector<Point> hull_points;
if(points.empty())
return hull_points;
// Left most point
auto first_point_it = std::min_element(points.begin(), points.end(), [](const Point& a, const Point& b){ return a.x < b.x; });
auto next_point_it = first_point_it;
do
{
hull_points.push_back(*next_point_it);
const Point& p1 = hull_points.back();
// Largest internal angle
next_point_it = std::max_element(
points.begin(),
points.end(),
[p1](const Point& p2, const Point& p3){
return (p1 == p2) || (p2.x - p1.x) * (p3.y - p1.y) > (p3.x - p1.x) * (p2.y - p1.y);
}
);
}
while(*next_point_it != *first_point_it);
return hull_points;
}
int main() {
std::vector<Point> points = {
{ -5.0, 2.0 },
{ 5.0, 7.0 },
{ -6.0, -12.0 },
{ -14.0, -14.0 },
{ 9.0, 9.0 },
{ -1.0, -1.0 },
{ -10.0, 11.0 },
{ -6.0, 15.0 },
{ -6.0, -8.0 },
{ 15.0, -9.0 },
{ 7.0, -7.0 },
{ -2.0, -9.0 },
{ 6.0, -5.0 },
{ 0.0, 14.0 },
{ 2.0, 8.0 }
};
auto hull_points = jarvis_march(points);
std::cout << "Hull points are:" << std::endl;
for(const Point& point : hull_points) {
std::cout << '(' << point.x << ", " << point.y << ')' << std::endl;
}
}