Научная статья на тему 'Алгоритмы вычислительной геометрии. Пересечение отрезков: метод заметания плоскости'

Алгоритмы вычислительной геометрии. Пересечение отрезков: метод заметания плоскости Текст научной статьи по специальности «Математика»

CC BY
2338
131
i Надоели баннеры? Вы всегда можете отключить рекламу.
Ключевые слова
ВЫЧИСЛИТЕЛЬНАЯ ГЕОМЕТРИЯ / ЗАДАЧЕ О ПЕРЕСЕЧЕНИИ ОТРЕЗКОВ / МЕТОД ЗАМЕТАНИЯ ПЛОСКОСТИ

Аннотация научной статьи по математике, автор научной работы — Ивановский Сергей Алексеевич, Симончик Сергей Константинович

Статья продолжает цикл, начатый в №№ 1, 2, 3 за 2007 г. Авторы раасказывают об одной из базовых задач вычислительной геометрии задаче о пересечении отрезков на плоскости, знакомят читателя с таким важным и эффективным приемом построения геометрических алгоритмов, как метод заметания плоскости прямой линией.

i Надоели баннеры? Вы всегда можете отключить рекламу.

Похожие темы научных работ по математике , автор научной работы — Ивановский Сергей Алексеевич, Симончик Сергей Константинович

iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.
i Надоели баннеры? Вы всегда можете отключить рекламу.

Текст научной работы на тему «Алгоритмы вычислительной геометрии. Пересечение отрезков: метод заметания плоскости»

Ивановский Сергей Алексеевич, Симончик Сергей Константинович

АЛГОРИТМЫ ВЫЧИСЛИТЕЛЬНОЙ ГЕОМЕТРИИ. ПЕРЕСЕЧЕНИЕ ОТРЕЗКОВ: МЕТОД ЗАМЕТАНИЯ ПЛОСКОСТИ

1. ВВЕДЕНИЕ

Тема этой статьи определяется не только желанием авторов рассказать об одной из базовых задач вычислительной геометрии - задаче о пересечении отрезков на плоскости, но и познакомить читателя с таким важным и эффективным приемом построения геометрических алгоритмов, как метод заметания плоскости прямой линией.

Рис. 1. Примеры различных карт и планов: многие геометрические образы на них представлены (или могут быть аппроксимированы) отрезками прямых линий

Задача о пересечении прямолинейных отрезков на плоскости кратко формулируется так: дано конечное множество отрезков; требуется найти их пересечения. Эта задача имеет разнообразные приложения.

В геоинформационны1х системах (и не только в них) используются разнообразные географические карты. На картах отображается множество объектов: населенные пункты, границы, реки и другие водоемы, овраги и горы, дороги разного типа, мосты, линии электропередач и другие промышленные объекты; на картах городов: улицы, скверы и площади, кварталы и отдельные дома, реки и каналы (см. рис. 1). Все эти объекты представляются определенными геометрическими образами, многие из которых можно считать так или иначе состоящими из прямолинейных отрезков. Поэтому определение пересечения географических объектов, например, дорог, рек, границ и т. п., сводится к нахождению пересечений множества отрезков.

В машинной графике требуются методы удаления невидимых линий и

поверхностей в трехмерных сценах, когда различные объекты сцены частично закрывают друг друга (см. рис. 2). Не имея оптимального алгоритма определения попарных пересечений отрезков из заданного набора, из которых, как правило, состоит большинство объектов сцены, трудно рассчитывать на эффективную реализацию удаления невидимых линий.

В микроэлектронике возникает необходимость проверки пересечения различных компонентов интегральных схем, состоящих из большого количества элементов (до миллиона и более), что невозможно осуществить без компьютерных методов, в том числе без алгоритмов пересечения геометрических объектов.

2. ПЕРЕСЕЧЕНИЕ ПРЯМОЛИНЕЙНЫХ ОТРЕЗКОВ НА ПЛОСКОСТИ.

ПОСТАНОВКА ЗАДАЧИ

Уточним постановку задачи о пересечении отрезков и рассмотрим различные фор-

Рис. 2. Удаление невидимых линий

мы этой задачи, а также некоторые другие задачи, тесно связанные с ней.

Задача 1. ПРОВЕРКА ПЕРЕСЕЧЕНИЯ ПРЯМОЛИНЕЙНЫХ ОТРЕЗКОВ (ПППО). Дано: п прямолинейных отрезков на плоскости. Требуется: определить факт пересечения хотя бы двух из них (ответ задачи -«да», если пересекаются, или «нет» в противном случае).

Задача 2. ВСЕ ПЕРЕСЕЧЕНИЯ ОТРЕЗКОВ (ВПО). Дано: п прямолинейных отрезков на плоскости. Требуется: найти все попарные пересечения отрезков.

Постановку этой задачи можно уточнить, рассматривая две её формы:

1. Задача 2.1. ВПО-П: Задача ВПО в форме подсчета (ответ: число попарных пересечений).

2. Задача 2.2. ВПО-О: Задача ВПО в форме отчета (ответ: перечень всех пар пересекающихся отрезков).

Очевидно, что задача ВПО-П не сложнее задачи ВПО-О, поскольку из ответа второй задачи можно легко (за линейное время) получить ответ первой.

Рис. 3. Простые (а и б) и непростые (в и г) многоугольники

а)

Рх

Р?

б)

в)

Рх

г)

Рис. 4. Исходные многоугольники Р1 и Р2 (а и б). Случай в) Р2 сР1. Случай г) в точке д пересекаются ребра

Р1

Задача 3. ПРОВЕРКА ПЕРЕСЕЧЕНИЯ МНОГОУГОЛЬНИКОВ (ППМ). Дано: два простых многоугольника Р1 (с п вершинами) и Р2 (с т вершинами). Требуется: определить, пересекаются ли они (ответ задачи - «да», если пересекаются, или «нет» в противном случае).

