The so-called convex hull is a concept in computational geometry (graphics). In the case of non-rigorous words, given a set of points on a two-dimensional plane, a convex hull is a convex multilateral type that joins the outermost point together, and it can contain all points in a point set. Wikipedia has four definitions for the convex hull (convex Hull) for set X, respectively:
-
The (unique) minimal convex set containing X      &NB sp; --- minimum convex set containing set x
-
The intersection of all convex sets Contai ning x ---the intersection of all convex sets containing set X
-
The Set of All convex combinations of points in X . --- A collection of convex combinations in the set X
-
The union of All simplices with vertices in X . & nbsp; A collection of all the single vertices in the collection x---
For two-dimensional convex hull, we think of some points on the plane as "nails", and you are holding a rubber band large enough so that all the "nails" are in the area surrounded by your rubber bands. Now let's loosen it. "Pa", the rubber band will shrink as much as possible to the extreme, and then prop up the rubber bands of these "nails" constitute a set of, that is, convex bag.
By observing, we can know that the two points of "leftmost" and "most right" must be in the set that make up the convex hull. The Garham's scan algorithm is also aware of this. Also, if we look at the convex hull in a clockwise direction, such as P->q->r, the convex hull at each point is "right" (or, of course, a straight line).
Using two linked lists Lupper and llower represent the upper part of the convex hull (Upper Hull) and the lower half (Lower Hull) respectively, the Garham algorithm can be described by the following pseudo-code:
Algorithm convexhull (P) Input. a set p of points in the plane. Output. a list containing the vertices of ch (P) in clockwise order. Sort the points by x-coordinate, resulting in a SEQUENCE P1,..., pn. put the points p1 and p2 in a list lupper, with p1 as the first point. for i ← 3 to n do Append pi to Lupper. while lupper contains more than two points and the last three points in lupper do not make a right turn do Delete The middle of the&nBsp;last three points from lupper. put the points pn and pn? 1 in a list llower 6 , with pn as the first point. for i ← n?2 downto 1 do Append pi To llower. while llower contains more than 2 points and the last three points in llower do not make a right turn do Delete the middle of the last three points From llower. remove the first and the last point from llower to avoid duplication of the points where the upper and lower hull&Nbsp;meet. append llower to lupper, and call the resulting list l. return l
Now the problem goes to the coordinates of the known three point a,b,c, how to determine if the C point is on the left side of the vector ab.
For this problem, we can use one of the conclusions of geometry: the area of the direction. The forward area of a triangle can be obtained by a determinant:
(I do not know the determinant of how to calculate the children's shoes can go to fill the line to substitute for the ~)
If c is to the left of the ab direction, then the determinant value is positive and vice versa. When designing a program, we only need to know the positive and negative values of the determinant, not the specific value, so there is no more division.
/** * Calculate the doubled directed area of PQs */long long Area2 (point P, point Q, point s) {return p.x*q.y-p.y*q. x +q.x*s.y-q.y*s.x +s.x*p.y-p.x*s.y;} Determinate whether S is on the left side of a directed line P->qbool ToLeft (point P, point Q, point s) {return a REA2 (P,q,s) >0;}
The entire algorithm can be written in the following code:
/** created on 2015-10-12 11:24:04 description : generate the Convex hull via the graham ' s scan algorithm time cost : o (NLOGN) Thanks to Tsinghua univ. mooc computational geometry 2015 as the answer of cg2015 pa1-1 convex Hull (HTTP/ dsa.cs.tsinghua.edu.cn/oj/course.shtml?courseid=39) author: chenzheng / arc001 email : [email protected] copyright 2015 xi ' an university of posts & telecommunications*/#include <iostream> #include <cstdio> #include <algorithm> #include < list>using namespace std;enum point_status {isextreme, notextreme};struct point{ long long x,y; int index; Point_Status status; bool operator < (const POINT&NBSP;&&NBSP;RHS) const { if (x == rhs.x) { return y < rhs.y; } return x < rhs.x; &NBSP;&NBSP;}};LONG&NBSP;LONG&NBSP;AREA2 ( point p, point q, point s); // No more repeating bool toleft here ( pOint p, point q, point s); Point s[100005];list<point> upper_hull, lower_hull;int main () { &NBSP;INT&NBSP;N;&NBSP;&NBSP;&NBSP;&NBSP;LONG&NBSP;LONG&NBSP;ANS&NBSP;=&NBSP;1;&NBSP;&NBSP;&NBSP;&NBSP;SCANF (" %d ", &n); for (int i=1;i<=n;i++) { &NBSP;SCANF ("%lld%lld", &s[i].x,&s[i].y); s[i].index = i; S[i].status = notExtreme; } sort (&s[1],&s[n+1]); upper_hull.push_back ( S[1]); upper_hull.push_back (s[2]); list<point>::iterator it,it2,it3; for (int i=3; i<=n; i++) { upper_hull.push_back (S[i]); &NBSP;&NBSp; it = it2 = it3 = upper_hull.end (); --it; --it; --it; --it2; --it2; --it3; //cout<<it3->index<< " pushed!" <<endl; while (Upper_hull.size () >2 && toleft (*IT,*IT2,*IT3)) { upper_hull.erase (IT2); //cout<<it2->index<< " deleted! " <<it3->index << " " <<AREA2 (*IT,*IT2,*IT3) <<endl; it = it2 = it3 = upPer_hull.end (); --it; --it; - -it; --it2; --it2; --it3; } //cout<<upper_hull.size () <<endl<<endl ; } upper_hull.pop_back (); lower_ Hull.push_back (S[n]); lower_hull.push_back (s[n-1]); for (int i=n-2; i>=1; i--) { Lower_hull.push_back (S[i]); it = it2 = it3 = lower_hull.end (); --it; --it; --it; --it2; --it2; --it3; while (Lower_hull.size () >2 && toleft (* (IT), * (IT2), * (IT3))) { lower_hull.erase (it2); it = it2 = it3 = lower_hull.end (); --it; --it; --it; --it2; --it2; --it3; } } lower_ Hull.pop_back (); //cout<<lower_hull.size () <<endl; Int count_vertex =&nbsP;0; for (It = upper_hull.begin (); it != upper_hull.end (); it++) { s[it->index].status = isExtreme; //cout<<it->index<<endl; count_vertex++; } for (It = lower_hull.begin (); it != lower_hull.end (); it++) { S[it->index].status = isExtreme; //cout<<it->index<<endl; count_vertex++; } for (Int i=1 ; i<=n; i++) { //Here calculates the answer to this question, with little relation to the algorithm if (S[i].status == isextreme) { ans *= i; ans %= (n+1); //cout<<i<<endl; } } ans *= count_vertex; ans %= (n +1); printf ("%lld\n", ans); return 0;}
A new algorithm--C + + implementation of Garham ' s scan algorithm for convex packet