Convex bag (convex Hull)
In graphics, convex hull is a very important concept. In brief, n points are given in the plane to find a convex polygon composed of some points as vertices, which can enclose all n points.
It was much like nailing n nails on a piece of wood, and then using a taut rubber band to circle them, the shape of the rubber band is the so-called convex bag.
A well-known algorithm for calculating convex hull is the Graham scan method, whose time complexity is the same as the time complexity of the sorting algorithm used, usually using the linear logarithm algorithm, thus the \ (O\left (N\mathrm{log}\left (n\right) \right) \).
1. Find the bottom point of a bit \ (p_{0,1,..., N-1} \), and write it as \ (P_{l} \);
2. Calculate the angle of all other points \ (P_{i}\left (i\neq l\right) \) and \ (P_{l} \) the Vector \ (\overrightarrow{p_{l}p_{i}} \) relative to the horizontal axis. Because all the points are above the \ (P_{l} \), the value range of the vector is \ (\left (0, 180\right) \), so the cotangent value can be used instead of the angle value;
3. Sort all other points according to the angle calculated by the 2nd step, and \ (P_{l} \) is the No. 0 bit of the sorted array;
4. Starting from the Point \ (P_{l} \), according to this connection each point (has been sorted), each connection point to detect whether the line is counterclockwise, if it is left the point of the previous point, and vice versa to remove the previous point, so that it is directly connected with the second point in front, continue this test, Until it is counterclockwise or all points have been detected.
Determine whether the three points in accordance with this link into two line lines is counterclockwise, with the two line segment vector cross product judgment: Cross product >0, counter-clockwise; conversely clockwise or collinear.
The QT 5.7 is used to implement a demo of the algorithm, where the part of the algorithm is as follows (because Y is growing downward in the QT coordinate system, you need to take the opposite number when calculating the ordinate difference).
voidDisplaywidget::calconvexhull () {intSize =m_points.size (); if(Size <3) { return; } //first:find the lowest point intMaxy =0; intIndexoflowest =-1; for(inti =0; i < size; i++) { if(M_points.at (i). Y () >Maxy) {Maxy=m_points.at (i). Y (); Indexoflowest=i; }} std::swap (*m_points.begin (), * (M_points.begin () +indexoflowest)); Qpoint&lowestpoint = *(M_points.begin ()); //second:calculate Ctan (angles) Double*ctanangles =New Double[size]; for(inti =1; i < size; i++) { DoubleDeltaY = Lowestpoint.y ()-m_points.at (i). Y () +Dbl_epsilon; DoubleDeltaX = m_points.at (i). x ()-lowestpoint.x (); Ctanangles[i]= DeltaX/DeltaY; } //third:sort Subscript int*subscript =New int[size]; for(inti =1; i < size; i++) {Subscript[i]=i; } std::sort (Subscript+1, subscript + size, [Ctanangles] (intA1,intA2) {returnCTANANGLES[A2] <CTANANGLES[A1];}); //fourth:calculate Convex HullStd::vector<qpoint>convexhullpoints; Convexhullpoints.push_back (*M_points.begin ()); Convexhullpoints.push_back (m_points.at (subscript[1])); for(inti =2; i < size; i++) {convexhullpoints.push_back (m_points.at (subscript[i)); while(Convexhullpoints.size () >3&&!isanticlockwise (* (Convexhullpoints.end ()-3), * (Convexhullpoints.end ()-2), * (Convexhullpoints.end ()-1))) { * (Convexhullpoints.end ()-2) = * (Convexhullpoints.end ()-1); Convexhullpoints.pop_back (); }} m_convexhullpoints=Std::move (convexhullpoints); Delete[] ctanangles; Delete[] subscript;}
The effect is as follows:
Program Source: Http://files.cnblogs.com/files/HolyChen/ConvexHull.rar
--graham scanning method for convex hull (convex Hull) construction algorithm