Напомним, что простым многоугольником называется такой многоугольник, у которого никакая пара его непоследовательных ребер не имеет общих точек. Примеры простых и непростых многоугольников приведены на рис. 3.

Так как в задаче 3 входные многоугольники Р1 и Р2 простые, то при любом пересечении их ребер это будут ребра разных многоугольников. Пусть £ (п) время, необходимое для решения задачи 1 (ПППО). Тогда факт пересечения многоугольников Р1 и Р2 можно определить за время £ (п + т). При этом если в задаче ПППО получен ответ «да», то это означает, что многоугольники Р1 и Р2 пересекаются (пересекаются их границы). Если в задаче ПППО получен

Рис. 5. Число пересечений справа от точки д равно 5, следовательно, точка д лежит внутри многоугольника. Число пересечений справа от точки д равно 6, следовательно, точка д лежит вне многоугольника

ответ «нет», то необходимо проверить случаи Р1сР2 и Р2 с Р1 (см. рис. 4).

Проверку Р1 с Р2 можно выполнить, определив для любой вершины д многоугольника Р1 ее принадлежность многоугольнику Р2. Если вершина д й Р2, то тем же способом следует проверить Р2 с Р1. Проверка принадлежности точки д простому многоугольнику Р может быть выполнена за время О (п) (см., например [1]). Идея алгоритма такова (см. рис. 5): следует подсчитать число пересечений к линией у = ду сторон многоугольника, например справа от точки д = (дх, ), тогда если к нечетно, то точка д лежит внутри многоугольника.

В статье [2] мы уже использовали понятие преобразования задач. Напомним, что задача А преобразуется в задачу В за время О(Т(п)) (будем обозначать это, как

А —!М—^ в), если задачу А можно решить следующим образом:

1. Из исходных данных к задаче А сконструировать соответствующие исходные данные к задаче В за время О(Т(п)).

2. Решить задачу В.

3. Из результата решения задачи В получить результат решения задачи А за время О (Т(п)).

Можно подвести итог нашего обсуждения связи задачи 3 о проверке пересечения многоугольников (ППМ) и задачи 1 о проверке пересечения прямолинейных отрезков (ПППО):

ППМ ——® ПППО.

Отметим, что сложность алгоритмов, работающих с многоугольниками, может зависеть от того, известно ли, что многоуголь-

Ч

Рис. 6. Примеры простых многоугольников при n = 1000

ник простой. Проверка простоты многоугольника не является простой задачей. Например, при тестировании программ, порождающих простые п-угольники, в случае больших значений п визуальный анализ, как правило, неосуществим. На рис. 6 в качестве примера приведены некоторые простые многоугольники при п = 1000. Уже здесь при данном разрешении трудно оценить простоту многоугольников, а во многих задачах, речь идет о многоугольниках размера около п = 1 000 000.

Задача 4. ТЕСТ ПРОСТОТЫ МНОГОУГОЛЬНИКА (ТПМ). Дано: многоугольник Р (с п вершинами). Требуется: определить, прост ли он (ответ задачи - «да», если многоугольник простой, или «нет» в противном случае).

Многоугольник прост тогда и только тогда, когда никакая пара его ребер не пересекается. Следовательно, тест пересечения многоугольников (ТПМ) преобразуется в задачу проверки пересечения прямолинейных отрезков (ПППО):

КОВ преобразуется в задачу 2.1 - ВСЕ ПЕРЕСЕЧЕНИЯ ОТРЕЗКОВ (в форме подсчета), которая, в свою очередь, преобразуется в задачу 2.2 - ВСЕ ПЕРЕСЕЧЕНИЯ ОТРЕЗКОВ (в форме отчета):

ПППО

ВПО-П

ВПО-О.

Действительно, если иметь ответ задачи ВПО-О в виде списка пар пересекающихся отрезков, то прямым подсчетом можно получить ответ задачи ВПО-П: число пересечений к (к > 0). Далее, если к > 0, то ответом задачи ПППО является «да», если же к = 0, то ответом будет «нет».

Задача ВПО-О решается очевидным ал-

горитмом: перебираются все

n(n — 1)

пары

ТПМ

ПППО.

3. НИЖНЯЯ ОЦЕНКА СЛОЖНОСТИ ПРОВЕРКИ ПЕРЕСЕЧЕНИЯ ПРЯМОЛИНЕЙНЫХ ОТРЕЗКОВ

Рассмотрим задачи 1 и 2. Используя преобразование задач, легко показать, что задача 1 - ПРОВЕРКА ПЕРЕСЕЧЕНИЯ ПРЯМОЛИНЕЙНЫХ ОТРЕЗ

-'/., 1 \ \\Vk

отрезков и каждая пара проверяется на пересечение. Этот «лобовой» алгоритм имеет сложность O(n2). Этот же алгоритм с учетов описанных преобразований задач 1 и 2 решает и задачи ВПО-П и ПППО. Естественно задать вопрос: можно ли решить все эти задачи каким-либо более эффективным алгоритмом? Для ответа на этот вопрос целесообразно сначала выявить нижнюю оценку сложности задачи ПППО, то есть выяснить, каково необходимое время гарантированного решения задачи при произвольных входных данных. Имеется в виду, что всегда можно предъявить для алгоритма, решающего задачу, такие исходные данные, что время работы алгоритма (или количество операций алгоритма) будет не менее некоторой определенной величины, зависящей от размера входных данных задачи (в нашем случае от количества отрезков n).

а)

1 0 1

10 10

1 0

1 0 1

0 0 10 1

1

0

01

0

1

101

Рис. 7. Проверка наложения интервалов: а) последовательность «01010101010101» чередующаяся - нет наложений; б) последовательность «00101100101101» не чередующаяся - есть наложения интервалов

