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

56 statements

, created at 2023-01-27 05:44 +0100

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