1
1
from collections import namedtuple
2
- import numpy as np
3
2
import matplotlib .pyplot as plt
3
+ import random
4
4
5
5
6
6
Point = namedtuple ('Point' , 'x y' )
7
7
8
8
9
9
class ConvexHull (object ):
10
- points = []
10
+ _points = []
11
+ _hull_points = []
11
12
12
13
def __init__ (self ):
13
14
pass
14
15
15
16
def add (self , point ):
16
- self .points .append (point )
17
+ self ._points .append (point )
17
18
18
- def display (self ):
19
- x = [p .x for p in self .points ]
20
- y = [p .y for p in self .points ]
19
+ def _get_orientation (self , origin , p1 , p2 ):
20
+ '''
21
+ Returns the orientation of the Point p1 with regards to Point p2 using origin.
22
+ :param p1:
23
+ :param p2:
24
+ :return: integer
25
+ '''
26
+ difference = (
27
+ ((p2 .x - origin .x ) * (p1 .y - origin .y ))
28
+ - ((p1 .x - origin .x ) * (p2 .y - origin .y ))
29
+ )
30
+
31
+ return difference
32
+
33
+ def compute_hull (self ):
34
+ '''
35
+ Computes the convex hull and returns the points on the hull.
36
+ :return:
37
+ '''
38
+ points = sorted (self ._points , key = lambda temp_point : temp_point .x )
39
+
40
+ start = points [0 ]
41
+ point = points [0 ]
42
+ self ._hull_points .append (start )
43
+
44
+ far_point = None
45
+ while far_point is not start :
46
+
47
+ p1 = None
48
+ for p in points :
49
+ if p is point :
50
+ continue
51
+ else :
52
+ p1 = p
53
+ break
54
+
55
+ far_point = p1
56
+
57
+ for p2 in points :
58
+ if p2 is point or p2 is p1 :
59
+ continue
60
+ else :
61
+ direction = self ._get_orientation (point , far_point , p2 )
62
+ if direction > 0 :
63
+ far_point = p2
21
64
65
+ self ._hull_points .append (far_point )
66
+ point = far_point
67
+
68
+ def get_hull_points (self ):
69
+ if self ._points and not self ._hull_points :
70
+ self .compute_hull ()
71
+
72
+ return self ._hull_points
73
+
74
+ def display (self ):
75
+ x = [p .x for p in self ._points ]
76
+ y = [p .y for p in self ._points ]
22
77
plt .plot (x , y , marker = 'D' , linestyle = 'None' )
78
+
79
+ hx = [p .x for p in self ._hull_points ]
80
+ hy = [p .y for p in self ._hull_points ]
81
+ plt .plot (hx , hy )
82
+
23
83
plt .title ('Convex Hull' )
24
84
plt .show ()
25
85
26
86
27
87
def main ():
28
88
ch = ConvexHull ()
89
+ # for _ in range(10):
90
+ # ch.add(Point(random.randint(0, 100), random.randint(0, 100)))
91
+
29
92
ch .add (Point (1 , 4 ))
30
93
ch .add (Point (3 , 12 ))
31
94
ch .add (Point (5 , 7 ))
@@ -39,6 +102,7 @@ def main():
39
102
ch .add (Point (8 , 16 ))
40
103
ch .add (Point (2 , 6 ))
41
104
105
+ ch .compute_hull ()
42
106
ch .display ()
43
107
44
108
0 commit comments