Coverage for src/ensae_teaching_cs/special/geometry_polygone.py: 84%

56 statements  

« prev     ^ index     » next       coverage.py v7.1.0, created at 2023-04-28 06:23 +0200

1""" 

2@file 

3@brief defines a polyline 

4""" 

5 

6import copy 

7from .geometry_point import GeometryException 

8from .geometry_segment import GeometrySegment 

9 

10 

11class GeometryPolygone(list): 

12 """ 

13 A sequence of point, the last one is connected to the first one. 

14 """ 

15 

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))) 

26 

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]) 

35 

36 def convex(self): 

37 """ 

38 @return the convex envelop 

39 

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 

56 

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 

66 

67 if mod: 

68 del cir[r] 

69 

70 return cir 

71 

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) 

76 

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