К сожалению, я все еще не настолько силен в понимании алгоритма 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, то окружности совпадают и существует бесконечное число решений.
Таким образом, похоже, что условия пересечения готовы, конечно, это могут быть неправильные условия. Пожалуйста, исправьте, если это так.
Алгоритм. Теперь нам нужно найти что-то общее между двумя пересекающимися кругами. При пересечении с аналогом на линию нам нужно иметь условие вставки и удаления условия в очередь событий. Допустим, точка события - это координата x первой и последней точек, к которым касается вертикальная линия развертки. В первой точке мы вставляем кружок в статус и проверяем на пересечение (3 случая для проверки упомянуты выше) с ближайшими кружками, в последней точке мы удаляем кружок из статуса .
Похоже, этого достаточно для алгоритма стреловидности. Если что-то не так или может быть что-то, что должно быть сделано иначе, не стесняйтесь поделиться своими мыслями с нами.
Приложение :
Я вставляю круг, когда вертикальная линия развертки касается круга в первый раз, и удаляю круг из состояния, когда линия развертки касается его в последний раз. Проверка на пересечение должна быть сделана для ближайшего предыдущего круга. Если мы добавили круг к статусу, и уже был другой круг, который мы добавили ранее, и он все еще был там, следовательно, предыдущий круг не был «замкнут», поэтому может быть пересечение.
status
поддерживает круги, в настоящее время пересекающие линию развертки? Предположим, у вас есть 100 кружков status
, и вы обрабатываете событие вставки и вставляете 101-й кружок. Сколько кругов вы сравниваете, чтобы проверить на пересечение? Как вы выбираете, какие круги сравнивать?