{"id":1253,"date":"2020-01-26T17:43:03","date_gmt":"2020-01-26T17:43:03","guid":{"rendered":"https:\/\/muthu.co\/?p=1253"},"modified":"2021-05-24T02:39:03","modified_gmt":"2021-05-24T02:39:03","slug":"understanding-graham-scan-algorithm-for-finding-the-convex-hull-of-a-set-of-points","status":"publish","type":"post","link":"http:\/\/write.muthu.co\/understanding-graham-scan-algorithm-for-finding-the-convex-hull-of-a-set-of-points\/","title":{"rendered":"Understanding Graham scan algorithm for finding the Convex hull of a set of Points"},"content":{"rendered":"\n
Convex Hull is one of the fundamental algorithms in Computational geometry used in many computer vision applications like Collision avoidance in Self Driving Cars, Shape analysis and Hand Gesture-recognition, etc.<\/p>\n\n\n\n
By Definition, A Convex Hull is the smallest convex set that encloses a given set of points. For Example, Given a set of points P in 2D or 3D space, a subset of points in P which fully encloses all points is called the Convex Hull. Take a look at the below figure.<\/p>\n\n\n\n
There are a number of algorithms[1] proposed for computing the convex hull of a finite set of points with various computational complexities. One such algorithm is the Graham Scan algorithm with a worst case complexity of O(nlogn)<\/em> which is going to be the topic of my discussion in this post.<\/p>\n\n\n\n Before we get into the algorithm we must understand a few basics upon which the Graham scan is built upon because once you understand them, convex hull would become fairly easy to implement.<\/p>\n\n\n\n Every polygon is either Convex or Concave. A polygon is said to be Convex if all its internal angles are less than \\(180^{\\circ} \\) as you can see in the figure above. It’s Concave if the polygon has angles greater than \\(180^{\\circ} \\).<\/p>\n\n\n\n There is another way to define a Convex Polygon. If every point on every line segment between two points inside or on the boundary of the polygon remains inside or on the boundary then the polygon is said to be Convex. Take a look at the below image to understand the above statement.<\/p>\n\n\n\n There are many ways to determine if the tuple of 3 points forms a clockwise turn or a counterclockwise turn or if they are collinear. One of the ways is by finding the determinant of the matrix formed by the three points. If the determinant is positive, then a->b->c is counterclockwise; if the determinant is negative, then a->b->c is clockwise; if the determinant is zero then a->b->c are collinear.<\/p>\n\n\n\n The determinant is not the most efficient way to identify the turn because of the complexity of multiplication and addition operations. There is a more efficient way which uses the slope of the lines formed by the points.<\/p>\n\n\n\n Slope of line segment (A, B): \u03c3 = (y2 – y1)\/(x2 – x1) If \u03c3 > \u03c4, the orientation is clockwise (right turn)<\/p>\n\n\n\n Using above values of \u03c3 and \u03c4, we can conclude that, (y2 – y1)*(x3 – x2) – (y3 – y2)*(x2 – x1)<\/p>\n\n\n\n The above expression is negative when \u03c3 < \u03c4, i.e., counterclockwise<\/p>\n\n\n\n The python code we will be using later on for determining the CCW is as below:<\/p>\n\n\n\n In the plane, the polar angle theta is the counterclockwise angle from the x-axis at which a point in the xy-plane lies. [2]<\/p>\n\n\n\n We use a special function in math library atan2 to find the angle in radians.<\/p>\n\n\n\n With the basics in place, we are ready to understand the Graham Scan Convex Hull algorithm. The steps in the algorithm are:<\/p>\n\n\n\n Take a look at the below simulation to understand the Graham Scan process.<\/p>\n\n\n\nConvex vs Concave<\/h2>\n\n\n\n
<\/a><\/figure><\/div>\n\n\n\n
<\/a><\/figure><\/div>\n\n\n\n
<\/h2>\n\n\n\n
Counterclockwise turns<\/h2>\n\n\n\n
<\/a><\/figure><\/div>\n\n\n\n
<\/a><\/figure><\/div>\n\n\n\n
<\/a><\/figure><\/div>\n\n\n\n
Slope of line segment (B, C): \u03c4 = (y3 – y2)\/(x3 – x2)<\/p>\n\n\n\n
the orientation depends on sign of below expression:<\/p>\n\n\n\ndef ccw(a, b, c):\n return (b[0] - a[0]) * (c[1] - a[1]) - (c[0] - a[0]) * (b[1] - a[1])<\/code><\/pre>\n\n\n\n
Polar Angle<\/h2>\n\n\n\n
<\/a><\/figure><\/div>\n\n\n\n
from math import atan2\n\ndef polar_angle(p0, p1):\n y_span=p0[1]-p1[1]\n x_span=p0[0]-p1[0]\n return atan2(y_span,x_span)<\/code><\/pre>\n\n\n\n
Graham Scan Algorithm<\/h2>\n\n\n\n