From 7105397e5d51a697cd8ee7190639b6ead7d5d812 Mon Sep 17 00:00:00 2001 From: AYUSH GUPTA <98117063+ayush-1123@users.noreply.github.com> Date: Sat, 22 Oct 2022 12:15:09 +0530 Subject: [PATCH] Create Convex Hull C++ Program to Implement Graham Scan Algorithm to find the Convex Hull for a set of points. --- Convex Hull | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 Convex Hull diff --git a/Convex Hull b/Convex Hull new file mode 100644 index 0000000..e2c696e --- /dev/null +++ b/Convex Hull @@ -0,0 +1,119 @@ +#include +#include +#include +using namespace std; + +struct Point +{ + int x; + int y; +}; + +Point p0; + +// A utility function to find next to top in a stack +Point nextToTop(stack &S) +{ + Point p = S.top(); + S.pop(); + Point res = S.top(); + S.push(p); + return res; +} + +// A utility function to swap two points +int swap(Point &p1, Point &p2) +{ + Point temp = p1; + p1 = p2; + p2 = temp; +} + +// A utility function to return square of distance between p1 and p2 +int dist(Point p1, Point p2) +{ + return (p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y); +} + +int orientation(Point p, Point q, Point r) +{ + int val = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y); + + if (val == 0) + return 0; // colinear + return (val > 0) ? 1 : 2; // clock or counterclock wise +} + +// A function used by library function qsort() to sort an array of +// points with respect to the first point +int compare(const void *vp1, const void *vp2) +{ + Point *p1 = (Point *) vp1; + Point *p2 = (Point *) vp2; + + // Find orientation + int o = orientation(p0, *p1, *p2); + if (o == 0) + return (dist(p0, *p2) >= dist(p0, *p1)) ? -1 : 1; + + return (o == 2) ? -1 : 1; +} + +// Prints convex hull of a set of n points. +void convexHull(Point points[], int n) +{ + // Find the bottommost point + int ymin = points[0].y, min = 0; + for (int i = 1; i < n; i++) + { + int y = points[i].y; + + // Pick the bottom-most or chose the left most point in case of tie + if ((y < ymin) || (ymin == y && points[i].x < points[min].x)) + ymin = points[i].y, min = i; + } + + // Place the bottom-most point at first position + swap(points[0], points[min]); + + // Sort n-1 points with respect to the first point. A point p1 comes + // before p2 in sorted ouput if p2 has larger polar angle (in + // counterclockwise direction) than p1 + p0 = points[0]; + qsort(&points[1], n - 1, sizeof(Point), compare); + + // Create an empty stack and push first three points to it. + stack S; + S.push(points[0]); + S.push(points[1]); + S.push(points[2]); + + // Process remaining n-3 points + for (int i = 3; i < n; i++) + { + // Keep removing top while the angle formed by points next-to-top, + // top, and points[i] makes a non-left turn + while (orientation(nextToTop(S), S.top(), points[i]) != 2) + S.pop(); + S.push(points[i]); + } + + // Now stack has the output points, print contents of stack + while (!S.empty()) + { + Point p = S.top(); + cout << "(" << p.x << ", " << p.y << ")" << endl; + S.pop(); + } +} + +// Driver program +int main() +{ + Point points[] = { { 0, 3 }, { 1, 1 }, { 2, 2 }, { 4, 4 }, { 0, 0 }, + { 1, 2 }, { 3, 1 }, { 3, 3 } }; + int n = sizeof(points) / sizeof(points[0]); + cout << "The points in the convex hull are: \n"; + convexHull(points, n); + return 0; +}