Code source de ensae_teaching_cs.special.geometry_polygone

"""
defines a polyline


:githublink:`%|py|5`
"""

import copy
from .geometry_point import GeometryException
from .geometry_segment import GeometrySegment


[docs]class GeometryPolygone(list): """ A sequence of point, the last one is connected to the first one. :githublink:`%|py|14` """
[docs] def barycentre(self): """ :return: the barycentre :githublink:`%|py|19` """ if len(self) == 0: raise GeometryException("no point") r = copy.copy(self[0]) for i in range(1, len(self)): r += self[i] return r * (1. / float(len(self)))
[docs] def circle(self): """ :return: a list of points ordered by angle taken to the barycenter (works only dimension 2) :githublink:`%|py|30` """ bary = self.barycentre() prod = [((p - bary).angle(), p) for p in self] prod.sort() return GeometryPolygone([p[1] for p in prod])
[docs] def convex(self): """ :return: the convex envelop only in 2 dimensions right now :githublink:`%|py|41` """ cir = self.circle() mod = True while mod: mod = False r = None n = len(cir) for i in range(2, n): a = cir[i - 1] - cir[i - 2] b = cir[i] - cir[i - 1] s = a.product(b) if s > 0: r = i - 1 mod = True break if not mod: for i in range(n, n + 2): a = cir[(i - 1) % n] - cir[(i - 2) % n] b = cir[i % n] - cir[(i - 1) % n] s = a.product(b) if s > 0: mod = True r = (i - 1) % len(n) break if mod: del cir[r] return cir
[docs] def in_convex(self, p): """ we assume the polygone is convex and the result of function convex (points sorted by angle we check then if a point p belongs to the envelop (only 2-dimension) :param p: point :return: boolean :githublink:`%|py|79` """ res = None for i in range(1, len(self)): s = GeometrySegment(self[i - 1], self[i]) t = s.equation_eval(p) if t == 0: continue r = 1 if t > 0 else -1 if res is None: res = r elif res != r: return False return True