Если предположить, что ваши спрайты занимают наборы плиток, которые являются прямоугольниками (если они занимают произвольные наборы, то в общем случае вы вообще не сможете правильно нарисовать), проблема в том, что между элементами нет отношения общего порядка, поэтому вы не можете сортировать они используют сортировку, которая приведет к O (nlogn) сравнениям.
Обратите внимание, что для любых двух объектов A и B либо A должно быть нарисовано до B (A <- B), B должно быть нарисовано до A (B <- A), либо они могут быть нарисованы в любом порядке. Они образуют частичный порядок. Если вы нарисуете несколько примеров с 3 перекрывающимися объектами, вы можете заметить, что, хотя 1-й и 3-й объекты могут не перекрываться, поэтому не имеют прямой зависимости, их порядок рисования зависит от 2-го объекта, который находится между ними - в зависимости от того, как Вы разместите его, вы получите различные заказы на рисование. Итог - традиционные сорта здесь не работают.
Одним из решений является использование сравнения (упомянутого Dani) и сравнение каждого объекта с другим объектом для определения их зависимостей и формирования графа зависимостей (который будет DAG). Затем выполните топологическую сортировку на графике, чтобы определить порядок рисования. Если не так много объектов, это может быть достаточно быстро (этоO(n^2)
).
Другое решение заключается в использовании (для балансировки - псевдо ) четырехугольное дерево и сохранить в нем прямоугольники всех объектов.
Затем выполните итерацию по всем объектам X и используйте четырехугольное дерево, чтобы проверить, есть ли какие-либо объекты Y в полосе над объектом X, который начинается с самого левого и заканчивается самым правым углом объекта X - для всех таких Y, Y < - X. Таким образом, вам все равно придется формировать график и топологически сортировать.
Но вы можете избежать этого. Вы используете список объектов Q и таблицу объектов T. Итерируете все видимые слоты от меньших к большим значениям по оси X (одна строка), переходя строка за строкой по оси Y. Если в этом слоте есть нижний угол объекта, выполните описанную выше процедуру, чтобы определить зависимости. Если объект X зависит от некоторого другого объекта Y, который частично над ним (Y <- X), и каждый такой Y уже находится в Q, добавьте X к Q. Если есть некоторый Y, которого нет в Q, добавьте X к T и обозначим Y <- X. Каждый раз, когда вы добавляете объект в Q, вы удаляете зависимости объектов, ожидающих в T. Если все зависимости удалены, объект из T перемещается в Q.
Мы предполагаем, что объектные спрайты не выглядывают из своих слотов снизу, слева или справа (только сверху, как деревья на вашей картинке). Это должно улучшить производительность для большого количества объектов. Этот подход снова будет O(n^2)
, но только в худшем случае, который включает в себя объекты странного размера и / или странные конфигурации объектов. В большинстве случаев это так O(n * logn * sqrt(n))
. Знание высоты ваших спрайтов может устранить sqrt(n)
, потому что вам не нужно проверять всю полосу выше. В зависимости от количества объектов на экране вы можете попробовать заменить дерево квадратов массивом, указывающим, какие слоты заняты (имеет смысл, если объектов много).
Наконец, не стесняйтесь проверять этот исходный код на предмет некоторых идей: https://github.com/axel22/sages/blob/master/src/gui/scala/name/brijest/sages/gui/Canvas.scala