Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""
2@file
3@brief defines a polyline
4"""
6import copy
7from .geometry_point import GeometryException
8from .geometry_segment import GeometrySegment
11class GeometryPolygone(list):
12 """
13 A sequence of point, the last one is connected to the first one.
14 """
16 def barycentre(self):
17 """
18 @return the barycentre
19 """
20 if len(self) == 0:
21 raise GeometryException("no point")
22 r = copy.copy(self[0])
23 for i in range(1, len(self)):
24 r += self[i]
25 return r * (1. / float(len(self)))
27 def circle(self):
28 """
29 @return a list of points ordered by angle taken to the barycenter (works only dimension 2)
30 """
31 bary = self.barycentre()
32 prod = [((p - bary).angle(), p) for p in self]
33 prod.sort()
34 return GeometryPolygone([p[1] for p in prod])
36 def convex(self):
37 """
38 @return the convex envelop
40 only in 2 dimensions right now
41 """
42 cir = self.circle()
43 mod = True
44 while mod:
45 mod = False
46 r = None
47 n = len(cir)
48 for i in range(2, n):
49 a = cir[i - 1] - cir[i - 2]
50 b = cir[i] - cir[i - 1]
51 s = a.product(b)
52 if s > 0:
53 r = i - 1
54 mod = True
55 break
57 if not mod:
58 for i in range(n, n + 2):
59 a = cir[(i - 1) % n] - cir[(i - 2) % n]
60 b = cir[i % n] - cir[(i - 1) % n]
61 s = a.product(b)
62 if s > 0:
63 mod = True
64 r = (i - 1) % len(n)
65 break
67 if mod:
68 del cir[r]
70 return cir
72 def in_convex(self, p):
73 """
74 we assume the polygone is convex and the result of function convex (points sorted by angle
75 we check then if a point p belongs to the envelop (only 2-dimension)
77 @param p point
78 @return boolean
79 """
80 res = None
81 for i in range(1, len(self)):
82 s = GeometrySegment(self[i - 1], self[i])
83 t = s.equation_eval(p)
84 if t == 0:
85 continue
86 r = 1 if t > 0 else -1
87 if res is None:
88 res = r
89 elif res != r:
90 return False
91 return True