Для выявления нижней оценки рассмотрим задачу ПППО в одномерном случае: все заданные отрезки расположены на одной прямой, и необходимо проверить, пересекаются ли хотя бы два из них. Ясно, что задача на плоскости не проще, чем задача на прямой. В одномерном случае задачу можно переформулировать так: заданы n интервалов на вещественной оси и необходимо узнать, не перекрываются ли какие-нибудь два из них. Конечно, наш «лобовой» алгоритм решает эту задачу за время O (n2). Можно поступить иначе. Пометим все левые концы интервалов знаком «0», а все правые - знаком «1» и упорядочим по возрастанию 2n концевых точек заданных интервалов за время O (n log n). Интервалы не перекрываются тогда и только тогда, когда после сортировки последовательность пометок является чередующейся -«0101...0101» (см. рис. 7).

Проверку чередования можно провести за время O (n) и, следовательно, решить всю задачу за время O(n log n).

Фактически этот алгоритм является преобразованием задачи ПППО в задачу сортировки и дает верхнюю оценку сложности. Для получения нижней оценки требуется преобразовать некоторую задачу с известной нижней оценкой (вычислительный прототип) в задачу ПППО. Задача сортировки на эту роль не подходит. Рассмотрим задачу ПРОВЕРКИ ЕДИНСТВЕННОСТИ ЭЛЕМЕНТОВ (ПЕЭ): даны n вещественных чисел, требуется проверить, все ли они различны. Очевидно, задача ПЕЭ преобразуется за время O (n) в задачу сортировки. Однако обратного преобразования нет. Оказывается, что нижняя оценка задачи ПЕЭ есть W (n log n) и этот факт устанавливается прямым использованием формальной вы-

числительной модели, основанной на деревьях решений (см. [1], с. 232). Покажем, что задача ПППО преобразуется в задачу ПЕЭ. Действительно, за время O (n) заданный набор из n вещественных чисел jxj можно преобразовать в набор из n интервалов {[xt, X;]}. Эти (вырожденные) интервалы перекрываются тогда и только тогда, когда среди исходных чисел {x;} есть совпадающие. Следовательно, ПЕЭ ———> ПППО, и нижняя оценка задачи ПППО есть W (n log n), так как решив задачу ПППО за меньшее, чем W (n log n), время, мы могли бы и задачу ПЕЭ решить за меньшее время, что невозможно.

Итак, нижняя оценка сложности задач о пересечении отрезков на плоскости (задач ПППО, ВПО-П и ВПО-О) есть W(n log n). Достижима ли она, то есть существуют ли алгоритмы, решающие перечисленные задачи за время O(n log n)? Ответ на этот вопрос будет дан в разделе 5.

4. БАЗОВАЯ ОПЕРАЦИЯ «ПЕРЕСЕЧЕНИЕ ДВУХ ОТРЕЗКОВ»

Определяя нижнюю оценку сложности задач о пересечении отрезков, мы считали, что базовые операции, используемые в этих задачах, выполняются за время O (1). Можно предположить, что основной базовой операцией будет проверка пересечения пары отрезков.

Определять факт пересечения пары отрезков можно в два этапа. Сначала определяется факт пересечения ограничивающих прямоугольников каждого из отрезков (этот

0

0

а)

Рис. 8. Ограничивающие прямоугольники: а) из пересечения отрезков следует пересечение прямоугольников; б) из пересечения прямоугольников не следует пересечение отрезков; в) из факта непересечения прямоугольников следует факт непересечения отрезков

грубый тест выполняется быстро). Ограничивающий прямоугольник отрезка является наименьшим из прямоугольников, содержащих отрезок и имеющих стороны, параллельные осям координат. На рис. 8 показаны ограничивающие прямоугольники ориентированных отрезков [ра,рь ] и [рс, рЛ ] в различных ситуациях. Если ограничивающие прямоугольники не пересекаются, то и отрезки не пересекаются, если же установлен факт пересечения ограничивающих прямоугольников, то следует перейти ко второму этапу и проверить собственно пересечение отрезков (точный тест).

Перед проверкой пересечения прямоугольников полезно сначала определить ограничивающие прямоугольники отрезков, используя следующий вспомогательный алгоритм (листинг 1).

Два прямоугольника со сторонами, параллельными координатным осям, пересекаются тогда и только тогда, когда пересекаются и их проекции на ось х, и их проекции на ось у. Алгоритм проверки пересечения прямоугольников можно представить в виде алгоритма (см. листинг 2).

Условное выражение в строке 1 алгоритма иллюстрируется на рис. 9 (на примере пересечения x-проекций, то есть части конъюнкции (xb > xc) and (xd > xa).

Следует отметить, что в случаях, когда хотя бы один из исходных отрезков [pa, pb ] и [ Pc,Pd ] вертикален или горизонтален, алгоритмы BoundingRectangle и Rectangles Intersect дают правильный результат.

Итак, если на первом этапе отсутствие пересечения двух отрезков не установлено тестом на пересечение ограничивающих прямоугольников, то необходимо применить точный тест. В основе теста лежит следующее утверждение: два отрезка пересекаются тогда и только тогда, когда каждый из отрезков пересекается с прямой, содержащей другой отрезок. Различные граничные случаи требуют аккуратного рассмотрения (см. далее). Отрезок [ pa,pb ] пересекается с прямой, если концы отрезка лежат по разные стороны от прямой или на прямой (хотя бы один конец). Как мы знаем [3, стр. 9], определить, лежит ли точка q = (xq,yq) по левую или по правую сторону от прямой, содержащей ориентированный отрезок

Листинг 1. Algorithm BoundingRectangle (pa,pb) ® (p1, p2) ВхоД: Pa = (ха'Уа)' Pb = (ХЬ'УЬ)

Выход: ограничивающий прямоугольник для отрезка [pa,pb], заданный парой вершин (p1,p2), где

p! = (x, yi) - левый нижний угол прямоугольника; p2 = (%2, y2) - правый верхний угол прямоугольника;

1 xx — min (xa,xb)

2 У1 — min (ya,yb )

iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.

3 x2 — max (xa,xb)

4 y2 — max (ya,yb )

5 Вернуть в качестве результата p1 = (x1 ,y1) и p2 = (x2 ,y2)

Листинг 2. Algorithm Rectangleslntersect (pa,pb,pc,pd) ® Boolean

Вход: pa = (xa' УаX pb = (Ч'Уь )' pc = (xc^c)' pd = (xd>yd)

pa - левый нижний угол первого прямоугольника; pb - правый верхний угол первого прямоугольника; pc - левый нижний угол второго прямоугольника; pd - правый верхний угол второго прямоугольника Выход: True, если прямоугольники пересекаются, иначе False

if (xb > xc) and (xd > xa) and (Уь > yc) and (yd > ya) then Вернуть в качестве результата True else Вернуть в качестве результата False

а)

Xd

Xb

6)

Xb

Xd

в)

