Exemple #1
0
    def make_triangles(self, p):
        # ищем треугольник для вставки внутрь него точки
        for index in range(len(self.triangles_list)):
            if self.triangles_list[index].is_point_in(p):
                insert_index = index
                break
        else:
            print("Точка должна лежать по крайней мере в одном из треугольников.")
            return None
        # треугольник, в который вставляем точку
        insert_triangle = self.triangles_list[insert_index]

        # создаём 3 новых треугольника
        p1, p2, p3 = insert_triangle.points()

        e1 = (p1, p2)
        e2 = (p2, p3)
        e3 = (p1, p3)

        e4 = (p1, p)
        e5 = (p2, p)
        e6 = (p3, p)

        t1 = insert_triangle.get_neigh(e1)
        t2 = insert_triangle.get_neigh(e2)
        t3 = insert_triangle.get_neigh(e3)

        new_t1 = Triangle([[e1, t1],
                           [e4, None],
                           [e5, None]],
                          insert_index)
        new_t2 = Triangle([[e2, t2],
                           [e5, new_t1],
                           [e6, None]],
                          len(self.triangles_list))
        new_t3 = Triangle([[e3, t3],
                           [e4, new_t1],
                           [e6, new_t2]],
                          len(self.triangles_list) + 1)

        new_t1.set_neigh(e5, new_t2)
        new_t1.set_neigh(e4, new_t3)
        new_t2.set_neigh(e6, new_t3)

        # обновляем соседей треугольника, в который вставили точку
        if t1 is not None:
            t1.set_neigh(e1, new_t1)
        if t2 is not None:
            t2.set_neigh(e2, new_t2)
        if t3 is not None:
            t3.set_neigh(e3, new_t3)

        # заменяем старый треугольник и добавляем новые
        self.triangles_list[insert_index] = new_t1
        self.triangles_list.append(new_t2)
        self.triangles_list.append(new_t3)

        # рёбра для возможного flip - пары [треугольник, проблемное ребро]
        return deque([[new_t1, e1], [new_t2, e2], [new_t3, e3]])
Exemple #2
0
    def add_point(self, p):
        # получаем новые образованные рёбра и треугольники в виде очереди
        flip_list = self.make_triangles(p)
        # флипаем некоторые рёбра, добавляем их соседей в очередь
        while flip_list:
            t1, e = flip_list.popleft()
            if t1 is None:
                continue
            t2 = t1.get_neigh(e)
            if t2 is None:
                continue
            p1, p2 = e
            p3 = t1.get_opposite(e)
            p4 = t2.get_opposite(e)
            # получаем окружность по трём точкам
            circle = Circle.get_circle(p1, p2, p3)
            # если четвертая точка в окружности, то делаем флип
            if Circle.is_in_circle(circle, p4):
                id1 = t1.id
                id2 = t2.id
                e13 = (p1, p3)
                e14 = (p1, p4)
                e23 = (p2, p3)
                e24 = (p2, p4)
                e34 = (p3, p4)

                t13 = t1.get_neigh(e13)
                t23 = t1.get_neigh(e23)
                t14 = t2.get_neigh(e14)
                t24 = t2.get_neigh(e24)

                t1_new = Triangle([[e13, t13],
                                   [e14, t14],
                                   [e34, None]],
                                  id1)
                t2_new = Triangle([[e23, t23],
                                   [e24, t24],
                                   [e34, t1_new]],
                                  id2)
                t1_new.set_neigh(e34, t2_new)

                # заменяем старые треугольники на новые
                self.triangles_list[id1] = t1_new
                self.triangles_list[id2] = t2_new

                if t13 is not None:
                    t13.set_neigh(e13, t1_new)
                if t14 is not None:
                    t14.set_neigh(e14, t1_new)
                if t23 is not None:
                    t23.set_neigh(e23, t2_new)
                if t24 is not None:
                    t24.set_neigh(e24, t2_new)
                # добавляем новые потенциально опасные ребра в виде пар [треугольник, проблемное ребро]
                flip_list.append([t14, e14])
                flip_list.append([t24, e24])
                flip_list.append([t13, e13])
                flip_list.append([t23, e23])