Якщо припустити, що ваші спрайти займають набори плиток, які є прямокутниками (якщо вони займають довільні множини, то ви взагалі не можете правильно намалювати), проблема полягає в тому, що між елементами немає загального відношення порядку, тому ви не можете сортувати вони використовують сортування, яке призведе до порівняння O (nlogn).
Зверніть увагу, що для будь-яких двох об'єктів A і B перед B (A <- B) потрібно намалювати A, B перед A (B <- A) або їх можна намалювати в будь-якому порядку. Вони утворюють частковий порядок. Якщо ви намалюєте собі кілька прикладів з 3 перекриваються об’єктами, ви можете помітити, що навіть якщо 1-й і 3-й об'єкти можуть не перетинатися, таким чином, не маючи прямої залежності, їх порядок малювання залежить від 2-го об'єкта, який знаходиться між ними - залежно від того, як розмістивши його, ви отримаєте різні замовлення на малювання. Підсумок - традиційні сорти тут не працюють.
Одним із варіантів є використання порівняння (згадане Дані) та порівняння кожного об'єкта один з одним для визначення їх залежностей та формування графіка залежності (який буде 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