Xd Xb

г) « л »-' ?

1 1 ! w 1 1 ! к.

Xb Xd

д)

Xd Xa

"f e)

Xb

Xb Xc

-9

i

Xd

Рис. 9. В вариантах а)-г) справедливо (xb > xc) and (xd > xa), в варианте д) - (xb > xc) and (xd < xa), в варианте e) - (xb < xc) and (xd > xa)

[Р1, Р2 ], или на этой прямой, можно, анализируя знак ориентированной площади

5(Р1,Р2,4) = 1(х - х2)(уч -У1) - (У2 -У1)(хч - х1) треугольника А р1 р2д (или, что то же, век-

торного произведения [ р1 р2 ,р14], см. [4] и приложение в [3]). На рис. 10 рассмотрены различные варианты расположения точки относительно отрезка.

Введем вспомогательный алгоритм вычисления ориентированной площади (см. листинг 3).

На рис. 11 представлены основные варианты расположения отрезков и их характеристики, определяющие факт пересечения отрезков.

На рис. 12 представлены некоторые из граничных случаев (остальные легко дополнить), когда хотя бы один из концов одного отрезка лежит на прямой, содержащей другой отрезок, и, следовательно, хотя бы одна из ориентированных площадей равна нулю. Как показывают, например, варианты а) и б), решение о пересечении отрезков нельзя принять только на основе анализа ориенти-

j \ ¡К

У"

' q

q

1. 5(р1 ,р2,4) > 0, точка 4 - слева от [р1 ,р2], А р1р24 ориентирован (обходится) против часовой стрелки;

2. 5(р1 ,р2,4') < 0, точка д" - справа от [р1 ,р2], А р1 р2д" ориентирован (обходится) по часовой стрелке;

3. 5(р1 ,р2,4"') = 0, точка 4" - на прямой, содержащей отрезок [р1 ,р2], А р1 р24" вырожден, точки р1 ,р2,4" - коллинеарные.

Рис. 10. Различные варианты расположения точки ц относительно отрезка [р1 ,р2]

X

X

X

X

X

X

a

c

a

a

c

c

X

X

X

X

a

a

c

c

Листинг 3. Algorithm Area (pa,pb,pc) ® 2S(pa,pb,pc)

Вход: pa = (ха'Уа)' pb = (ХЬ'УЬ)' pc = (хсУс)

Выход: удвоенная ориентированная площадь треугольника D papbpc 1 Вернуть в качестве результата (xa - xb)(yc - ya) - (yb - ya)(xc - xa)

{если результат > 0, то точкаpc лежит слева от ориентированного отрезка [pa, pb], если результат < 0, то точка pc лежит справа от ориентированного отрезка [pa, pb ], если результат = 0, то точка pc лежит на прямой, содержащей отрезок [pa,pb ], то есть точки pa,pb,pc коллинеарные}

Рис. 11. Анализ пересечения отрезков [ ра,рь ] и [ рс,рЛ ]: а) отрезки пересекаются, и £(ра,рь,рс) и £(ра,рь,рл) имеют разные знаки; б) отрезки не пересекаются, и £(ра,рь,рс) и £(ра,рь,рл) имеют одинаковые знаки

рованных площадей. Отметим, что в нашем подходе вариант г) не может появиться на втором этапе, так как ограничивающие прямоугольники здесь не пересекаются.

Итак, граничные случаи требуют дополнительного анализа, который может быть проведен с использованием следующего алгоритма (см. листинг 4).

а) б)

S(Pc, Pd , Pa ) = 0 S(Pc, Pd , Pb ) = 0

S(Pc >Pd, Pb ) * 0 S(Pc,Pd, Pa ) * 0

РЬ ^ г) Ра Г—Г"

Ра !.....'"'^Г ±.....' РЬ

: г------------г

Та Д____________;

' Рс " Рс

Б(рс, Ра, Ра) = 0, Я (Рс, Ра, Ра) = 0,

Б(Рс , Ра, РЬ) = 0 Я (Рс, Ра, Рь) = 0

Рис. 12. Граничные случаи, когда ориентированная площадь равна нулю ИНФОРМАТИКА

Листинг 4. Algorithm Between (pa,pb,pc) ® Boolean Вход: pa = (xa^a)' pb = (хЬ'Уь)' pc = (xXc ^c)

Предусловие: точка pc лежит на прямой, содержащей отрезок [pa,pb ] Выход: True, если точка pc является точкой ориентированного отрезка [pa,pb ], иначе False

if min (Xa, xb ) < xc < max (Xa, xb ) and min(ya,yb ) < yc < max(xa,xb )

then Вернуть в качестве результата True else Вернуть в качестве результата False

Подытожим наши соображения в алгоритме ЗеомемтзШтекзест (листинг 5).

