Skip to content

Instantly share code, notes, and snippets.

@lvngd
Last active May 23, 2023 04:26
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save lvngd/54a26a748c073d35e269f90419c0f629 to your computer and use it in GitHub Desktop.
Save lvngd/54a26a748c073d35e269f90419c0f629 to your computer and use it in GitHub Desktop.
import random
"""
Computes the Convex Hull with the Graham Scan algorithm
Use:
h = ConvexHull()
print(h.hull)
"""
class ConvexHull:
def __init__(self, points):
if not points:
self.points = [(random.randint(0,100),random.randint(0,100)) for i in range(50)]
else:
self.points = points
self.hull = self.compute_convex_hull()
def get_cross_product(self,p1, p2, p3):
return ((p2[0] - p1[0])*(p3[1] - p1[1])) - ((p2[1] - p1[1])*(p3[0] - p1[0]))
def get_slope(self,p1, p2):
if p1[0] == p2[0]:
return float('inf')
else:
return 1.0*(p1[1]-p2[1])/(p1[0]-p2[0])
def compute_convex_hull(self):
hull = []
self.points.sort(key=lambda x:[x[0],x[1]])
start = self.points.pop(0)
hull.append(start)
self.points.sort(key=lambda p: (self.get_slope(p,start), -p[1],p[0]))
for pt in self.points:
hull.append(pt)
while len(hull) > 2 and self.get_cross_product(hull[-3],hull[-2],hull[-1]) < 0:
hull.pop(-2)
return hull
@rajat044
Copy link

It seems this code has some bugs. It does not remove colinear points.
For instance, If input is [[0, 0], [5, 3], [0, 5], [5, 3]] output should be [[0, 0], [0, 5], [5, 3]] but It returns [[0, 0], [0, 3], [0, 5], [5, 3]]

@lvngd
Copy link
Author

lvngd commented Oct 29, 2020

Hi, Thanks for commenting. I did leave in the collinear points - you can leave them in or remove them depending on your needs with the algorithm.

@davidshumway
Copy link

Broken?

If self.points = [(4,9),(4,8),(8,2),(6,2),(8,3),(5,4),(7,3)] , then hull = [(4, 9), (5, 4), (6, 2), (8, 2), (8, 3), (4, 8)]??

@davidshumway
Copy link

image

@JacquesDuflos
Copy link

I used your code for a python script for Gimp, it works for me (I had to remove the duplicate points).
https://gist.github.com/JacquesDuflos/0a4914099d497631cff9211737e2f24f

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment