Quickhull Algorithm for Convex Hull
Last Updated :
07 Mar, 2024
Given a set of points, a Convex hull is the smallest convex polygon containing all the given points.

Input : points[] = {{0, 3}, {1, 1}, {2, 2}, {4, 4},
{0, 0}, {1, 2}, {3, 1}, {3, 3}};
Output : The points in convex hull are:
(0, 0) (0, 3) (3, 1) (4, 4)
Input : points[] = {{0, 3}, {1, 1}
Output : Not Possible
There must be at least three points to form a hull.
Input : points[] = {(0, 0), (0, 4), (-4, 0), (5, 0),
(0, -6), (1, 0)};
Output : (-4, 0), (5, 0), (0, -6), (0, 4)
We have discussed following algorithms for Convex Hull problem. Convex Hull | Set 1 (Jarvis’s Algorithm or Wrapping) Convex Hull | Set 2 (Graham Scan) The QuickHull algorithm is a Divide and Conquer algorithm similar to QuickSort. Let a[0...n-1] be the input array of points. Following are the steps for finding the convex hull of these points.
- Find the point with minimum x-coordinate lets say, min_x and similarly the point with maximum x-coordinate, max_x.
- Make a line joining these two points, say L. This line will divide the whole set into two parts. Take both the parts one by one and proceed further.
- For a part, find the point P with maximum distance from the line L. P forms a triangle with the points min_x, max_x. It is clear that the points residing inside this triangle can never be the part of convex hull.
- The above step divides the problem into two sub-problems (solved recursively). Now the line joining the points P and min_x and the line joining the points P and max_x are new lines and the points residing outside the triangle is the set of points. Repeat point no. 3 till there no point left with the line. Add the end points of this point to the convex hull.
Below is C++ implementation of above idea. The implementation uses set to store points so that points can be printed in sorted order. A point is represented as a pair.Â
CPP
// C++ program to implement Quick Hull algorithm
// to find convex hull.
#include<bits/stdc++.h>
using namespace std;
// iPair is integer pairs
#define iPair pair<int, int>
// Stores the result (points of convex hull)
set<iPair> hull;
// Returns the side of point p with respect to line
// joining points p1 and p2.
int findSide(iPair p1, iPair p2, iPair p)
{
int val = (p.second - p1.second) * (p2.first - p1.first) -
(p2.second - p1.second) * (p.first - p1.first);
if (val > 0)
return 1;
if (val < 0)
return -1;
return 0;
}
// returns a value proportional to the distance
// between the point p and the line joining the
// points p1 and p2
int lineDist(iPair p1, iPair p2, iPair p)
{
return abs ((p.second - p1.second) * (p2.first - p1.first) -
(p2.second - p1.second) * (p.first - p1.first));
}
// End points of line L are p1 and p2. side can have value
// 1 or -1 specifying each of the parts made by the line L
void quickHull(iPair a[], int n, iPair p1, iPair p2, int side)
{
int ind = -1;
int max_dist = 0;
// finding the point with maximum distance
// from L and also on the specified side of L.
for (int i=0; i<n; i++)
{
int temp = lineDist(p1, p2, a[i]);
if (findSide(p1, p2, a[i]) == side && temp > max_dist)
{
ind = i;
max_dist = temp;
}
}
// If no point is found, add the end points
// of L to the convex hull.
if (ind == -1)
{
hull.insert(p1);
hull.insert(p2);
return;
}
// Recur for the two parts divided by a[ind]
quickHull(a, n, a[ind], p1, -findSide(a[ind], p1, p2));
quickHull(a, n, a[ind], p2, -findSide(a[ind], p2, p1));
}
void printHull(iPair a[], int n)
{
// a[i].second -> y-coordinate of the ith point
if (n < 3)
{
cout << "Convex hull not possible\n";
return;
}
// Finding the point with minimum and
// maximum x-coordinate
int min_x = 0, max_x = 0;
for (int i=1; i<n; i++)
{
if (a[i].first < a[min_x].first)
min_x = i;
if (a[i].first > a[max_x].first)
max_x = i;
}
// Recursively find convex hull points on
// one side of line joining a[min_x] and
// a[max_x]
quickHull(a, n, a[min_x], a[max_x], 1);
// Recursively find convex hull points on
// other side of line joining a[min_x] and
// a[max_x]
quickHull(a, n, a[min_x], a[max_x], -1);
cout << "The points in Convex Hull are:\n";
while (!hull.empty())
{
cout << "(" <<( *hull.begin()).first << ", "
<< (*hull.begin()).second << ") ";
hull.erase(hull.begin());
}
}
// Driver code
int main()
{
iPair a[] = {{0, 3}, {1, 1}, {2, 2}, {4, 4},
{0, 0}, {1, 2}, {3, 1}, {3, 3}};
int n = sizeof(a)/sizeof(a[0]);
printHull(a, n);
return 0;
}
Java
/*package whatever //do not write package name here */
import java.io.*;
class GFG {
public static void main (String[] args) {
int a[][] = {{0, 3}, {1, 1}, {2, 2}, {4, 4},
{0, 0}, {1, 2}, {3, 1}, {3, 3}};
int[][] ans = FindConvexHull(a);
System.out.println("The points in Convex Hull are: ");
for (int i = 0; i < ans.length; i++)
System.out.print("(" + ans[i][0] + ","+ ans [i][1]+ ") ");
}
public static int[][] FindConvexHull(int[][] points_list)
{
int n= points_list.length;
int small = 0;
for(int i=1;i<n;i++){
if( points_list[i][1] < points_list[small][1])
small = i;
}
if(n == 1)
return new int[][]{{-1, -1}};
int t[] = points_list[small];
points_list[small] = points_list[0];
points_list[0] = t;
quickSort( points_list, 1, n-1, true);
int stack[] = new int[n];
int p=1;
stack[0] = 0;
stack[1]=n-1;
for(int i=n-2;i>0;i--){
long prod = -1;
while(prod <= 0 && p>0){
int p1[] = points_list[stack[p]];
int p2[] = points_list[stack[p-1]];
long y1 = p1[1]-p2[1];
long x1 = p1[0]-p2[0];
long x2 = points_list[i][0]-p1[0];
long y2 = points_list[i][1]-p1[1];
prod = x1 * y2 - x2 * y1;
if(prod <= 0){
p--;
}
}
p++;
stack[p] = i;
}
if(p+1 <=2 )
return new int[][]{{-1, -1}};
int ans[][] = new int[p+1][2];
for(int i=p;i>=0;i--){
ans[i] = points_list[stack[i]];
}
quickSort(ans,0,p,false);
return ans;
}
public static void quickSort(int arr[][],int low, int end,boolean flag){
if(low >= end)
return;
int p = -1;
if(flag)
p = partition(arr, low, end);
else p = part(arr,low,end);
quickSort(arr, low, p-1, flag);
quickSort(arr, p+1,end, flag);
}
private static int part(int arr[][], int low, int end){
int p=low;
for(int i=low+1;i <= end;i++){
if((arr[i][0] < arr[p][0]) || (arr[i][0] == arr[p][0] && arr[i][1]< arr[p][1])){
low++;
int t[] = arr[low];
arr[low] = arr[i];
arr[i] = t;
}
}
int t[] = arr[low];
arr[low] = arr[p];
arr[p]=t;
return low;
}
private static int partition(int arr[][], int low, int end){
int p = low;
double a1 = angle(arr[low], arr[0]);
for(int i=low+1;i <= end;i++){
double a2 = angle(arr[i],arr[0]);
if(a1 < a2){
low++;
int t[] = arr[low];
arr[low] = arr[i];
arr[i] = t;
}
}
int t[] = arr[low];
arr[low] = arr[p];
arr[p] = t;
return low;
}
private static double angle(int p1[], int p2[]){
double x=p1[0]-p2[0];
double y = p1[1] - p2[1];
return -(x/Math.sqrt(x*x + y*y));
}
}
C#
using System;
using System.Collections.Generic;
public static class GFG {
static HashSet<List<int> > hull
= new HashSet<List<int> >();
// Stores the result (points of convex hull)
// Returns the side of point p with respect to line
// joining points p1 and p2.
public static int findSide(List<int> p1, List<int> p2,
List<int> p)
{
int val = (p[1] - p1[1]) * (p2[0] - p1[0])
- (p2[1] - p1[1]) * (p[0] - p1[0]);
if (val > 0) {
return 1;
}
if (val < 0) {
return -1;
}
return 0;
}
// returns a value proportional to the distance
// between the point p and the line joining the
// points p1 and p2
public static int lineDist(List<int> p1, List<int> p2,
List<int> p)
{
return Math.Abs((p[1] - p1[1]) * (p2[0] - p1[0])
- (p2[1] - p1[1]) * (p[0] - p1[0]));
}
// End points of line L are p1 and p2. side can have
// value 1 or -1 specifying each of the parts made by
// the line L
public static void quickHull(List<List<int> > a, int n,
List<int> p1, List<int> p2,
int side)
{
int ind = -1;
int max_dist = 0;
// finding the point with maximum distance
// from L and also on the specified side of L.
for (int i = 0; i < n; i++) {
int temp = lineDist(p1, p2, a[i]);
if (findSide(p1, p2, a[i]) == side
&& temp > max_dist) {
ind = i;
max_dist = temp;
}
}
// If no point is found, add the end points
// of L to the convex hull.
if (ind == -1) {
hull.Add(p1);
hull.Add(p2);
return;
}
// Recur for the two parts divided by a[ind]
quickHull(a, n, a[ind], p1,
-findSide(a[ind], p1, p2));
quickHull(a, n, a[ind], p2,
-findSide(a[ind], p2, p1));
}
public static void printHull(List<List<int> > a, int n)
{
// a[i].second -> y-coordinate of the ith point
if (n < 3) {
Console.Write("Convex hull not possible\n");
return;
}
// Finding the point with minimum and
// maximum x-coordinate
int min_x = 0;
int max_x = 0;
for (int i = 1; i < n; i++) {
if (a[i][0] < a[min_x][0]) {
min_x = i;
}
if (a[i][0] > a[max_x][0]) {
max_x = i;
}
}
// Recursively find convex hull points on
// one side of line joining a[min_x] and
// a[max_x]
quickHull(a, n, a[min_x], a[max_x], 1);
quickHull(a, n, a[min_x], a[max_x], -1);
Console.Write("The points in Convex Hull are:\n");
foreach(var item in hull)
{
Console.WriteLine(item[0] + " " + item[1]);
}
}
// Driver code
public static void Main()
{
// the set of points in the convex hull
List<List<int> > a = new List<List<int> >();
{
a.Add(new List<int>() { 0, 3 });
a.Add(new List<int>() { 1, 1 });
a.Add(new List<int>() { 2, 2 });
a.Add(new List<int>() { 4, 4 });
a.Add(new List<int>() { 0, 0 });
a.Add(new List<int>() { 1, 2 });
a.Add(new List<int>() { 3, 1 });
a.Add(new List<int>() { 3, 3 });
};
int n = a.Count;
printHull(a, n);
}
}
// The code is contributed by Aarti_Rathi
JavaScript
// JavaScript program to implement Quick Hull algorithm
// to find convex hull.
// Stores the result (points of convex hull)
let hull = new Set();
// Returns the side of point p with respect to line
// joining points p1 and p2.
function findSide(p1, p2, p)
{
let val = (p[1] - p1[1]) * (p2[0] - p1[0]) -
(p2[1] - p1[1]) * (p[0] - p1[0]);
if (val > 0)
return 1;
if (val < 0)
return -1;
return 0;
}
// returns a value proportional to the distance
// between the point p and the line joining the
// points p1 and p2
function lineDist(p1, p2, p)
{
return Math.abs ((p[1] - p1[1]) * (p2[0] - p1[0]) -
(p2[1] - p1[1]) * (p[0] - p1[0]));
}
// End points of line L are p1 and p2. side can have value
// 1 or -1 specifying each of the parts made by the line L
function quickHull(a, n, p1, p2, side)
{
let ind = -1;
let max_dist = 0;
// finding the point with maximum distance
// from L and also on the specified side of L.
for (let i=0; i<n; i++)
{
let temp = lineDist(p1, p2, a[i]);
if ((findSide(p1, p2, a[i]) == side) && (temp > max_dist))
{
ind = i;
max_dist = temp;
}
}
// If no point is found, add the end points
// of L to the convex hull.
if (ind == -1)
{
hull.add(p1);
hull.add(p2);
return;
}
// Recur for the two parts divided by a[ind]
quickHull(a, n, a[ind], p1, -findSide(a[ind], p1, p2));
quickHull(a, n, a[ind], p2, -findSide(a[ind], p2, p1));
}
function printHull(a, n)
{
// a[i].second -> y-coordinate of the ith point
if (n < 3)
{
console.log("Convex hull not possible");
return;
}
// Finding the point with minimum and
// maximum x-coordinate
let min_x = 0, max_x = 0;
for (let i=1; i<n; i++)
{
if (a[i][0] < a[min_x][0])
min_x = i;
if (a[i][0] > a[max_x][0])
max_x = i;
}
// Recursively find convex hull points on
// one side of line joining a[min_x] and
// a[max_x]
quickHull(a, n, a[min_x], a[max_x], 1);
// Recursively find convex hull points on
// other side of line joining a[min_x] and
// a[max_x]
quickHull(a, n, a[min_x], a[max_x], -1);
console.log("The points in Convex Hull are:");
hull.forEach(element =>{
console.log("(", element[0], ", ", element[1], ") ");
})
}
// Driver code
{
let a = [[0, 3], [1, 1], [2, 2], [4, 4],
[0, 0], [1, 2], [3, 1], [3, 3]];
let n = a.length;
printHull(a, n);
}
// The code is contributed by Nidhi goel
Python3
# python program to implement Quick Hull algorithm
# to find convex hull.
# Stores the result (points of convex hull)
hull = set()
# Returns the side of point p with respect to line
# joining points p1 and p2.
def findSide(p1, p2, p):
val = (p[1] - p1[1]) * (p2[0] - p1[0]) - (p2[1] - p1[1]) * (p[0] - p1[0])
if val > 0:
return 1
if val < 0:
return -1
return 0
# returns a value proportional to the distance
# between the point p and the line joining the
# points p1 and p2
def lineDist(p1, p2, p):
return abs((p[1] - p1[1]) * (p2[0] - p1[0]) -
(p2[1] - p1[1]) * (p[0] - p1[0]))
# End points of line L are p1 and p2. side can have value
# 1 or -1 specifying each of the parts made by the line L
def quickHull(a, n, p1, p2, side):
ind = -1
max_dist = 0
# finding the point with maximum distance
# from L and also on the specified side of L.
for i in range(n):
temp = lineDist(p1, p2, a[i])
if (findSide(p1, p2, a[i]) == side) and (temp > max_dist):
ind = i
max_dist = temp
# If no point is found, add the end points
# of L to the convex hull.
if ind == -1:
hull.add("$".join(map(str, p1)))
hull.add("$".join(map(str, p2)))
return
# Recur for the two parts divided by a[ind]
quickHull(a, n, a[ind], p1, -findSide(a[ind], p1, p2))
quickHull(a, n, a[ind], p2, -findSide(a[ind], p2, p1))
def printHull(a, n):
# a[i].second -> y-coordinate of the ith point
if (n < 3):
print("Convex hull not possible")
return
# Finding the point with minimum and
# maximum x-coordinate
min_x = 0
max_x = 0
for i in range(1, n):
if a[i][0] < a[min_x][0]:
min_x = i
if a[i][0] > a[max_x][0]:
max_x = i
# Recursively find convex hull points on
# one side of line joining a[min_x] and
# a[max_x]
quickHull(a, n, a[min_x], a[max_x], 1)
# Recursively find convex hull points on
# other side of line joining a[min_x] and
# a[max_x]
quickHull(a, n, a[min_x], a[max_x], -1)
print("The points in Convex Hull are:")
for element in hull:
x = element.split("$")
print("(", x[0], ",", x[1], ") ", end = " ")
# Driver code
a = [[0, 3], [1, 1], [2, 2], [4, 4],
[0, 0], [1, 2], [3, 1], [3, 3]]
n = len(a)
printHull(a, n)
# The code is contributed by Nidhi goel
OutputThe points in Convex Hull are:
(0, 0) (0, 3) (3, 1) (4, 4)
Time Complexity: The analysis is similar to Quick Sort. On average, we get time complexity as O(n Log n), but in worst case, it can become O(n2)
space complexity : O(n)Â
If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to [email protected]. See your article appearing on the GeeksforGeeks main page and help other Geeks. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
Similar Reads
Convex Hull Algorithm
The Convex Hull Algorithm is used to find the convex hull of a set of points in computational geometry. The convex hull is the smallest convex set that encloses all the points, forming a convex polygon. This algorithm is important in various applications such as image processing, route planning, and
8 min read
Convex Hull using Divide and Conquer Algorithm
In computational geometry, a convex hull is the smallest convex polygon that contains a given set of points. It is a fundamental concept with applications in various fields such as computer graphics, robotics, and image processing. Importance of Convex Hull:Convex hulls are important in computationa
15 min read
Convex Hull using Jarvis' Algorithm or Wrapping
Given a set of points in the plane. the convex hull of the set is the smallest convex polygon that contains all the points of it.We strongly recommend to see the following post first. How to check if two given line segments intersect?The idea of Jarvis's Algorithm is simple, we start from the leftmo
13 min read
Convex Hull using Graham Scan
A convex hull is the smallest convex polygon that contains a given set of points. It is a useful concept in computational geometry and has applications in various fields such as computer graphics, image processing, and collision detection.A convex polygon is a polygon in which all interior angles ar
15+ min read
Convex Hull | Monotone chain algorithm
Given a set of points, the task is to find the convex hull of the given points. The convex hull is the smallest convex polygon that contains all the points. Please check this article first: Convex Hull | Set 1 (Jarvisâs Algorithm or Wrapping) Examples: Input: Points[] = {{0, 3}, {2, 2}, {1, 1}, {2,
11 min read
Quickhull Algorithm for Convex Hull
Given a set of points, a Convex hull is the smallest convex polygon containing all the given points. Input : points[] = {{0, 3}, {1, 1}, {2, 2}, {4, 4}, {0, 0}, {1, 2}, {3, 1}, {3, 3}};Output : The points in convex hull are: (0, 0) (0, 3) (3, 1) (4, 4)Input : points[] = {{0, 3}, {1, 1}Output : Not P
14 min read
Problems on Convex Hull
Dynamic Convex hull | Adding Points to an Existing Convex Hull
Given a convex hull, we need to add a given number of points to the convex hull and print the convex hull after every point addition. The points should be in anti-clockwise order after addition of every point. Examples: Input : Convex Hull : (0, 0), (3, -1), (4, 5), (-1, 4) Point to add : (100, 100)
15 min read
Deleting points from Convex Hull
Given a fixed set of points. We need to find convex hull of given set. We also need to find convex hull when a point is removed from the set. Example: Initial Set of Points: (-2, 8) (-1, 2) (0, 1) (1, 0) (-3, 0) (-1, -9) (2, -6) (3, 0) (5, 3) (2, 5) Initial convex hull:- (-2, 8) (-3, 0) (-1, -9) (2,
15+ min read
Perimeter of Convex hull for a given set of points
Given n 2-D points points[], the task is to find the perimeter of the convex hull for the set of points. A convex hull for a set of points is the smallest convex polygon that contains all the points. Examples: Input: points[] = {{0, 3}, {2, 2}, {1, 1}, {2, 1}, {3, 0}, {0, 0}, {3, 3}} Output: 12 Inpu
10 min read
Check if the given point lies inside given N points of a Convex Polygon
Given coordinates of the N points of a Convex Polygon. The task is to check if the given point (X, Y) lies inside the polygon. Examples:Input: N = 7, Points: {(1, 1), (2, 1), (3, 1), (4, 1), (4, 2), (4, 3), (4, 4)}, Query: X = 3, Y = 2 Below is the image of plotting of the given points: Output: YES
15 min read
Tangents between two Convex Polygons
Given two convex polygons, we aim to identify the lower and upper tangents connecting them. As shown in the figure below, TRL and TLR represent the upper and lower tangents, respectively. Examples: Input: First Polygon : [[2, 2], [3, 3], [5, 2], [4, 0], [3, 1]] Second Polygon : [[-1, 0], [0, 1], [1,
15 min read
Check if given polygon is a convex polygon or not
Given a 2D array point[][] with each row of the form {X, Y}, representing the co-ordinates of a polygon in either clockwise or counterclockwise sequence, the task is to check if the polygon is a convex polygon or not. If found to be true, then print "Yes" . Otherwise, print "No".In a convex polygon,
9 min read
Check whether two convex regular polygon have same center or not
Given two positive integers N and M which denotes the sides of the convex regular polygon where N < M, the task is to check whether polygons have the same center or not if N-sided polygon was inscribed in an M-sided polygon.Center of Polygon: Point inside a polygon which is equidistant from each
3 min read
Minimum Enclosing Circle
Prerequisites: Equation of circle when three points on the circle are given, Convex HullGiven an array arr[][] containing N points in a 2-D plane with integer coordinates. The task is to find the centre and the radius of the minimum enclosing circle(MEC). A minimum enclosing circle is a circle in wh
15+ min read
How to Highlight Groups with Convex Hull in ggplot2 in R?
In this article, we are going to see how to highlight groups with the convex hull in ggplot2 using R Programming Language. Convex hull polygon refers to the draw a line bounding box around the outermost points in each group. Creating scatterplot for demonstration Here we will use the iris dataset t
2 min read