На жаль, я все ще не такий сильний у розумінні алгоритму Sweep Line . Усі статті та підручники з цієї теми вже прочитані, однак до розуміння ще далеко. Просто для того, щоб було зрозуміліше, я намагаюся вирішити якомога більше вправ. Але, дійсно цікаві та важливі завдання все ще залишаються для мене викликом.
Наступну вправу я знайшов у конспектах лекцій про перетин сегмента лінії всемогутнього Джеффа Еріксона.
Вправа 2. Охарактеризуйте та проаналізуйте алгоритм швидкої лінії, щоб визначити, чи задано кружків у площині, чи є два пересікання, за час O ( n log n ) . Кожне коло визначається його центром та його радіусом, тому вхід складається з трьох масивів X [ 1 .. n ] , Y [ 1 .. n ] та R [ 1 .. n ] . Будьте обережні, щоб правильно здійснити примітиви низького рівня.
Спробуємо полегшити складну річ. Що ми знаємо про перетин кіл? Який аналог можна знайти при перетині ліній. Дві лінії можуть перетинатися, якщо вони суміжні, яке властивість має мати два кола, щоб перетинатися? Нехай - відстань між центром кіл, r 0 та r 1 центрами кіл. Розглянемо кілька випадків:
Випадок 1: Якщо то розв’язків немає, кола відокремлюються.
Випадок 2: Якщо то рішення немає, тому що одне коло міститься в іншому.
Випадок 3: Якщо і r 0 = r 1, то кола збігаються і існує нескінченна кількість розв’язків.
Отже, схоже, що умови перехрестя готові, звичайно, це можуть бути неправильні умови. Будь ласка, виправте, якщо це так.
Алгоритм. Тепер нам потрібно знайти щось спільне між двома пересічними колами. З аналоговим переходом лінії нам потрібно мати умову вставки та видалити умову до черги подій. Скажімо, точка події - це х координата першої та останньої точок, до яких торкається вертикальна лінія розгортки. На першій точці ми вставляємо коло в статус і перевіряємо на перехрестя (3 випадки для перевірки згадуються вище) з найближчими колами, на останній точці видаляємо коло зі статусу .
Схоже, цього достатньо для алгоритму розгортки ліній. Якщо щось не так, або може бути щось таке, що слід зробити іншим, сміливо поділіться своїми думками з нами.
Додаток :
Я вставляю коло, коли вертикальна лінія розгортки торкається кола вперше, і виймаю коло зі стану, коли лінія розгортки торкається його в останній раз. Перевірку на перехрестя слід зробити для найближчого попереднього кола. Якщо ми додамо коло до статусу і вже було інше коло, яке ми додавали раніше, і воно все ще було, тому первісне коло не було «закрите», тому може бути перехрестя.
status
підтримує кола, що перетинають лінію розгортки? Припустимо, у вас зараз є 100 кіл status
, і ви обробляєте подію вставки та вставляєте 101-е коло. Скільки кіл ви порівняєте, щоб перевірити на перехрестя? Як ви вибираєте, які кола для порівняння?