Skip to content

Commit d6de773

Browse files
committed
jarvis convux hull
1 parent 931c9df commit d6de773

File tree

1 file changed

+96
-0
lines changed

1 file changed

+96
-0
lines changed

Math/convuxhull/convuxhull.cpp

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#include <bits/stdc++.h>
2+
using namespace std;
3+
4+
struct Point
5+
{
6+
int x, y;
7+
};
8+
9+
// To find orientation of ordered triplet (p, q, r).
10+
// The function returns following values
11+
// 0 --> p, q and r are colinear
12+
// 1 --> Clockwise
13+
// 2 --> Counterclockwise
14+
int orientation(Point p, Point q, Point r)
15+
{
16+
int val = (q.y - p.y) * (r.x - q.x) -
17+
(q.x - p.x) * (r.y - q.y);
18+
19+
if (val == 0) return 0; // colinear
20+
return (val > 0)? 1: 2; // clock or counterclock wise
21+
}
22+
23+
// Prints convex hull of a set of n points.
24+
void convexHull(Point points[], int n)
25+
{
26+
// There must be at least 3 points
27+
if (n < 3) return;
28+
29+
// Initialize Result
30+
vector<Point> hull;
31+
32+
// Find the leftmost point
33+
int l = 0;
34+
for (int i = 1; i < n; i++)
35+
if (points[i].x < points[l].x)
36+
l = i;
37+
38+
// Start from leftmost point, keep moving counterclockwise
39+
// until reach the start point again. This loop runs O(h)
40+
// times where h is number of points in result or output.
41+
int p = l, q;
42+
do
43+
{
44+
// Add current point to result
45+
hull.push_back(points[p]);
46+
47+
// Search for a point 'q' such that orientation(p, x,
48+
// q) is counterclockwise for all points 'x'. The idea
49+
// is to keep track of last visited most counterclock-
50+
// wise point in q. If any point 'i' is more counterclock-
51+
// wise than q, then update q.
52+
q = (p+1)%n;
53+
for (int i = 0; i < n; i++)
54+
{
55+
// If i is more counterclockwise than current q, then
56+
// update q
57+
if (orientation(points[p], points[i], points[q]) == 2)
58+
q = i;
59+
}
60+
61+
// Now q is the most counterclockwise with respect to p
62+
// Set p as q for next iteration, so that q is added to
63+
// result 'hull'
64+
p = q;
65+
66+
} while (p != l); // While we don't come to first point
67+
68+
// Print Result
69+
for (int i = 0; i < hull.size(); i++)
70+
cout << "(" << hull[i].x << ", "
71+
<< hull[i].y << ")\n";
72+
}
73+
74+
75+
int main()
76+
{
77+
Point points[] = {{0, 3}, {2, 2}, {1, 1}, {2, 1},
78+
{3, 0}, {0, 0}, {3, 3}};
79+
int n = sizeof(points)/sizeof(points[0]);
80+
convexHull(points, n);
81+
return 0;
82+
}
83+
84+
85+
/*
86+
Explanation
87+
The idea of Jarvis’s Algorithm is simple, we start from the leftmost point (or point with minimum x coordinate value) and we keep wrapping points in counterclockwise direction. The big question is, given a point p as current point, how to find the next point in output? The idea is to use orientation() here. Next point is selected as the point that beats all other points at counterclockwise orientation, i.e., next point is q if for any other point r, we have “orientation(p, r, q) = counterclockwise”. Following is the detailed algorithm.
88+
89+
1) Initialize p as leftmost point.
90+
2) Do following while we don’t come back to the first (or leftmost) point.
91+
…..a) The next point q is the point such that the triplet (p, q, r) is counterclockwise for any other point r.
92+
…..b) next[p] = q (Store q as next of p in the output convex hull).
93+
…..c) p = q (Set p as q for next iteration).
94+
95+
96+
*/

0 commit comments

Comments
 (0)