Skip to content

Commit b80b623

Browse files
Merge pull request #481 from Shivam2498/patch-1
Graham Scan For Convex Hall C++
2 parents 408cab0 + c5e7f25 commit b80b623

File tree

1 file changed

+157
-0
lines changed

1 file changed

+157
-0
lines changed

C++/Graham Scan For Convex Hall

+157
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
// A C++ program to find convex hull of a set of points. Refer
2+
// https://www.geeksforgeeks.org/orientation-3-ordered-points/
3+
// for explanation of orientation()
4+
#include <iostream>
5+
#include <stack>
6+
#include <stdlib.h>
7+
using namespace std;
8+
9+
struct Point
10+
{
11+
int x, y;
12+
};
13+
14+
// A global point needed for sorting points with reference
15+
// to the first point Used in compare function of qsort()
16+
Point p0;
17+
18+
// A utility function to find next to top in a stack
19+
Point nextToTop(stack<Point> &S)
20+
{
21+
Point p = S.top();
22+
S.pop();
23+
Point res = S.top();
24+
S.push(p);
25+
return res;
26+
}
27+
28+
// A utility function to swap two points
29+
int swap(Point &p1, Point &p2)
30+
{
31+
Point temp = p1;
32+
p1 = p2;
33+
p2 = temp;
34+
}
35+
36+
// A utility function to return square of distance
37+
// between p1 and p2
38+
int distSq(Point p1, Point p2)
39+
{
40+
return (p1.x - p2.x)*(p1.x - p2.x) +
41+
(p1.y - p2.y)*(p1.y - p2.y);
42+
}
43+
44+
// To find orientation of ordered triplet (p, q, r).
45+
// The function returns following values
46+
// 0 --> p, q and r are colinear
47+
// 1 --> Clockwise
48+
// 2 --> Counterclockwise
49+
int orientation(Point p, Point q, Point r)
50+
{
51+
int val = (q.y - p.y) * (r.x - q.x) -
52+
(q.x - p.x) * (r.y - q.y);
53+
54+
if (val == 0) return 0; // colinear
55+
return (val > 0)? 1: 2; // clock or counterclock wise
56+
}
57+
58+
// A function used by library function qsort() to sort an array of
59+
// points with respect to the first point
60+
int compare(const void *vp1, const void *vp2)
61+
{
62+
Point *p1 = (Point *)vp1;
63+
Point *p2 = (Point *)vp2;
64+
65+
// Find orientation
66+
int o = orientation(p0, *p1, *p2);
67+
if (o == 0)
68+
return (distSq(p0, *p2) >= distSq(p0, *p1))? -1 : 1;
69+
70+
return (o == 2)? -1: 1;
71+
}
72+
73+
// Prints convex hull of a set of n points.
74+
void convexHull(Point points[], int n)
75+
{
76+
// Find the bottommost point
77+
int ymin = points[0].y, min = 0;
78+
for (int i = 1; i < n; i++)
79+
{
80+
int y = points[i].y;
81+
82+
// Pick the bottom-most or chose the left
83+
// most point in case of tie
84+
if ((y < ymin) || (ymin == y &&
85+
points[i].x < points[min].x))
86+
ymin = points[i].y, min = i;
87+
}
88+
89+
// Place the bottom-most point at first position
90+
swap(points[0], points[min]);
91+
92+
// Sort n-1 points with respect to the first point.
93+
// A point p1 comes before p2 in sorted output if p2
94+
// has larger polar angle (in counterclockwise
95+
// direction) than p1
96+
p0 = points[0];
97+
qsort(&points[1], n-1, sizeof(Point), compare);
98+
99+
// If two or more points make same angle with p0,
100+
// Remove all but the one that is farthest from p0
101+
// Remember that, in above sorting, our criteria was
102+
// to keep the farthest point at the end when more than
103+
// one points have same angle.
104+
int m = 1; // Initialize size of modified array
105+
for (int i=1; i<n; i++)
106+
{
107+
// Keep removing i while angle of i and i+1 is same
108+
// with respect to p0
109+
while (i < n-1 && orientation(p0, points[i],
110+
points[i+1]) == 0)
111+
i++;
112+
113+
114+
points[m] = points[i];
115+
m++; // Update size of modified array
116+
}
117+
118+
// If modified array of points has less than 3 points,
119+
// convex hull is not possible
120+
if (m < 3) return;
121+
122+
// Create an empty stack and push first three points
123+
// to it.
124+
stack<Point> S;
125+
S.push(points[0]);
126+
S.push(points[1]);
127+
S.push(points[2]);
128+
129+
// Process remaining n-3 points
130+
for (int i = 3; i < m; i++)
131+
{
132+
// Keep removing top while the angle formed by
133+
// points next-to-top, top, and points[i] makes
134+
// a non-left turn
135+
while (orientation(nextToTop(S), S.top(), points[i]) != 2)
136+
S.pop();
137+
S.push(points[i]);
138+
}
139+
140+
// Now stack has the output points, print contents of stack
141+
while (!S.empty())
142+
{
143+
Point p = S.top();
144+
cout << "(" << p.x << ", " << p.y <<")" << endl;
145+
S.pop();
146+
}
147+
}
148+
149+
// Driver program to test above functions
150+
int main()
151+
{
152+
Point points[] = {{0, 3}, {1, 1}, {2, 2}, {4, 4},
153+
{0, 0}, {1, 2}, {3, 1}, {3, 3}};
154+
int n = sizeof(points)/sizeof(points[0]);
155+
convexHull(points, n);
156+
return 0;
157+
}

0 commit comments

Comments
 (0)