Зберігання шестигранної сітки


10

Я створював невелику рамку для шістнадцяткової сітки для Unity3D і прийшов до наступної дилеми. Це моя система координат (взята звідси ):

введіть тут опис зображення

Це все працює дуже добре, за винятком того, що я не маю уявлення, як його зберігати. Спочатку я мав намір зберігати це у двовимірному масиві та використовувати зображення для створення моїх карт.

Одна з проблем полягала в тому, що вона мала негативні значення (це легко було виправлено шляхом трохи зміщення координат).

Однак, завдяки цій системі координат, таке зображення чи растрова карта повинні мати ромбовидну форму, а оскільки ці структури мають квадратну форму, це може спричинити багато головних болів, навіть якщо я щось зламаю разом. Чи є щось, що я пропускаю, що могло б це виправити? Я пригадую, як на форумах єдності бачив повідомлення на форумі щодо цього, але я більше не можу знайти посилання.

Чи є написання набору перекладачів координат найкращим рішенням тут?

Якщо ви думаєте, що це буде корисно, я можу розмістити код та зображення своєї проблеми.


1
Ви не можете просто зберегти зображення PNG, прозорі навколо шестикутників?
Маркус фон Броаді

Моя основна проблема із збереженням на png та масивах - це кількість "пробілів", які вони повинні містити, щоб зберегти цю систему координат недоторканою.
PeeC

1
Якщо "пробіл" означає прозорі пікселі, то чому його кількість є проблемою?
Маркус фон Броаді

Це дуже вдалий момент. Більшість форматів зображень не витрачають стільки пам’яті на зберігання повторних шаблонів. Але все - таки, це трохи дратує мене , що зберігати цю карту , я використовую це багато пам'яті (сірі пікселі порожнього простору, інші кольорами є дійсними координатами шестигранною).
PeeC

1
О, ви зберігаєте дані сітки, а не зображення плитки! Чому ви просто не збережіть ваші структури даних (сітку) у двійковий файл або не кодуєте їх, наприклад, JSON та збережіть у текстовому файлі? Я не знаю можливостей Єдності. Також ви можете підтвердити це, але я вважаю, що область такого ж кольору оптимізована (слабко стиснута) у форматі PNG.
Маркус фон Броаді

Відповіді:


9

Координати паралелограма, якими ви користуєтеся, простіше працювати, але вони мають дивний характер для прямокутних карт. Один із підходів - зберігати його з координатами зміщення, але фактично використовувати координати паралелограма в логіці гри.

Спостереження: у кожному рядку карти дані сітки є суміжними. Весь витрачений простір знаходиться зліва та справа.

Рішення: у цьому рядку зберігайте дані, починаючи з крайнього лівого стовпця, замість стовпця, позначеного 0. Обчисліть перший стовпець прямокутної карти у вашій системі координат , а потім відніміть його з координати стовпчика, щоб визначити, куди в масиві він йде. Це працює і для негативних координат стовпців.

Виконайте перетворення в геттері та сетері для карти, таким чином:

inline function get(q, r) {
    first_column_in_this_row = -floor(q/2);
    return array[r][q - first_column_in_this_row];
}

Вам доведеться змінити це, щоб працювати з вибором координат та карти (зверніть увагу на одну різницю). У деяких макетах ви хочете змістити стовпці рядком, а не навпаки.

Ви можете використовувати той самий трюк, щоб робити карти інших фігур; це не обмежується прямокутниками.

Якщо ви використовуєте C або C ++, ви можете використовувати арифметику вказівника, щоб зробити це швидше. Замість того, щоб зберігати масив покажчиків до масивів, зберігайте масив покажчиків, на який було скориговано first_column_in_row. (Це може бути не портативно)


Наскільки я можу сказати, це працює, проте математика була дуже дивною. Після того, як випробував кілька рівнянь, які мали сенс у моїй голові, я зупинився yIndex = y-((x%2==0)?(x/2-x):(-x/2)-1)після деяких спроб та помилок. Не маю уявлення, як це працює важко.
PeeC

Зробіть це yIndex = y-((x%2==0)?(-x/2):(-x/2)-1). x / 2 - це все btw на основі цілого числа, тому не потрібно підлоги.
PeeC

6

Особисто я віддаю перевагу простоті над збереженням пам’яті. Не оптимізуйте, поки не знадобиться!

Якщо ви все ще намагаєтесь зберегти кілька байт, ось як це зробити:

введіть тут опис зображення

  1. Розріжте паралелограм навпіл, щоб утворилися два правильні трикутники
  2. Переставіть два трикутники, щоб утворився прямокутник.
  3. (Зауважте, я додав смужку зеленого буфера, щоб математика гарно виходила.)

Код Python для відображення координат прямокутника на координати паралелограма та назад:

# Height of rectangle
H = 15

def r2p(x, y):
"rectangle to parallelogram"
if y < -x/2 + H:
    y = y + H
return (x - 1, y)

def p2r(x,y):
"parallelogram to rectangle"
if y >= H:
    y = y - H
return (x + 1, y)

2
Ви також можете просто перемістити пікселі вертикально вниз - на зображенні, яке було бoffsetY = Math.floor ( (x+1)/2 )
Маркус фон Броаді

1

Не потрібно спотворювати свою карту, оскільки перетворення між прямокутними та "канонічними" координатами відбувається швидко та легко. Ось посилання на вступ про те, як це зробити:

Перетворення між шестигранними прямокутними та канонічними координатами

Ця методика поєднує ліниву оцінку з кешуванням обчислених конверсій.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.