From 5b05a8f11b2198e099688e3055b0deb7dddd1c60 Mon Sep 17 00:00:00 2001 From: ani37 <44133710+ani37@users.noreply.github.com> Date: Mon, 15 Oct 2018 16:40:08 +0530 Subject: [PATCH] create --- C++/convex_hull | 241 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 241 insertions(+) create mode 100644 C++/convex_hull diff --git a/C++/convex_hull b/C++/convex_hull new file mode 100644 index 000000000..407fa7df1 --- /dev/null +++ b/C++/convex_hull @@ -0,0 +1,241 @@ + +// A divide and conquer program to find convex +// hull of a given set of points. +#include +using namespace std; + +// stores the centre of polygon (It is made +// global because it is used in compare function) +pair mid; + +// determines the quadrant of a point +// (used in compare()) +int quad(pair p) +{ + if (p.first >= 0 && p.second >= 0) + return 1; + if (p.first <= 0 && p.second >= 0) + return 2; + if (p.first <= 0 && p.second <= 0) + return 3; + return 4; +} + +// Checks whether the line is crossing the polygon +int orientation(pair a, pair b, + pair c) +{ + int res = (b.second-a.second)*(c.first-b.first) - + (c.second-b.second)*(b.first-a.first); + + if (res == 0) + return 0; + if (res > 0) + return 1; + return -1; +} + +// compare function for sorting +bool compare(pair p1, pair q1) +{ + pair p = make_pair(p1.first - mid.first, + p1.second - mid.second); + pair q = make_pair(q1.first - mid.first, + q1.second - mid.second); + + int one = quad(p); + int two = quad(q); + + if (one != two) + return (one < two); + return (p.second*q.first < q.second*p.first); +} + +// Finds upper tangent of two polygons 'a' and 'b' +// represented as two vectors. +vector> merger(vector > a, + vector > b) +{ + // n1 -> number of points in polygon a + // n2 -> number of points in polygon b + int n1 = a.size(), n2 = b.size(); + + int ia = 0, ib = 0; + for (int i=1; i a[ia].first) + ia = i; + + // ib -> leftmost point of b + for (int i=1; i=0) + inda = (inda + 1) % n1; + + while (orientation(a[inda], b[indb], b[(n2+indb-1)%n2]) <=0) + { + indb = (n2+indb-1)%n2; + done = 0; + } + } + + int uppera = inda, upperb = indb; + inda = ia, indb=ib; + done = 0; + int g = 0; + while (!done)//finding the lower tangent + { + done = 1; + while (orientation(a[inda], b[indb], b[(indb+1)%n2])>=0) + indb=(indb+1)%n2; + + while (orientation(b[indb], a[inda], a[(n1+inda-1)%n1])<=0) + { + inda=(n1+inda-1)%n1; + done=0; + } + } + + int lowera = inda, lowerb = indb; + vector> ret; + + //ret contains the convex hull after merging the two convex hulls + //with the points sorted in anti-clockwise order + int ind = uppera; + ret.push_back(a[uppera]); + while (ind != lowera) + { + ind = (ind+1)%n1; + ret.push_back(a[ind]); + } + + ind = lowerb; + ret.push_back(b[lowerb]); + while (ind != upperb) + { + ind = (ind+1)%n2; + ret.push_back(b[ind]); + } + return ret; + +} + +// Brute force algorithm to find convex hull for a set +// of less than 6 points +vector> bruteHull(vector> a) +{ + // Take any pair of points from the set and check + // whether it is the edge of the convex hull or not. + // if all the remaining points are on the same side + // of the line then the line is the edge of convex + // hull otherwise not + set >s; + + for (int i=0; i= 0) + pos++; + } + if (pos == a.size() || neg == a.size()) + { + s.insert(a[i]); + s.insert(a[j]); + } + } + } + + vector>ret; + for (auto e:s) + ret.push_back(e); + + // Sorting the points in the anti-clockwise order + mid = {0, 0}; + int n = ret.size(); + for (int i=0; i> divide(vector> a) +{ + // If the number of points is less than 6 then the + // function uses the brute algorithm to find the + // convex hull + if (a.size() <= 5) + return bruteHull(a); + + // left contains the left half points + // right contains the right half points + vector>left, right; + for (int i=0; i>left_hull = divide(left); + vector>right_hull = divide(right); + + // merging the convex hulls + return merger(left_hull, right_hull); +} + +// Driver code +int main() +{ + vector > a; + a.push_back(make_pair(0, 0)); + a.push_back(make_pair(1, -4)); + a.push_back(make_pair(-1, -5)); + a.push_back(make_pair(-5, -3)); + a.push_back(make_pair(-3, -1)); + a.push_back(make_pair(-1, -3)); + a.push_back(make_pair(-2, -2)); + a.push_back(make_pair(-1, -1)); + a.push_back(make_pair(-2, -1)); + a.push_back(make_pair(-1, 1)); + + int n = a.size(); + + // sorting the set of points according + // to the x-coordinate + sort(a.begin(), a.end()); + vector >ans = divide(a); + + cout << "convex hull:\n"; + for (auto e:ans) + cout << e.first << " " + << e.second << endl; + + return 0; +}