Эффективный алгоритм, чтобы вернуть все прямоугольники на поверхности - PullRequest
3 голосов
/ 13 марта 2012

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

У меня уже есть функция, которая возвращает прямоугольник для заданной координаты, если он существует

GetRectangle( int row, int col )

Вот как я бы назвал полученный код.

foreach( var rect in GetRectangles( row, col, rowCount, colCount ) ) {
   //..  my processing code here
}

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

Вам известен такой алгоритм?

ОБНОВЛЕНИЕ: Поверхность не обязательно покрыта прямоугольниками, но это может быть для некоторых особых случаев.Итак, функция GetRectangle( int row, int col ) может возвращать ноль.

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

Спасибо

1 Ответ

3 голосов
/ 13 марта 2012

Для получения наилучших результатов организуйте свою коллекцию прямоугольников в пространственную структуру поиска .В этом случае звучит так, как будто R-дерево будет хорошей ставкой.Но если вы не можете этого сделать, и GetRectangle - это все, что у вас есть, то вот что я буду делать:

План состоит в том, чтобы вести список целых чисел x j для 0 ≤ j <<code>rowCount, где x j это самая левая точка в строке j , для которой я еще не нашел прямоугольник, закрывающий ее.

  1. Начните с инициализации x j : = 0 для всех j .

  2. Если x j = colCount для всех j , все готово.Стоп.

  3. Пусть J = мин ( j | x j = мин ( x i )).Тогда x J - самая верхняя левая точка, которую я еще не нашел прямоугольника, который ее покрывает.

  4. Звоните GetRectangle ( x J , J ).Если это не возвращает прямоугольник, то точка не раскрыта.Установите x J : = x J + 1 и перейдите к шагу 2.

  5. В противном случае у нас есть прямоугольник с верхним левым углом в ( x J , J).Назовите его ширину ш и высоту ч .Для J j <<em> J + ч , установите x j : = x j + w .Переходите к шагу 2.

Вот пример выполнения этого алгоритма.Список x j показан номерами слева, а крайний левый край выделен жирным шрифтом.Оранжевый прямоугольник - это тот, который обнаружен на этом шаге алгоритма.

The algorithm finds seven rectangles in seven steps

Для эффективного обнаружения минимума на шаге 3 может потребоваться сохранить список x j в куче .

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