Вибачте за відродження древньої нитки, але звичайні старі сітки ІМХО не використовуються досить часто для цих випадків. Є багато переваг сітки в тому, що введення / видалення комірок - бруд дешевий. Ви не повинні турбуватися із звільненням комірки, оскільки сітка не має на меті оптимізувати розріджені зображення. Я кажу, що скоротивши час для розміщення, виберіть купу елементів у застарілій кодовій базі з понад 1200 мс до 20 мс, просто замінивши квадратичне дерево сіткою. Справедливо кажучи, що квадратичне дерево було реально погано реалізовано, зберігаючи окремий динамічний масив на вузол листя для елементів.
Інший, який я вважаю надзвичайно корисним, - це те, що класичні алгоритми растризації для малювання фігур можна використовувати для пошуку в сітці. Наприклад, ви можете використовувати растерізацію ліній Брезенама для пошуку елементів, які перетинають лінію, розширення растрової лінії, щоб знайти, які клітини перетинають полігон і т. Д. Оскільки я багато працюю в обробці зображень, дуже приємно мати можливість використовувати саме те саме оптимізований код, який я використовую для нанесення пікселів на зображення, як і для виявлення перехрестя проти рухомих об'єктів у сітці.
Це означає, що для того, щоб зробити сітку ефективною, вам не потрібно більше 32 біт на одну комірку сітки. Ви повинні мати можливість зберігати мільйон комірок у розмірі менше 4 мегабайт. Кожна комірка сітки може просто індексувати перший елемент у комірці, а перший елемент у комірці може потім індексувати наступний елемент у комірці. Якщо ви зберігаєте який-небудь повнофункціональний контейнер з кожною осередком, він швидко отримує вибухонебезпечне використання та розподілення пам'яті. Натомість ви можете просто зробити:
struct Node
{
int32_t next;
...
};
struct Grid
{
vector<int32_t> cells;
vector<Node> nodes;
};
Приблизно так:
Гаразд, так до мінусів. Я до цього зізнаюся, з ухилом і перевагою сіток, але головним їх недоліком є те, що вони не рідкісні.
Доступ до певної комірки сітки з заданою координатою є постійним часом і не потребує спуску вниз по дереву, яке дешевше, але сітка щільна, не розріджена, тож ви зможете перевірити більше комірок, ніж потрібно. У ситуаціях, коли ваші дані дуже рідко розповсюджуються, сітка може зажадати перевірити ще більше, щоб визначити елементи, які перетинаються, наприклад, лінією або заповненим багатокутником, прямокутником або обмежуючим колом. Сітка повинна зберігати 32-бітну клітинку, навіть якщо вона є абсолютно порожньою, і коли ви робите запит перетину фігури, ви повинні перевірити ці порожні комірки, чи перетинають вони вашу форму.
Основна перевага квадрового дерева - це, звичайно, його здатність зберігати розрізнені дані та лише підрозділяти, скільки потрібно. Однак це важче реально реалізувати, особливо якщо у вас є речі, що рухаються навколо кожного кадру. Дерево потрібно дуже ефективно підрозділяти та звільняти дочірні вузли, інакше воно деградує в щільну сітку, витрачаючи накладні витрати на зберігання батьківських та дочірніх посилань. Це дуже доцільно реалізувати ефективне чотиривіршеве дерево, використовуючи дуже схожі методи, які я описав вище для сітки, але, як правило, це буде більш трудомістким. І якщо ви робите це так, як я роблю в сітці, це теж не обов'язково оптимально, оскільки це призведе до втрати здатності гарантувати, що всі 4 дитини вузла квадратичного дерева зберігаються безперервно.
Крім того, і квадратичне дерево, і сітка не виконують чудової роботи, якщо у вас є кілька великих елементів, які охоплюють більшу частину всієї сцени, але принаймні сітка залишається рівною і не підрозділяється на n-й ступінь у цих випадках. . Квадратне дерево повинно зберігати елементи у гілках, а не просто залишати для розумного впорядкування таких випадків, інакше воно захоче надзвичайно швидко поділитися як божевільне та погіршити якість. Існує більше таких патологічних випадків, про які вам потрібно подбати з квадратом, якщо ви хочете, щоб він обробляв найширший діапазон вмісту. Наприклад, ще один випадок, який справді може зіткнутися з квадрового дерева - це якщо у вас є вантаж супутніх елементів. У цей момент деякі люди просто вдаються до встановлення межі глибини для свого квадратичного дерева, щоб не допустити його нескінченного поділу. У сітці є заклик, що вона робить гідну роботу,
Стабільність і передбачуваність також вигідна в ігровому контексті, оскільки іноді не обов'язково потрібно найшвидше рішення для загального випадку, якщо це може час від часу призводити до гикавки частоти кадрів у рідкісних сценаріях порівняно з рішенням, яке досить швидко все- навколо, але ніколи не призводить до таких гикавок і забезпечує швидкість кадрів плавною та передбачуваною. Сітка має таку останню якість для цього.
З урахуванням сказаного, я дійсно думаю, що це залежить від програміста. З такими речами, як сітка проти квадратичного дерева або octree проти kd-tree проти BVH, я голосую за найбільш плідного розробника, який має записи про створення дуже ефективних рішень незалежно від того, яку структуру даних він / вона використовує. На мікрорівні також багато, як багатопотокова, SIMD, зручна в кеші макет пам'яті та шаблони доступу. Деякі люди можуть розглянути ці мікро, але вони не обов'язково мають мікровплив. Такі речі можуть зробити різницю в 100 разів від одного рішення до іншого. Незважаючи на це, якби мені особисто дали кілька днів і мені сказали, що мені потрібно впровадити структуру даних для швидкого прискорення виявлення зіткнення елементів, що рухаються навколо кожного кадру, я б краще за короткий час застосував сітку, ніж квадроцикл -древо.