Алгоритм решения простой (?) Проблема массива

голоса
7

Для этой скорости проблемы очень важно. Я нарисовал хорошую картинку, чтобы объяснить проблему лучше. Алгоритм должен рассчитать, если края прямоугольника продолжать в пределах холста, будет ребро пересекает другой прямоугольник?

Мы знаем:

  1. Размер холста
  2. Размер каждого прямоугольника
  3. Положение каждого прямоугольника

Чем быстрее решение, тем лучше! Я довольно застрял на этом и на самом деле не знаю, с чего начать.

альтернативный текст http://www.freeimagehosting.net/uploads/8a457f2925.gif

ура

Задан 08/07/2010 в 13:23
источник пользователем
На других языках...                            


6 ответов

голоса
2

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

Начнем с того, а затем посмотрим, как оптимизировать его. Я не уверен, как представляется ваши данные, и я не могу видеть изображение.

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

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

Ответил 08/07/2010 в 13:35
источник пользователем

голоса
6

Просто создать множество интервалов для каждого из X и оси Y. Тогда для каждого нового прямоугольника, увидеть , если есть пересекающиеся интервалы в Х или оси Y. Смотрите здесь один из способов реализации множества интервалов.

В первом примере, интервал установлен на горизонтальной оси будет { [0-8], [0-8], [9-10] }, а по вертикали:{ [0-3], [4-6], [0-4] }

Это только эскиз, я отведенный многие деталей (например, как правило, можно было бы задать интервальный набор / дерево «которое интервалы перекрываются этой», вместо «пересекается этой», но ничего не выполним).

редактировать

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

Ответил 08/07/2010 в 13:36
источник пользователем

голоса
1

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

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

  1. число все ваши прямоугольники, назначая им индивидуальные идентификаторы
  2. создать пустую бинарную дерево коллекцию (БКИ). эта коллекция должна иметь метод, чтобы вставить целое узла с информацией BTC :: вкладыша (ключ, значение)
  3. для всех прямоугольников, сделайте следующее:

foreach rect in rects do
    btc.insert(rect.top, rect.id)
    btc.insert(rect.bottom, rect.id)
  1. Теперь перебирать БТК (это даст вам порядок сортировки)

btc_item = btc.first()
do
    id = btc_item.id
    btc_item = btc.next()
    if(id != btc_item.id)
    then report_invalid_placement(id, btc_item.id)
    btc_item = btc.next()
while btc_item is valid

5,7,8 - повторите шаги 2,3,4 для rect.left и rect.right координат

Ответил 08/07/2010 в 13:49
источник пользователем

голоса
1

Мне нравится этот вопрос. Вот моя попытка попасть на него:

Если возможно: Создать многоугольник из каждого прямоугольника. Рассматривать каждое ребро в виде линии максимальной длины , которые должны быть подрезанными. Используйте алгоритм отсечения , чтобы проверить погоду или не линия пересекается с другой. Например , это одна: линия Clipping

Но имейте в виду: Если вы нашли пересечение, которое находится в положении вершины, ее действительный один.

Ответил 08/07/2010 в 14:01
источник пользователем

голоса
1

Вот идея. Вместо того чтобы создавать каждый прямоугольник (x, y, width, height), экземпляр их (x1, y1, x2, y2), или , по крайней мере, это интерпретировать эти значения , приведенные в ширину и высоту.

Таким образом, вы можете проверить , какие прямоугольники имеют аналогичный xили yзначение , и убедитесь , что соответствующий прямоугольник имеет ту же среднюю величину.


Пример:

Прямоугольники вы дали имеют следующие значения:

  • Квадрат 1: [0, 0, 8, 3]
  • Площадь 3: [0, 4, 8, 6]
  • Площадь 4: [9, 0, 10, 4]

Во- первых, мы сравниваем Square 1с Square 3(не столкновение):

  • Сравните значения х
    • [0, 8] на [0, 8] Это точно так же, так что нет кроссовера.
  • Сравните значения Y
    • [0, 4] [3, 6] Ни одно из этих чисел не похожи, так что они не является фактором

Далее мы сравним Square 3с Square 4(столкновение):

  • Сравните значения х
    • [0, 8] [9, 10] Ни одно из этих чисел не похожи, так что они не является фактором
  • Сравните значения Y
    • [4, 6] на [0, 4] Прямоугольники имеют номер 4 в общем, но 0! = 6, следовательно, происходит столкновение

По знаем , что мы знаем , что столкновение произойдет, поэтому метод закончится, но позволяет оценить Square 1и Square 4для некоторой дополнительной ясности.

  • Сравните значения х
    • [0, 8] [9, 10] Ни одно из этих чисел не похожи, так что они не является фактором
  • Сравните значения Y
    • [0, 3] на [0, 4] Прямоугольники имеют номер 0 в общем, но 3! = 4, следовательно, происходит столкновение

Дайте мне знать, если вам нужны какие-либо дополнительные подробности :)

Ответил 08/07/2010 в 14:08
источник пользователем

голоса
0

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

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

Ответил 09/07/2010 в 07:53
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more