Алгоритм нахождения ячеек сетки, содержащихся в произвольно повернутом прямоугольнике (растеризация)
Я ищу алгоритм, который может вычислить все ячейки сетки, занятые произвольным прямоугольником в 2-мерном пространстве в определенной области. Прямоугольник определяется его четырьмя угловыми координатами. На рисунке ниже я отметил два из них как красный, координаты ячеек сетки выделены черным цветом. Я ищу общий случай, который также охватывает невыровненные сетки (центр сетки!= Центр базовой системы coodinate), но преобразование между координатами ячейки <=> Система координат тривиально и уже реализовано. Все клетки являются квадратами.
Расчет выполняется тысячами в очень короткие сроки и должен быть максимально быстрым.
Что я сейчас делаю:
Прямо сейчас я вычисляю края прямоугольника (AB, BC, CD, DA) и пробую их в sampleRate = cellWidth / 4
интервалы. Чтобы найти средние клетки, я строю новые линии из AB + sampleRate * x
в CD + sampleRate * x
и снова попробовать эти строки в sampleRate
, Я помещаю все ячейки, которые я нахожу в каждой точке выборки, в HashSet для удаления дубликатов. Но я чувствую, что это невероятно неэффективно.
Я также подумал о том, чтобы собрать все ячейки в соответствующей области в буфер и создать дерево диапазонов или дерево индексов. Тогда я мог бы поставить в очередь границы прямоугольника и получить все содержащиеся в нем ячейки в O(log n+m), но я не уверен, как это реализовать, и я даже не могу найти какие-либо реализации дерева диапазонов C#.
Мои знания в компьютерной графике очень ржавые, но разве не должен быть простой геометрический подход, который работает без выборки?
1 ответ
Точки, которые вас интересуют, отмечены точкой на изображении ниже. Каждая точка представляет собой либо минимальное значение X, либо максимальное значение X для данного значения Y. Для каждого значения Y значение X легко вычисляется из уравнения для строки:
x = x 0 + (y - y 0) (x 1 - x 0) / (y 1 - y 0)
Обратите внимание, что выровненный по оси прямоугольник (где (y 1 - y 0) равен 0) должен обрабатываться как особый (но тривиальный) случай.
Также обратите внимание, что как только вы вычислили первое значение X по краю прямоугольника, остальные значения X будут равнорасположены. Интервал является обратным к наклону линии. Итак, разделение
M = (x 1 - x 0) / (y 1 - y 0)
нужно сделать только один раз, а затем многократно добавить к значению X. Например, после вычисления координаты X для точки A на изображении координата X для точки B будет B x = A x + M. И координата X для точки C будет C x = B x + M.
Если у вас есть минимальное и максимальное значения X для каждого значения Y, это просто for
цикл, чтобы получить все ячейки, которые имеют это значение Y.