Skip to content

Commit a58620d

Browse files
committed
Implemented Graham's convex hull algorithm
1 parent 46fb224 commit a58620d

File tree

2 files changed

+104
-0
lines changed

2 files changed

+104
-0
lines changed

algorithms/GrahamAlgorithm.py

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
from math import atan2, sqrt
2+
from pointPosition import position
3+
4+
5+
class Point:
6+
def __init__(self, x, y):
7+
self.x = x
8+
self.y = y
9+
10+
11+
lowest_point = None
12+
13+
14+
def angle(point):
15+
return atan2(point.y - lowest_point.y, point.x - lowest_point.x)
16+
17+
18+
def distance(point):
19+
return sqrt((point.x - lowest_point.x)**2 + (point.y - lowest_point.y)**2)
20+
21+
22+
def find_lowest(points):
23+
temp_low = points[0]
24+
minimum = float("inf")
25+
for p in points:
26+
if p.y < minimum:
27+
temp_low = p
28+
minimum = p.y
29+
elif p.y == minimum and p.x < temp_low.x:
30+
temp_low = p
31+
global lowest_point
32+
lowest_point = temp_low
33+
34+
35+
def graham(points):
36+
points = sorted(points, key=lambda x: (angle(x), distance(x)))
37+
stack = []
38+
stack.append(points[0])
39+
stack.append(points[1])
40+
stack.append(points[2])
41+
for i in range(3, len(points)):
42+
while position(stack[-1], stack[-2], points[i]) == 2:
43+
stack.pop()
44+
stack.append(points[i])
45+
return stack
46+
47+
48+
if __name__ == "__main__":
49+
points = []
50+
p1 = Point(3, 8)
51+
p2 = Point(1, 4)
52+
p3 = Point(2, 5)
53+
p4 = Point(7, 2)
54+
p5 = Point(3, 2)
55+
p6 = Point(5, 4)
56+
points.append(p1)
57+
points.append(p2)
58+
points.append(p3)
59+
points.append(p4)
60+
points.append(p5)
61+
points.append(p6)
62+
find_lowest(points)
63+
hull = graham(points)
64+
for point in hull:
65+
print("Point x: " + str(point.x) + ", y: " + str(point.y))

algorithms/pointPosition.py

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Given three points on a plane, determine the position of the third
2+
# point relative to p->q vector.
3+
class Point:
4+
def __init__(self, x, y):
5+
self.x = x
6+
self.y = y
7+
8+
9+
def position(p, q, r):
10+
first = p.x * q.y * 1
11+
second = q.x * r.y * 1
12+
third = r.x * p.y * 1
13+
part1 = first + second + third
14+
15+
fourth = 1 * q.y * r.x
16+
fifth = 1 * r.y * p.x
17+
sixth = 1 * p.y * q.x
18+
part2 = fourth + fifth + sixth
19+
20+
result = part1 - part2
21+
if result > 0:
22+
return 2
23+
elif result < 0:
24+
return 1
25+
else:
26+
return 0
27+
28+
29+
if __name__ == "__main__":
30+
p = Point(5, 4)
31+
q = Point(3, 2)
32+
r = Point(6, 7)
33+
outcome = position(p, q, r)
34+
if outcome == 2:
35+
print("Point r is on the left side of pq vector")
36+
elif outcome == 1:
37+
print("Point r is on the right side of the pq vector")
38+
else:
39+
print("Point r is on the same line as pq vector")

0 commit comments

Comments
 (0)