Convex Hull
Convex Hull
many variati
common form of this algorithm involves determining the smallest convex set (called the "convex hull") containing a disc
This algorithm also applies to a polygon, or just any set of line segments, whose hull is the same as the hull of its vertex
numerous applications for convex hulls: collision avoidance, hidden object determination, and shape analysis to name a
minimal linear bounding container.
The most popular hull algorithms are the "Graham scan" algorithm [Graham, 1972] and the "divide-and-conquer" algori
Hong, 1977]. Implementations of both these algorithms are readily available (see [O'Rourke, 1998]). Both are
but the Graham has a low runtime constant in 2D and runs very fast there. However, the Graham algorithm does not gen
higher dimensions whereas the divide-and-conquer algorithm has a natural extension. We do not consider 3D algorithms
1998] for more information).
Here is a list of some well-known 2D hull algorithms. Let n = # points in the input set, and h = # vertices on the output h
so
Algorithm
Speed
Discovered By
Brute Force
Gift Wrapping
Graham Scan
[Graham, 1972]
Jarvis March
[Jarvis, 1973]
QuickHull
Divide-and-Conquer
Monotone Chain
[Andrew, 1979]
Incremental
[Kallay, 1984]
Marriage-before-Conquest
Convex Hulls
The convex hull of a geometric object (such as a point set or a polygon) is the smallest convex set containing that object
equivalent definitions for a convex set S. The most basic of these is:
Def 1. A set S is convex if whenever two points P and Q are inside S, then the whole line segment PQ is also in S.
But this definition does not readily lead to algorithms for constructing convex sets. A more useful definition states:
Def 2. A set S is convex if it is exactly equal to the intersection of all the half planes containing it.
It can be shown that these two definitions are equivalent. However, the second one gives us a better computational hand
the set S is the intersection of a finite number of half planes. In this case, the boundary of S is polygon in 2D, and polyh
which it can be identified.
Def 3. The convex hull of a finite point set S = {P} is the smallest 2D convex polygon
there is no other convex polygon (or polyhedron)
with
Also, this convex hull has the smallest area and the smallest perimeter of all convex polygons that contain S.
2D Hull Algorithms
For this algorithm we will cover two similar fast 2D hull algorithms: the Graham scan, and Andrew's Monotone Chain s
similar idea, and are implemented as a stack. In practice, they are both very fast, but Andrew's algorithm will execute sli
sort comparisons and rejection tests are more efficient. An implementation of Andrew's algorithm is given below in
our chainHull_2D() routine.
The Graham scan algorithm [Graham, 1972] is often cited ([Preparata & Shamos, 1985], [O'Rourke, 1998]) as the first r
geometry" algorithm. As the size of the geometric problem (namely, n = the number of points in the set) increases, it ach
asymptotic efficiency of
time. This algorithm and its implementation has been covered in great detail by [
3.5, 72-86] with downloadable C code available from his web site: Computational Geometry in C. We do not repeat that
and only give a conceptual overview of the algorithm. The
input set points. After that, the algorithm employs a stack-based method which runs in just
time. In fact, the meth
2n simple stack push and pop operations. Thus, it executes very rapidly, bounded only by the speed of sorting.
Let S = {P} be a finite set of points. The algorithm starts by picking a point in S known to be a vertex of the convex hul
in
time by selecting the rightmost lowest point in the set; that is, a point with first a minimum (lowest) y coordin
maximum (rightmost) x coordinate. Call this base point P0. Then, the algorithm sorts the other points P in S radially by
counter-clockwise (ccw) angle the line segment P0P makes with the x-axis. If there is a tie and two points have the same
one that is closest to P0. For efficiency, it is important to note that the sort comparison between two points P1 and P2 can
actually computing their angles. In fact, computing angles would use slow inaccurate trigonometry functions, and doing
would be a bad mistake. Instead, one just observes that P2 would make a greater angle than P1 if (and only if) P2 lies on
directed line segment P0P1 as shown in the following diagram. This condition can be tested by a fast accurate computati
additions and 2 multiplications. The code for this test was given in the isLeft()routine from Algorithm 1 about the A
Polygons.
We next loop through the points of S one-by-one testing for convex hull vertices. The algorithm is an inductive incremen
stack of points. At each stage, we save (on the stack) the vertex points for the convex hull of all points already processed
condition. We start with P0and P1 on the stack. Then at the k-th stage, we add the next point Pk, and compute how it alter
hull. Because of the way S was sorted, Pk is outside the hull of the prior points Pi with ik, and it must be added as a
the stack. But it's addition may cause previous stack points to no longer be a hull vertices. If this happens, the previous p
off the stack and discarded. One tests for this by checking if the new point Pk is to the left or the right of the line joining
the stack. Again, we use the routine isLeft() to quickly make this test. If Pk is on the left of the top segment, then prio
intact, and Pk gets pushed onto the stack. But, if it is on the right side of the top segment, then the prior point at the stack
inside the new hull, and that prior point must be popped off the stack. This test against the line segment at the stack top c
either Pk is left of that line or the stack is reduced to the single base point P0. In either case, Pk gets pushed onto the stack
proceeds to the next point Pk+1 in the set. The different possibilities involved are illustrated in the following diagram.
It is easy to understand why this works by viewing it as an incremental algorithm. The old stack
top, is the convex hull of all points Pi with i < k. The next point Pk is outside this hull since it is left of the line P0Pk1 wh
the Sk1 hull. To incrementally extendSk1 to include Pk, we need to find the two tangents from Pk to Sk1. One tangent is c
The other is a line PkPt such that Pk is left of the segment in Sk1 preceding Pt and is right of the segment following Pt (w
uniquely characterizes the second tangent since Sk1 is a convex polygon. The way to find Pt is simply to search from the
until the point with the property is found. The points above Pt in Sk1 are easily seen to be contained inside the triangle
thus no longer on the hull extended to include Pk. So, they can be discarded by popping them off the stack during the sea
the k-th convex hull is the new stack
At the end, when k = n1, the points remaining on the stack are precisely the ordered vertices of the convex hull's polygo
that for each point of S there is one push and at most one pop operation, giving at most 2n stack operations for the whole
This procedure is summarized by the following pseudo-code.
Pseudo-Code: Graham Scan Algorithm
Input: a
{
Let PT1 = the top point on
If (PT1 == P[0]) {
Push P[i] onto
i++
// increment i
}
Let PT2 = the second top point on
If (P[i] is strictly left of the line
PT2 to PT1) {
[Andrew, 1979] discovered an alternative to the Graham scan that uses a linear lexographic sort of the point set by the x
This is an advantage if this ordering is already known for a set, which is sometimes the case. But even if sorting is requi
than the angular Graham-scan sort with its more complicated comparison function. The "Monotone Chain" algorithm co
lower hulls of a monotone chain of points, which is why we refer to it as the "Monotone Chain" algorithm. Like the Gra
in
time due to the sort time. After that, it only takes
manner very similar to Graham's algorithm.
First the algorithm sorts the point set
first and then min y among all those points. Also, let
and
when there is
. These points and lines are shown in the following example diagram.
of S is constructed by joining
below
above
and
The lower or upper convex chain is constructed using a stack algorithm almost identical to the one used for the Graham
chain, start with
line
. Suppose that at any stage, the points on the stack are the convex hull of points below
at
, and only considering points above
careful to avoid duplicating the endpoints).
. Once the two hull chains have been found, it is easy to join the
minmin
minmax
maxmin
maxmax
=
=
=
=
index
index
index
index
of
of
of
of
P
P
P
P
with
with
with
with
min
min
max
max
x
x
x
x
first
first
first
first
and
and
and
and
min
max
min
max
y
y
y
y
second
second
second
second
Output:
Implementation
Here is a "C++" implementation of the Chain Hull algorithm.
//
//
//
//
//
//
//
Input: three points P0, P1, and P2
//
Return: >0 for P2 left of the line through P0 and P1
//
=0 for P2 on the line
//
<0 for P2 right of the line
//
See: Algorithm 1 on Area of Triangles
inline float
isLeft( Point P0, Point P1, Point P2 )
{
return (P1.x - P0.x)*(P2.y - P0.y) - (P2.x - P0.x)*(P1.y - P0.y);
}
//===================================================================
// chainHull_2D(): Andrew's monotone chain 2D convex hull algorithm
//
Input: P[] = an array of 2D points
//
presorted by increasing x and y-coordinates
//
n = the number of points in P[]
//
Output: H[] = an array of the convex hull vertices (max is n)
//
Return: the number of points in H[]
int
chainHull_2D( Point* P, int n, Point* H )
{
// the output array H[] will be used as the stack
int
bot=0, top=(-1);
// indices for bottom and top of the stack
int
i;
// array scan index
// Get the indices of points with min x-coord and min|max y-coord
int minmin = 0, minmax;
float xmin = P[0].x;
for (i=1; i<n; i++)
if (P[i].x != xmin) break;
minmax = i-1;
if (minmax == n-1) {
// degenerate case: all x-coords == xmin
H[++top] = P[minmin];
if (P[minmax].y != P[minmin].y) // a nontrivial segment
H[++top] = P[minmax];
H[++top] = P[minmin];
// add polygon endpoint
return top+1;
}
// Get the indices of points with max x-coord and min|max y-coord
int maxmin, maxmax = n-1;
float xmax = P[n-1].x;
for (i=n-2; i>=0; i--)
if (P[i].x != xmax) break;
maxmin = i+1;
// Compute the lower hull on the stack H
H[++top] = P[minmin];
// push minmin point onto stack
i = minmax;
while (++i <= maxmin)
{
// the lower line joins P[minmin] with P[maxmin]
if (isLeft( P[minmin], P[maxmin], P[i]) >= 0 && i < maxmin)
continue;
// push
return top+1;
}
References
S.G. Akl & Godfried Toussaint, "Efficient Convex Hull Algorithms for Pattern Recognition Applications", Proc. 4th In
Pattern Recognition, Kyoto, Japan, 483-487 (1978)
A.M. Andrew, "Another Efficient Algorithm for Convex Hulls in Two Dimensions", Info. Proc. Letters 9, 216-219 (197
A. Bykat, "Convex Hull of a Finite Set of Points in Two Dimensions", Info. Proc. Letters 7, 296-298 (1978)
W. Eddy, "A New Convex Hull Algorithm for Planar Sets", ACM Trans. Math. Software 3(4), 398-403 (1977)
Ronald Graham, "An Efficient Algorithm for Determining the Convex Hull of a Finite Point Set", Info. Proc. Letters 1,
R.A. Jarvis, "On the Identification of the Convex Hull of of a Finite Set of Points in the Plane", Info. Proc. Letters 2, 18
M. Kallay, "The Complexity of Incremental Convex Hull Algorithms in Rd", Info. Proc. Letters 19, 197 (1984)
D.G. Kirkpatrick & R. Seidel, "The Ultimate Planar Convex Hull Algorithm?", SIAM Jour. Comput. 15, 287-299 (1986
Joseph O'Rourke, Computational Geometry in C (2nd Edition), Chap. 3 "Convex Hulls in 2D" (1998)
Franco Preparata & Michael Shamos, Computational Geometry: An Introduction, Chap. 3 "Convex Hulls: Basic Algori
Franco Preparata & S.J. Hong, "Convex Hulls of Finite Sets of Points in Two and Three Dimensions", Comm. ACM 20