Многоугольник видимости или область видимости для точки p на плоскости среди препятствий — это (возможно неограниченная) многоугольная область всех точек плоскости, видимых из точки p. Многоугольник видимости можно определить для видимости из отрезка или многоугольника. Многоугольники видимости полезны в робототехнике, компьютерных играх и для определения позиций объектов, например, для определеиня наилучшего расположения охраны в картинных галереях.
Если многоугольник видимости ограничен, то он является звёздчатым многоугольником. Многоугольник видимости ограничен, если все лучи, проведённые из точки, в конце концов, обрываются на некотором препятствии. Это случается, например, когда препятствия являются рёбрами простого многоугольника, а точка p находится внутри многоугольника. В таком случае многоугольник видимости может быть найден за линейное время[1][2][3][4].
Формально мы можем определить задачу о планарном многоугольнике видимости следующим образом. Пусть будет набором препятствий (отрезки, либо многоугольники) в . Пусть будет точкой в , не находящейся внутри препятствия. Тогда многоугольник видимости точки — это множество точек в , таких что для любой точки из отрезок не пересекает какой-либо объект из набора .
Аналогично, многоугольник видимости отрезка или многоугольник видимости ребра — это точки, видимые с любого места отрезка.
Многоугольники видимости полезны в робототехнике. Например, в ориентации робота[en] робот использует датчики, такие как лидар, которые обнаруживают препятствия, и область видимости аналогична многоугольнику видимости[5].
Они также полезны в компьютерных играх и имеется многочисленные онлайновые учебные курсы объясняют простые алгоритмы для реализации в играх [6][7][8].
Было предложено много алгоритмов вычисления многоугольника видимости для точки. Для различных вариантов задачи (то есть различных видов препятствий) алгоритмы могут отличаться по времени и сложности.
Наивные алгоритмы легко понять и реализовать, но они не оптимальны[en], поскольку они могут быть существенно медленнее других алгоритмов.
В реальной жизни светящаяся точка освещает область, видимую из точки, поскольку точка излучает свет во всех направлениях. Это можно смоделировать путём проведения лучей во многих направлениях. Предположим, что имеется точка и набор препятствий . Тогда псевдокод может быть выражен следующим образом:
Алгоритм простой_плохой_алгоритм( , ) := для : // проводим луч с углом with angle := для каждого препятствия из : := min( , расстояние от до препятствия в этом направлении) добавляем вершину в возвращаем
Теперь, если была бы возможность просмотреть бесконечно много углов, результат был бы правильным. К сожалению, невозможно просмотреть все возможные направления ввиду ограничений компьютеров. Можно создать приближение путём проведения, скажем, 50 лучей равномерно. Однако, это не точное решение, поскольку препятствия могут быть пропущены между двумя соседними лучами. Более того, алгоритм очень медленный, поскольку нужно проводить много лучей, а выходной многоугольник видимости может иметь много больше вершин, чем необходимо.
Описанный выше алгоритм может быть существенно улучшен как по скорости, так и по корректности путём наблюдения, что достаточно проводить лучи только к вершинам препятствий. Это потому, что любое огибание угла препятствия вдоль границы многоугольника видимости должно быть в некоторой угловой вершине препятствия.
Алгоритм простой_улучшенный_алгоритм( , ) := для каждого препятствия из : для каждой вершины of : // проводим луч из в := расстояние от до := угол of с для каждого препятствия из : := min( , расстояние от до ) добавляем вершину в возвращаем
Временная сложность алгоритма равна . Это потому, что алгоритм проводит луч в каждую из вершин и проверяет, где обрывается луч. Алгоритм должен проверить пересечение с каждым из препятствий. Это достаточно для многих простых приложений, таких как компьютерные игры и многие онлайновые обучающие курсы учат этому методу[8]. Однако, как мы можем видеть далее, существуют более быстрые алгоритмы со скоростью работы (или даже быстрее, если препятствием является простым многоугольником или имеется фиксированное число многоугольных дыр).
Если дан простой многоугольник и точка , алгоритм линейного времени является оптимальным для вычисления области , которая видна из точки . Такой алгоритм был предложен в 1981[2]. Однако он довольно сложен. В 1983 был предложен концептуально более простой алгоритм[3], но он имел небольшую ошибку, которая была исправлена в 1987[4].
Последний упомянутый алгоритм будет кратко изложен здесь. Он просто проходит границу многоугольника последовательно перебирая вершины и хранит стек вершин , где — вершина стека. Стек состоит из вершин, видимых из . Если потом обнаружатся вершины, которые закрывают часть , то закрытые вершины выталкиваются из стека . Алгоритм прекращает работу, когда состоит из всех видимых вершин, то есть, из желаемого многоугольника видимости. Эффективная реализация была опубликована в 2014[9].
Для точки в многоугольнике с дырами и вершинами (в сумме), можно показать, что в оптимален худшем случае алгоритм . Такой алгоритм был предложен в 1995 вместе с доказательством его оптимальности[10]. Однако это алгоритм опирается на алгоритм линейного времени триангуляризации многоугольника Чазелле, который крайне сложен.
Для точки среди множества из отрезков, которые могут пересекаться только на их концах, можно показать, что в худшем случае алгоритм со временем работы оптимален. Это потому, что алгоритм многоугольника видимости должен выводить вершины многоугольника видимости в отсортированном порядке, а следовательно задача сортировки может быть сведена к вычислению многоугольника видимости[11].
Заметим, что любой алгоритм, который вычисляет многоугольник видимости для точки среди отрезков может быть использован для вычисления многоугольника видимости для всех видов многоугольных препятствий, поскольку многоугольник может быть разбит на отрезки.
Алгоритм «Разделяй и властвуй» для вычисления многоугольника видимости был предложен в 1987[12].
Угловое выметание, то есть вращательный алгоритм выметающей прямой[en] для вычисления многоугольника видимости был предложен в 1985[13] и 1986[11]. Идея заключается в начальной сортировке концов отрезков по углу, а затем просмотре отсортированных точек. Во время итерирования события обрабатываются как куча. Эффективная реализация была опубликована в 2014[9].
Для точки среди произвольным образом пересекающихся отрезков задача о многоугольнике видимости сводится за линейное время к задаче о нижней огибающей. Согласно доводам Дэвенпорта — Шинцеля вычисление нижней огибающей в худшем случае имеет сложность от числа вершин, где — обратная функции Аккермана. Оптимальный в худшем случае алгоритм «разделяй и властвуй», работающий за время , создал Джон Хершбергер в 1989[14].
Для улучшения этой статьи желательно: |
Данная страница на сайте WikiSort.ru содержит текст со страницы сайта "Википедия".
Если Вы хотите её отредактировать, то можете сделать это на странице редактирования в Википедии.
Если сделанные Вами правки не будут кем-нибудь удалены, то через несколько дней они появятся на сайте WikiSort.ru .