В тех случаях, когда кроме факта пересечения пары отрезков требуется определить точку их пересечения, алгоритм Зеомеш^Штеизест следует дополнить. Рассмотрим основные необходимые для этого соотношения, оставляя читателю модификацию алгоритма SegmentsIntersect в качестве упражнения.

Для представления отрезков [ ра,рь] и [ рс,ра ], заданных концевыми точками, удобно использовать параметрические уравнения [4]. Например, все точки отрезка [ ра,рь ] описываются следующим уравнением:

раЬ (0 = Га + (РЬ - ра X где вещественный параметр г е [0,1]. Очевидно раЬ(0) = ра и раЬ(1) = рЬ , а внут-

Листинг 5. Algorithm Segmentslntersect (pa,pb,pc,pd) ® Boolean

Вход: pa = (xa,ya), pb = (xb,yb) - концы ориентированного отрезка [pa,pb],

pc = (xc,yc), pb = (xb,yb) - концы ориентированного отрезка [pc,pd ],

Выход: True, если отрезки пересекаются, иначе False

1 (p1 ,p2) — BoundingRectangle (pa,pb)

2 (p3 ,p4) — BoundingRectangle (pc,pd)

3 if not RectanglesIntersect (p1 ,p2,p3,p4)

4 then Вернуть в качестве результата False

{ограничивающие прямоугольники не пересекаются}

5 else {ограничивающие прямоугольники пересекаются}

6 s1 — Area (pc,pd,pa)

7 S2 — Area (pcpd>pb)

8 S3 — Area (Pa, Pb , Pc )

iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.

9 s4 — Area (Pa, pb, Pd )

10 if ((s1 > 0 and s2 < 0) or (s1 < 0 and s2 > 0)) and

((s3 > 0 and s4 < 0) or (s3 < 0 and s4 > 0))

11 then Вернуть в качестве результата True

12 else if (s1 = 0) and Between (pc,pd,pa)

13 then Вернуть в качестве результата True

14 else if (s2 = 0) and Between (pc,pd,pb)

15 then Вернуть в качестве результата True

16 else if (s3 = 0) and Between (pa,pb,pc)

17 then Вернуть в качестве результата True

18 else if (s4 = 0) and Between (pa,pb,pd)

19 then Вернуть в качестве результата True

20 else Вернуть в качестве результата False

ренним точкам раЬ (?) отрезка [ ра,рь ] соответствуют значения параметра [ ра,рь ]. Аналогичное уравнение запишем для отрезка [ рс,Р(1 ]:

р^ (0 = рс + (р(1 - рс ^

где параметр 5 е [0,1].

Поскольку алгоритм 8ЕОМЕМТ81МТЕК8ЕСТ при определении факта пересечения пары отрезков разбирает все необходимые ситуации, то будем интересоваться точкой пересечения отрезков только тогда, когда установлено, что отрезки пересекаются и при этом не лежат на одной прямой.

Для вычисления точки пересечения запишем уравнение раЬ (?) = рсЛ (5):

ра + (рЬ - ра){ = рс + (р(1 - рс

которое определяет значения параметров ? и 5, соответствующие точке пересечения д. Покоординатная запись этого уравнения

Ха + (ХЬ - Ха = Хс + (х<1 - Хс)s, Ха + (ХЬ - Ха = Хс + (х<1 - Хс

является системой двух линейных уравнений для определения неизвестных ? и 5. Нетрудно убедиться, что решением этой системы будут

* = [(Ха - Хс)(У<1 -Ус) + (х<1 - Хс)(Ус - Уа)] / 5 = [(ХЬ - Ха)(Ус Уа) + (Ха - Хс)(Уь - Уа)] /А где D есть определитель системы

° = (Ха - ХЬ)(У<1 -Ус) + (х<1 - Хс)(Уь - Уа)' В нашем случае D Ф 0, поскольку мы заранее знаем, что отрезки пересекаются (то есть не параллельны) и заведомо не лежат на одной прямой.

Подставив вычисленное значение ? или 5 в уравнение раЬ (0 = ра + (Ръ - раили рса(0 = Рс + (ра - Рссо-ответственно, получим точку пересечения, например,

4 = ра + (Рь - ра .

Разумеется, в вырожденных случаях, рассмотренных в алгоритме 8ЕОМШТ8ЮТЕЯ8ЕСТ, а также в случае вертикаль- Рис 13

ных или горизонтальных отрезков, система уравнений для определения ? и 5, а, следовательно, и формулы вычисления значений ? или 5 могут быть при необходимости упрощены.

5. АЛГОРИТМ НАХОЖДЕНИЯ ПЕРЕСЕЧЕНИЯ ОТРЕЗКОВ

Более эффективным, чем «лобовой» алгоритм, имеющий сложность О (я2), является алгоритм, основанный на применении метода заметания плоскости. Метод подсказан геометрической природой задач. В нашем случае речь идет о плоском заметании, поскольку рассматриваются задачи на плоскости.

Опишем идею метода плоского заметания применительно к задаче нахождения всех пересечений отрезков, а затем перейдем к описанию алгоритма. Возьмем вертикальную прямую Ь, которая разбивает плоскость на левую и правую полуплоскости (см. рис. 13). Пусть каждая из этих полуплоскостей содержит концы заданных отрезков. Решение нашей задачи может быть

1................■'■■■►

Х2 Хз Х4 Хр Х5 I Хд Х6 Х7 Х8 Х9 Хю

Заметание плоскости вертикальной прямой Ь

ь

получено объединением решений для каждой из двух полуплоскостей. Если предположить, что у нас уже есть множество точек пересечения слева от Ь, то на это множество не будут влиять отрезки, лежащие справа от Ь. Заметим, что искомое пересечение может произойти только между такими двумя отрезками, чьи пересечения с некоторой вертикалью смежны.

Теперь представим себе, что вертикальная прямая движется слева направо. По ходу движения будут пройдены все вертикальные сечения и, следовательно, могут быть выявлены все пары смежных в указанном смысле отрезков, а, значит, все пересечения будут обнаружены. Можно избежать построения всего бесконечного (континуального) множества секущих, если заметить (см. рис. 13), что плоскость разбивается на вертикальные полосы, ограниченные или концами отрезков, или точками их пересечения. При этом в пределах полосы вертикальный порядок точек пересечения отрезков с прямой L постоянен. Таким образом, вместо непрерывного движения заметающей прямой L мы можем рассмотреть скачки этой прямой по границам вертикальных полос. Каждый такой скачок связан с необходимостью обновления порядка точек пересечения вертикали и поиском пересечений среди соседних (смежных) в этом порядке отрезков.

Итак, подчеркнем, что непрерывное заметание плоскости является метафорой, в

совпадение

исчезновение

появление

г2 = гх+Дг

то время как алгоритм, основанный на этой идее, будет обрабатывать конечное множество «скачков». Точки, по которым заметающая прямая «скачет», называют точками событий. В этих точках пересечение заметающей прямой с входными отрезками содержит всю полезную информацию, которая позволит продолжить поиск. В связи с этим в методе заметания используют две основные структуры данных:

1. Список точек событий - последовательность абсцисс, упорядоченных слева направо и определяемых позициями «остановок» заметающей прямой (этот список может динамически обновляться в процессе заметания).

2. Статус заметающей прямой - подходящее описание пересечения этой прямой с набором заданных отрезков. Статус заметающей прямой должен обновляться в точках событий, и представляющая статус структура данных должна выбираться, исходя из требуемых операций анализа и обновления статуса.

Можно интерпретировать движение заметающей прямой по плоскости в терминах пространства-времени следующим образом. Представим ось абсцисс как ось времени, а заметающую прямую как мгновенный «снимок» ситуации. Тогда отрезки на плоскости становятся движущимися по вертикальной прямой («пространственной» оси) точками, которые в каждом временном сечении могут быть упорядочены (см. рис. 14). Иногда пространственно-временное представление способно «подтолкнуть» интуицию в процессе разработки геометрических алгоритмов.

Алгоритм использует два упрощающих предположения: среди рассматриваемых

Рис. 14. Перемещение по вертикальной прямой точек д. (г е 1...4) пересечения отрезков х- с этой прямой за время Д? на величину Ду.. В момент времени ?2 = ?1 + Д? точка д5 появляется на заметающей прямой, точка д4 должна исчезнуть, а точки д2 и д3 сливаются в месте пересечения отрезков х2 и х3, чтобы далее продолжить свое движение, пройдя сквозь друг друга

отрезков нет вертикальных, и никакие три отрезка не имеют общих точек. При нарушении предположений потребовалась бы модификация алгоритма, не меняющая его сути, но включающая дополнительную корректную обработку указанных вырожденных ситуаций.

Определим отношение порядка на отрезках следующим образом. Рассмотрим пару непересекающихся отрезков ' и s2. Будем считать, что ' и s2 сравнимы в абсциссе Х, если существует такая вертикаль, проходящая через Х, которая пересекает оба отрезка. Введем отношение выше в х следующим образом: ' выше s2 в х (' >Х s2), если ' и s2 сравнимы в х, а точка пересечения отрезка ' с вертикалью х лежит выше точки пересечения отрезка s2 с ней же. На рис. 15 показаны следующие отношения между отрезками ', s2

s3 и s4:

S2 >и '4, ' >V S2 >у ^4'' ' >у ^4.

Заметим, что отношение > Х задает полное упорядочение, которое изменяется по мере того, как вертикаль скользит слева направо. Отрезки входят в это упорядочение и покидают его, но оно всегда остается полным. Упорядочение должно быть представлено структурой статуса заметающей прямой и может изменяться только в трех случаях:

- встретился левый конец отрезка 5 (добавление 5 к структуре данных);

- встретился правый конец отрезка 5 (удаление 5 из структуры данных, поскольку он больше не сравним с оставшимися отрезками);

- обнаружена точка пересечения отрезков ' 1 и ' 2 ( ' 1 и '2 меняются местами в структуре данных).

Заметим, что необходимое условие пересечения двух отрезков ' 1 и ' 2 состоит в том, что существует такая абсцисса Х, в которой ' 1 и ' 2 смежны в упорядочении > Х. Отсюда следует, что последовательность пересечений множества отрез-

ков с вертикалью в x (то есть отношение > х) содержит всю необходимую информацию для поиска пересечений отрезков.

Статус заметающей прямой является описанием отношения > х; значит, он представляет собой последовательность элементов (отрезков). Так как отношение > х изменяется на конечном множестве абсцисс при плоском заметании, то станет очевидно, что в структуре данных SL (Sweep Line), реализующей статус заметающей прямой, должны быть предусмотрены следующие операции:

• ВСТАВИТЬ^, SL) - вставить отрезок s в полное упорядочение, представленное SL;

• УДАЛИТЬ^, SL) - удалить отрезок s из SL;

• НАД^, SL) - найти имя отрезка, расположенного непосредственно над s в SL;

• ПОД^, SL) - найти имя отрезка, расположенного непосредственно под s в SL.

Подобная структура данных известна как словарь [1, 5], а все вышеописанные операции можно реализовать за время, логарифмически связанное с его размером, например, с помощью подходящего типа бинарных деревьев поиска. На практике использование прошитого словаря (с прямым употреблением указателей, если адрес s известен) позволяет реализовать функции НАД^) и ПОД^) за константное время.

U V

Рис. 15. Отношение порядка между отрезками

Х1 Х^ Х3 Х4 Х5 Хб Х7 Х%

Рис. 16. Порождение нового события х7 при обработке события х1

Для регистрации всех пересечений в списке точек событий нужно уметь поддерживать отношение > Х в течение всего процесса заметания плоскости. Как указано ранее, упорядочение > Х изменяется только в некоторых абсциссах, которые являются концами отрезков или точками их пересечения. В то время как все концы отрезков заданы заранее, точка пересечения, найденная плоским заметанием, динамически порождает событие, которое, вообще говоря, должно запоминаться и обрабатываться алгоритмом в нужный момент. Заметим, что в действительности, возможно, придется обработать несколько других событий за время, прошедшее с момента обнаружения какой-нибудь точки пересечения до момента ее обработки.

На рис. 16 дан пример подобной ситуации: точка пересечения р обнаружена в момент х1 (когда отрезки ^ и s2 стали смежными); однако необходимо обработать абсциссы х2, х3, х4 и х6 перед обработкой соответствующего р события х7. Более того, при обработке события х3 возникнет точка пересечения д, и связанное с д событие х3 должно обрабатываться раньше событий х6 и х7. Отметим также, что после обработки события х3 отрезки ^ и s2 перестанут быть смежными, и вновь станут таковыми после обработки события х5. Тогда пересечение

отрезков и s2 в точке р будет обнаружено повторно, но его включение в список точек событий уже не потребуется.

Итак, для отчета обо всех пересечениях структура данных Q, создаваемая для работы со списком точек событий, должна поддерживать следующие операции (в Q хранится полное упорядочение точек событий):

• МШ^) - определить наименьший элемент в Q и удалить его;

• ВСТАВИТЬ(х, Q) - вставить абсциссу х в полное упорядочение, хранимое в Q;

• ПРИНАДЛЕЖИТ^, Q) - узнать принадлежит ли абсцисса х списку точек событий Q.

Указанная структура данных представляет собой очередь с приоритетом, и, как хорошо известно [5], при соответствующей реализации она может поддерживать все выше описанные операции за время, логарифмически связанное с ее размером.

Теперь можно описать алгоритм: при заметании плоскости вертикалью в каждой точке события структура данных БЬ корректируется и все пары отрезков, которые становятся смежными при этой корректировке, проверяются на пересечение. Если какое-нибудь пересечение обнаружено впервые, о нем дается отчет, и его абсцисса вставляется в список точек событий Q. Более формально приведенные рассуждения выражены в алгоритме ЛЬЬ-БЕОМЕМТ-ШТЕИЗЕСТ (листинг 6). Отметим, что в алгоритме используется локальный объект (рабочий параметр) - очередь А для временного (до занесения в очередь событий) хранения обнаруженных пересечений. При записи алгоритма на псевдокоде мы не будем детализировать тип операции пересечения пары отрезков, считая, что читатель при необходимости сделает это самостоятельно на основе изложенного в разделе 4 материала.

Корректность алгоритма ЛЬЬ-БЕОМЕМТ-ШТЕИЗЕСТ основана на том, что в процессе его работы не будет пропущено ни одного из пересечений, поскольку могут пересечься только смежные отрезки, причем все смежные пары корректно проверяются, по крайней мере, однажды. Более того, каждое пересечение регистрируется ровно один

Листинг 6. Algorithm All-Segment-Intersect (S) ® W

Вход: множество S отрезков {s1 ,s2.....sn}, заданных своими концами s = [pa,pb ]

Выход: W - последовательность пар пересекающихся отрезков (s, s')

1 Упорядочить 2n концов отрезков лексикографически по x и y и поместить их

в приоритетную очередь Q

2 A — 0

3 while Q Ф 0 do

4 p — MIN(Q)

5 if (p - левый конец) then

6 s — отрезок, концом которого служит p

7 ВСТАВИТЬ^, SL)

8 S — НАД^, SL)

9 s2 — ПОД^, SL)

10 if (sl пересекает s) then A — A u ( s1, s)

11 if (s2 пересекает s) then A — A u (s2, s)

12 else if (p - правый конец) then

13 s — отрезок, концом которого служит p

14 S — НАД^, SL)

15 s2 — ПОД^, SL)

16 if (s пересекает s2 справа от p) then A — A u (s, s2)

17 УДАЛИТЬ^, SL)

18 else {p - точка пересечения}

iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.

19 (s,s2) — отрезки, пересекающиеся в p {причем s = НАД(s2) слева от p}

20 s3 — НАД( s, SL)

21 s4 — ПОД( s2, SL)

22 if (s3 пересекает s2 справа от p) then A — A u (s3, s2)

23 if (пересекает s4 справа от p) then A — A u (^, s4)

24 поменять местами s и s2 в SL

25 end-if

end-if

{обнаруженные пересечения следует занести в очередь событий Q}

26 while A Ф 0 do

27 (s, s') — A

28 x — общая абсцисса s и s'

29 if not ПРИНАДЛЕЖИТ^, Q) then

30 Добавить (s, s') в выходную последовательность W

31 ВСТАВИТЬ(х, Q)

32 end-if

33 end-do

34 end-do

раз, поскольку, когда его абсцисса вставляется в Q, проверка в строке 29 предупреждает нежелательные повторы.

Оценим сложность алгоритма. Заметим, что операция строки 1 (начальная сортировка) выполняется за время O (n log n). Блоки 6-11, 13-17 и 19-24 выполняются каждый за время O (log n) , поскольку каждая операция на структуре данных SL укла-

дывается в такую временную оценку в худшем случае, а проверка попарного пересечения требует константного времени. Для каждого события, то есть для каждого исполнения главного цикла while (строка 3), эти три блока являются взаимоисключающими. Если через k обозначить число пересечений, встреченных алгоритмом, то главный цикл while выполняется ровно

I S3 I I I

IS4

S5

S6

S7

Si

S2

2n + k раз. На каждом шаге цикла обнаруживается и заносится в рабочую очередь A не более двух пересечений. Заметим, что какое-нибудь одно пересечение можно повторно обнаруживать (на разных шагах цикла) много раз (см. рис. 17).

Однако, если соотнести каждую пересекающуюся пару с тем выполнением главного цикла while, на котором она обнаружена, то станет ясно, что общее число обнаруженных пересечений равно O (n + k). Поэтому строка 29 (проверка перед переносом пересечения из рабочей очереди A в очередь событий Q) выполняется O (n + k) раз, а каждое выполнение требует O(log(n + k)) = O(log n) времени, посколь-

n(n — 1) 2 ку k < -2- = O(n ). Следовательно,

общая оценка времени главного цикла while, равна O((n + k)log n) , что, очевидно, превосходит оценку шага начальной сортиров-

Si '

S2

S3

S4

S5

S6

Рис. 17. Точка пересечения р отрезков ^ и х2 будет повторно обнаруживаться при обработке событий, связанных с правыми концами отрезков

^3' s4' s5' 36' S7'

то есть всякий раз, когда отрезки ^ и х2 вновь становятся смежными в статусе заметающей прямой

ки. Отсюда имеем, что на множестве из п отрезков можно обнаружить к пересечений за время 0((п + к)^ п). В итоге можно сформулировать следующее утверждение.

Утверждение 1. На множестве из п отрезков можно решить Задачу 2 (ВПО) и найти все к пересечений за время 0((п + к)^ п).

Алгоритм ЛЬЬ-ЗЕОМЕМТ-ШТЕИЗЕСТ значительно лучше, чем «лобовой» метод, если число пересечений достаточно мало, например, к = 0(п). Однако при к = 0(п2) (мак-

симальное значение k есть

n(n — 1)

см. рис.

Рис. 18. Пример пересечения

шести отрезков {,у;}6

в 15 точках. В общем случае

п отрезков дадут в аналогичной

п(п — 1)

- пересечений

18) время работы алгоритма составит O(n2log n) , что хуже, чем у «лобового» алгоритма. Дело в том, что алгоритм All-Segment-Intersect не достигает нижней границы. В действительности можно надеяться на получение алгоритма сложности O(k + n log n), поскольку W (n log n) есть нижняя оценка, полученная по задаче ПППО, а время формирования отчета о пересечениях есть O(k). Не вдаваясь в подробности сюжета о разработке оптимального алгоритма сложности O(k + n log n) [1], отметим, что такой алгоритм существует (см., например, [6]), но его описание выходит за рамки нашего изложения.

В том случае, когда нет необходимости находить все пересечения, а речь идет лишь о проверке наличия пересечений (задача 1 - ПППО), применение схемы с заметанием значительно упрощается. Главное отличие связано со структурой данных для списка точек событий. Теперь не требуется обработка событий, связанных с пересечениями, так как ал-

Р

горитм закончится при первом же обнаружении пересечения. Поэтому список событий представляется упорядоченным массивом, содержащим 2n исходных концевых точек. Соответствующую упрощенную версию алгоритма, работающего за время O(n log n), можно найти в [1] или [5]. Отсюда следует следующее утверждение.

Утверждение 2. Факт пересечения какой-либо пары из n отрезков на плоскости можно установить за оптимальное время Q (n log n).

Из утверждения 2 дополнительно вытекает

Следствие. За время O(n log n) в худшем случае решаются следующие задачи:

Задача 3. ПРОВЕРКА ПЕРЕСЕЧЕНИЯ МНОГОУГОЛЬНИКОВ (ППМ).

Задача 4. ТЕСТ ПРОСТОТЫ МНОГОУГОЛЬНИКА (ТПМ).

6. ЗАКЛЮЧЕНИЕ

Примененный в задаче пересечения отрезков метод заметания является эффективным средством решения многих геометрических задач. В качестве примера перечислим следующие задачи:

- геометрический поиск: метод полос, метод цепей (предобработка) [1];

- разбиение простого многоугольника на монотонные многоугольники [1];

- пересечение, объединение и другие характеристики множества прямоугольников [1];

- построение диаграммы Вороного и триангуляции Делоне

[7]. . _- ■

Литература

1. Препарата Ф., Шеймос М. Вычислительная геометрия: Введение. М.: Мир, 1989. 478 с.

2. Ивановский С.А., Преображенский А. С., Симончик С.К. Алгоритмы вычислительной геометрии. Выпуклые оболочки: связь с задачей сортировки и оптимальные алгоритмы // Компьютерные инструменты в образовании, 2007, №2. С. 6-18.

3. Ивановский С.А., Преображенский А.С., Симончик С.К. Алгоритмы вычислительной геометрии. Выпуклые оболочки: простые алгоритмы // Компьютерные инструменты в образовании, 2007, №1. С. 4-19.

4. Ильин В. А., Позняк Э. Г. Аналитическая геометрия. М.: ФИЗМАТЛИТ, 2002. 240 с.

5. Кормен Т., Лейзерсон Ч., Ривест Р. Алгоритмы: построение и анализ. М.: МЦМНО, 2000. 960 с.

6. Balaban I.J. An Optimal Algorithm for Finding Segment Intersections, Proc. 11-th Ann. ACM Sympos. Comp. Geom., 211-219, 1995.

7. de Berg M., van Kreveld M., Overmars M., Schwarzkopf O. Computational Geometry: Algorithms and Applications. (Second edition). Springer-Verlag, Heidelberg, 2000

Ивановский Сергей Алексеевич, кандидат технических наук, доцент кафедры Математического обеспечения и применения ЭВМ СПбГЭТУ «ЛЭТИ»,

Симончик Сергей Константинович, аспирант СПбГЭТУ «ЛЭТИ» магистр прикладной математики и информатики.

Наши авторы, 2007 Our authors, 2007

i Надоели баннеры? Вы всегда можете отключить рекламу.