-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathConvexHull.cpp
More file actions
73 lines (62 loc) · 1.82 KB
/
ConvexHull.cpp
File metadata and controls
73 lines (62 loc) · 1.82 KB
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
#include "Graphics.h"
#include <vector>
#include <algorithm>
namespace CG {
Polygon ConvexHull(std::vector<Point>& points)
{
/*
Input: a vector of **distinct** points
Output: a Polygon object describing the bounding polygon of the convex
hull in clockwise order, starting from the left-most point.
This algorithm is an implementation of the incremental algorithm,
described in [de Berg, van Kreveld et. al.]
*/
if (points.size() <= 2)
return Polygon(points);
std::vector<Point> upper_hull, lower_hull;
Polygon convex_hull;
int n = points.size();
sort(points.begin(), points.end());
upper_hull.push_back(points[0]);
upper_hull.push_back(points[1]);
for (int i = 2; i < n; ++i) {
upper_hull.push_back(points[i]);
int m = upper_hull.size();
Point p = upper_hull[m-3];
Point q = upper_hull[m-2];
Point r = upper_hull[m-1];
LineSegment l(p, q);
while (l.pointOnLeft(r) && upper_hull.size() > 2) {
upper_hull.erase(upper_hull.begin() + (m-2));
m = upper_hull.size();
p = upper_hull[m-3];
q = upper_hull[m-2];
l = LineSegment(p, q);
}
}
for (int i = 0; i < upper_hull.size(); ++i) {
convex_hull.points.push_back(upper_hull[i]);
}
lower_hull.push_back(points[n-1]);
lower_hull.push_back(points[n-2]);
for (int i = n-3; i >= 0; --i) {
lower_hull.push_back(points[i]);
int m = lower_hull.size();
Point p = lower_hull[m-3];
Point q = lower_hull[m-2];
Point r = lower_hull[m-1];
LineSegment l(p, q);
while (l.pointOnLeft(r) && lower_hull.size() > 2) {
lower_hull.erase(lower_hull.begin() + (m-2));
m = lower_hull.size();
p = lower_hull[m-3];
q = lower_hull[m-2];
l = LineSegment(p, q);
}
}
for (int i = 1; i < lower_hull.size()-1; ++i) {
convex_hull.points.push_back(lower_hull[i]);
}
return convex_hull;
}
}