Вот краткое описание алгоритма пересечения, представленное в ссылке DuduAlul .
Решение требует использования дерева поиска, способного выполнять диапазонные запросы. Запрос диапазона запрашивает все элементы со значениями между K1 и K2, и это должна быть операция O (R + log N), где N - общее количество элементов дерева, а R - количество результатов.
Алгоритм использует подход развертки:
1) Сортировать все левый и правый края прямоугольника в соответствии с их значением X в список L.
2) Создать новое дерево поиска пустого диапазона T, для Y упорядочения прямоугольных вершин / оснований
3) Создать новый пустой результирующий набор RS уникальных пар прямоугольников
4) Траверс L в порядке возрастания. Для всех V в L:
Если V.isRightEdge ()
T.remove (V.rectangle.top)
T.remove (V.rectangle.bottom)
остальное
Для всех U в T.getRange (V.rectangle.top, V.rectangle.bottom)
RS.add ()
T.add (V.rectangle.top)
T.add (V.rectangle.bottom)
5) возврат RS
Сложность по времени составляет O (R + N log N), где R - фактическое количество пересечений.
- РЕДАКТИРОВАТЬ -
Я только что выяснил, что решение не полностью корректно - тест пересечения в дереве T пропускает некоторые случаи. Дерево должно поддерживать интервалы Y, а не значения Y, и в идеале оно должно быть Interval Tree .