Solving convex hull problem by divide and conquer method

Source: Internet
Author: User

Convex hull means a convex polygon containing all the given points.


Enter a set of points that have X, Y coordinates set. The output is the convex hull of this set of points.

Example:

Input:points[] = {(0, 0), (0, 4), ( -4, 0), (5, 0), (0,-6), (1, 0)};
Output: (-4, 0), (5, 0), (0,-6), (0, 4)

Pre-Knowledge:

A tangent between two convex polygons.

algorithm:

A collection of points is known, and we already know their convex hull. Assuming that we already know the convex hull of the left and right halves, the problem now becomes the merging of the two convex packages, and the convex hull of the entire set is determined.

This step can be done by locating the upper and lower tangents of the left and right two convex packages. This is the tangent between the two convex polygons.

Set the convex hull on the left to a, and the convex hull on the right to B. The following tangents and the above tangents are 1 and 2, respectively, as shown in the figure.

Then the red line draws the last convex bag.


Now that the problem has not been solved completely, how can we find the whole convex hull around. Here recursion appears in the graph, we can partition the points in the collection until the number of points in each set is very small, such as 5 points, and then we can find the convex hull of this set by brute force method. For the entire set of points, the entire convex hull can be obtained during the merge process.

Note:

We have used brute force algorithms to get the convex hull of a small set of points, the time complexity of this step is O (n3) O (n^3). However, some people suggest that the convex hull of a 3 or fewer point set is the entire set of points. This is generally not a problem, but when we want to merge a two-point left convex hull and a 3-point right convex packet, in some special cases the program will fall into an infinite loop. So in order to solve this problem, we can directly find 5 or less convex hull in O (n3) O (n^3) time, although the number is a little bit large, but it does not affect the overall time complexity of the algorithm.

A divide and conquer program to find convex//hull of a given set of points.

#include <iostream> #include <vector> #include <set> #include <algorithm> using namespace std;

Stores the center of Polygon (it is made//global becuase it's used in Comare function) Pair<int, int> mid; Determines the quadrant of a point//(used in compare ()) int quad (pair<int, int> p) {if (p.first >= 0 &A
    mp;& 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<int, int> A, pair<int, int> B,  Pair<int, int> 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<int, int> p1, Pair<int, int> Q1) {pair<int, int> p = ma
    Ke_pair (P1.first-mid.first, P1.second-mid.second);

    Pair<int, int> q = Make_pair (Q1.first-mid.first, Q1.second-mid.second);
    int one = quad (p);

    int: quad (q);
    if (one! =) return (one < both);
Return (P.second*q.first < Q.second*p.first);
}//Finds upper tangent of both polygons ' a ' and ' B '//represented as both vectors. Vector<pair<int, int>> merger (Vector<pair<int, Int> > A, vector<pair<int, int> > 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<n1; i++) if (A[i].first > A[ia].first) ia = i; IB-Leftmost point of B for (int i = 1; i<n2; i++) if (B[i].first < B[ib].firST) IB = i;
    Finding the upper tangent int inda = ia, indb = IB;
    bool done = 0;
        while (!done) {done = 1;

        while (orientation (b[indb], A[inda], a[(Inda + 1)% N1]) >= 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<pair<int, int>> ret; RET contains the convex hull after merging the both 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<pair<int, int>> Brut Ehull (Vector<pair<int, int>> a) {/take any pair of points from the set and check//whether it is T
    He edge of the convex hull or not. If all the remaining points be on the same side//of the line then the line is the edge of convex//Hull oth

    Erwise not Set<pair<int, int> > S; for (int i = 0; I<a.size (); i++) {for (int j = i + 1; j<a.size (); j + +) {int x1 = A[i].first, X
            2 = A[j].first; int y1 = A[i].second, y2 = A[j].second;
            int a1 = Y1-y2;
            int b1 = x2-x1;
            int C1 = X1*Y2-Y1*X2;
            int pos = 0, neg = 0;
                    for (int k = 0; K<a.size (); k++) {if (A1*a[k].first + b1*a[k].second + C1 <= 0)
                neg++;
            if (A1*a[k].first + b1*a[k].second + C1 >= 0) pos++;
                } if (pos = = a.size () | | neg = = a.size ()) {S.insert (a[i]);
            S.insert (A[j]);
    }}} Vector<pair<int, int>>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<n; i++) {mid.first + = Ret[i].first;
        Mid.second + = Ret[i].second;
        Ret[i].first *= N;
    Ret[i].second *= N;
    } sort (Ret.begin (), ret.end (), compare); for (int i = 0; i<n; i++) ret[i] = make_pAir (ret[i].first/n, ret[i].second/n);
return ret;  }//Returns the convex hull for the given set of points vector<pair<int, int>> divide (Vector<pair<int, Int>> 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<pair<int, Int>>le
    FT, right;
    for (int i = 0; I<a.size ()/2; i++) Left.push_back (A[i]);

    for (int i = A.size ()/2; i<a.size (); i++) Right.push_back (A[i]);
    Convex hull for the left and right sets Vector<pair<int, Int>>left_hull = divide (left);

    Vector<pair<int, int>>right_hull = divide (right);
Merging the convex hulls return merger (Left_hull, Right_hull); }//Driver code int main () {vector<pair<int, int> > 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<pair<int, int> >ans = Divide (a);
    cout << "Convex hull:\n";

    for (auto E:ans) cout << e.first << << e.second << Endl;
return 0; }

Output:

Convex Hull:
-5-3
-1-5
1-4
0 0
-1 1

complexity of Time:
Because we want to divide the point set into two equal parts, the time complexity of merging the left and right convex packets is O (n) o (n), so the time complexity of the algorithm is O (NLOGN) O (n\log N).

Related articles:

Convex Hull | Set 1 (Jarvis ' s algorithm or wrapping)
Convex Hull | Set 2 (Graham Scan)
Quickhull algorithm for Convex Hull

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.