def add(self, t): # поиск освещённого ребра for n in range(self.points.size()): if t.is_light(self.points.last(), self.points.first()): break self.points.push_last(self.points.pop_first()) # хотя бы одно освещённое ребро есть if t.is_light(self.points.last(), self.points.first()): # учёт удаления ребра, соединяющего конец и начало дека self._perimeter -= float(self.points.first().dist( self.points.last())) self._g -= support.lenght(self.points.first(), self.points.last()) self._area += abs( R2Point.area(t, self.points.last(), self.points.first())) # удаление освещённых рёбер из начала дека p = self.points.pop_first() while t.is_light(p, self.points.first()): self._g -= support.lenght(p, self.points.first()) self._perimeter -= float(p.dist(self.points.first())) self._area += abs(R2Point.area(t, p, self.points.first())) p = self.points.pop_first() self.points.push_first(p) # удаление освещённых рёбер из конца дека p = self.points.pop_last() while t.is_light(self.points.last(), p): self._g -= support.lenght(p, self.points.last()) self._perimeter -= float(p.dist(self.points.last())) self._area += abs(R2Point.area(t, p, self.points.last())) p = self.points.pop_last() self.points.push_last(p) # добавление двух новых рёбер self._perimeter += float( t.dist(self.points.first()) + t.dist(self.points.last())) self._g += \ support.lenght(t, self. points.first()) + support.lenght(t, self. points.last()) self.points.push_first(t) return self
def __init__(self, a, b, c): self.points = Deq() self.points.push_first(b) if b.is_light(a, c): self.points.push_first(a) self.points.push_last(c) else: self.points.push_last(a) self.points.push_first(c) self._perimeter = a.dist(b) + b.dist(c) + c.dist(a) self._area = abs(R2Point.area(a, b, c))
def __init__(self, a, b, c): self.points = Deq() self.points.push_first(b) if b.is_light(a, c): self.points.push_first(a) self.points.push_last(c) else: self.points.push_last(a) self.points.push_first(c) self._perimeter = a.dist(b) + b.dist(c) + c.dist(a) self._area = abs(R2Point.area(a, b, c)) # подсчет велины g которая включает сумму искомых нами сегментов self._g = support.lenght(a, b) + support.lenght(b, c) \ + support.lenght(c, a)
def __init__(self, a, b, c): self.points = Deq() self.points.push_first(b) if b.is_light(a, c): self.points.push_first(a) self.points.push_last(c) else: self.points.push_last(a) self.points.push_first(c) self._perimeter = a.dist(b) + b.dist(c) + c.dist(a) self._area = abs(R2Point.area(a, b, c)) self._g = a.dist(self.fixed_point) + b.dist(self.fixed_point) + \ c.dist(self.fixed_point) self.rectangle.add_crossing( b, c) # Проверяем, пересекает ли отрезок какую-либо из граней self.rectangle.add_crossing( b, a) # Проверяем, пересекает ли отрезок какую-либо из граней self.rectangle.add_crossing( a, c) # Проверяем, пересекает ли отрезок какую-либо из граней # Добавляем в Дек вершины прямоугольника, которые находятся внутри выпуклой оболочки, # чтобы корректно считать площадь, если НЕТ пересечения self.rectangle.add_inside(a, b, c)
def test_area4(self): a, b, c = R2Point(0.0, 0.0), R2Point(1.0, 0.0), R2Point(1.0, 1.0) assert R2Point.area(a, c, b) < 0.0
def test_area3(self): a, b, c = R2Point(0.0, 0.0), R2Point(1.0, 0.0), R2Point(1.0, 1.0) assert R2Point.area(a, b, c) > 0.0
def test_area2(self): a, b, c = R2Point(0.0, 0.0), R2Point(1.0, 1.0), R2Point(2.0, 2.0) assert R2Point.area(a, b, c) == approx(0.0)
def test_area1(self): a = R2Point(1.0, 1.0) assert R2Point.area(a, a, a) == approx(0.0)
def add_common_point(self, t): # Если такая точка уже есть, то ничего не делаем #print('Common Points Before:', self.common_points) if t in self.common_points: return self # Поначалу просто наберем хотя бы одну точку if self.common_points.size() == 0: self.common_points.push_first(t) # Потом добавляем в конец другую точку if self.common_points.size() == 1: self.common_points.push_last(t) # Если у нас есть две точки, то добавляя третью нам надо расширить отрезок, удалив серединную точку if self.common_points.size() == 2: # Если точки лежат на одной прямой if not R2Point.is_triangle(t, self.common_points.first(), self.common_points.last()): # Проверяем, находится ли точка начала дека внутри отрезка if self.common_points.first().is_inside( t, self.common_points.last()): self.common_points.pop_first() self.common_points.push_first( t) # Если да, то заменяем на добавляемую точку # или если точка конца дека находится внутри отрезка elif self.common_points.last().is_inside( t, self.common_points.first()): self.common_points.pop_last() self.common_points.push_last(t) # Если же у нас уже накопилось более трех точек, то ищем площадь if self.common_points.size() >= 2: # поиск освещённого ребра for n in range(self.common_points.size()): if t.is_light(self.common_points.last(), self.common_points.first()): break self.common_points.push_last(self.common_points.pop_first()) # хотя бы одно освещённое ребро есть (если не внутри) if t.is_light(self.common_points.last(), self.common_points.first()): # учёт удаления ребра, соединяющего конец и начало дека self._common_perimeter -= self.common_points.first().dist( self.common_points.last()) area = abs( R2Point.area(t, self.common_points.last(), self.common_points.first())) self._common_area += area # удаление освещённых рёбер из начала дека #print('OK1:',self.common_points) #print('OK1_first:',self.common_points.first()) #print('OK1_last:',self.common_points.last()) #print('OK1_size:',self.common_points.size()) p = self.common_points.pop_first() #print('OK2:',self.common_points) #print('OK3:',p) #print('OK4:',self.common_points.array[0]) while t.is_light(p, self.common_points.first()): self._common_perimeter -= p.dist( self.common_points.first()) self._common_area += abs( R2Point.area(t, p, self.common_points.first())) p = self.common_points.pop_first() #print('OK5_p:', p) #print('OK5_after_p:', self.common_points) self.common_points.push_first(p) # удаление освещённых рёбер из конца дека p = self.common_points.pop_last() while t.is_light(self.common_points.last(), p): self._common_perimeter -= p.dist(self.common_points.last()) self._common_area += abs( R2Point.area(t, p, self.common_points.last())) p = self.common_points.pop_last() self.common_points.push_last(p) # добавление двух новых рёбер self._common_perimeter += t.dist(self.common_points.first()) + \ t.dist(self.common_points.last()) self.common_points.push_first(t) #print('Common Points After:', self.common_points) return self
def add(self, t): # поиск освещённого ребра for n in range(self.points.size()): if t.is_light(self.points.last(), self.points.first()): break self.points.push_last(self.points.pop_first()) # хотя бы одно освещённое ребро есть if t.is_light(self.points.last(), self.points.first()): # учёт удаления ребра, соединяющего конец и начало дека self._perimeter -= self.points.first().dist(self.points.last()) self._area += abs( R2Point.area(t, self.points.last(), self.points.first())) #print('OK11', t) #print('OK12', self.points.first()) #print('OK13', self.points.last()) self.rectangle.add_crossing(t, self.points.first( )) # Проверяем, пересекает ли отрезок какую-либо из граней self.rectangle.add_crossing(t, self.points.last( )) # Проверяем, пересекает ли отрезок какую-либо из граней # Добавляем в Дек вершины прямоугольника, которые находятся внутри выпуклой оболочки, # чтобы корректно считать площадь, если НЕТ пересечения self.rectangle.add_inside(self.points.first(), self.points.last(), t) # удаление освещённых рёбер из начала дека p = self.points.pop_first() while t.is_light(p, self.points.first()): self._perimeter -= p.dist(self.points.first()) self._area += abs(R2Point.area(t, p, self.points.first())) self._g -= p.dist(self.fixed_point) p = self.points.pop_first() self.points.push_first(p) # удаление освещённых рёбер из конца дека p = self.points.pop_last() while t.is_light(self.points.last(), p): self._perimeter -= p.dist(self.points.last()) self._area += abs(R2Point.area(t, p, self.points.last())) self._g -= p.dist(self.fixed_point) p = self.points.pop_last() self.points.push_last(p) # добавление двух новых рёбер self._perimeter += t.dist(self.points.first()) + \ t.dist(self.points.last()) self.points.push_first(t) self._g += t.dist(self.fixed_point) self.rectangle.add_crossing( self.points.first(), t) # Проверяем, пересекает ли отрезок какую-либо из граней self.rectangle.add_crossing( self.points.last(), t) # Проверяем, пересекает ли отрезок какую-либо из граней # Добавляем в Дек вершины прямоугольника, которые находятся внутри выпуклой оболочки, # чтобы корректно считать площадь, если НЕТ пересечения self.rectangle.add_inside(self.points.first(), self.points.last(), t) return self