Przechowywanie siatki heksadecymalnej

10

Tworzyłem małą strukturę heksadecymalną dla Unity3D i doszedłem do następującego dylematu. To jest mój układ współrzędnych (wzięty stąd ):

wprowadź opis zdjęcia tutaj

Wszystko działa całkiem ładnie, z wyjątkiem tego, że nie mam pojęcia, jak go przechowywać. Pierwotnie zamierzałem przechowywać to w tablicy 2D i wykorzystywać obrazy do generowania moich map.

Jednym z problemów było to, że miał ujemne wartości (można to łatwo naprawić przez nieco przesunięcie współrzędnych).

Jednak ze względu na ten układ współrzędnych taki obraz lub bitmapa musiałby mieć kształt rombu - a ponieważ te struktury mają kształt kwadratu, spowodowałoby to wiele bólów głowy, nawet jeśli zhakuję coś razem. Czy brakuje mi czegoś, co mogłoby to naprawić? Pamiętam, że widziałem post na forum na ten temat na forach jedności, ale nie mogę już znaleźć linku.

Czy pisanie zestawu tłumaczy współrzędnych jest tutaj najlepszym rozwiązaniem?

Jeśli uważacie, że byłoby to pomocne, mogę wysłać kod i zdjęcia mojego problemu.

PeeC
źródło
1
Czy nie można po prostu zapisać obrazów PNG, które są przezroczyste wokół sześciokątów?
Markus von Broady
Moim głównym problemem związanym z zapisywaniem plików PNG i tablic jest ilość „białych znaków”, które musieliby zawierać, aby utrzymać ten układ współrzędnych w stanie nienaruszonym.
PeeC
1
Jeśli „biała spacja” oznacza przezroczyste piksele, to dlaczego jest z tym problem?
Markus von Broady
To bardzo dobra uwaga. Większość formatów obrazów nie marnuje tyle pamięci na przechowywanie powtarzających się wzorów. Ale nadal, to lekko irytuje mnie, że aby zapisać tę mapę używam tego dużo pamięci (szare piksele są puste miejsca, inne kolory są prawidłowe współrzędne hex).
PeeC
1
Och, przechowujesz dane siatki, a nie kafelki! Dlaczego po prostu nie zapiszesz swoich struktur danych (siatki) do pliku binarnego lub nie zakodujesz go za pomocą np. JSON i nie zapiszesz w pliku tekstowym? Jednak nie znam możliwości Unity. Być może chcesz to potwierdzić, ale uważam, że obszar tego samego koloru jest zoptymalizowany (luźno skompresowany) w formacie PNG.
Markus von Broady

Odpowiedzi:

9

Współrzędne równoległoboku, z których korzystasz, są łatwiejsze do pracy, ale mają tę wadę, że są dziwne w przypadku map prostokątnych. Jednym z podejść jest przechowywanie go ze współrzędnymi przesunięcia, ale w rzeczywistości używa się współrzędnych równoległoboku w logice gry.

Obserwacja: w każdym rzędzie mapy dane siatki są ciągłe. Cała zmarnowana przestrzeń znajduje się po lewej i prawej stronie.

Rozwiązanie: w tym wierszu przechowuj dane, zaczynając od lewej kolumny zamiast kolumny oznaczonej 0. Oblicz pierwszą kolumnę mapy prostokątnej w układzie współrzędnych , a następnie odejmij ją od współrzędnej kolumny, aby określić, gdzie w macierzy idzie. Działa to również w przypadku ujemnych współrzędnych kolumny.

Wykonaj konwersję w narzędziu pobierającym i ustawiającym dla mapy za pomocą czegoś takiego:

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

Musisz to zmodyfikować, aby działało z wyborem współrzędnych i mapy (zwróć uwagę na jedną różnicę). W niektórych układach będziesz chciał przesunąć kolumny o rząd zamiast na odwrót.

Możesz użyć tej samej sztuczki, aby tworzyć mapy innych kształtów; nie ogranicza się to do prostokątów.

Jeśli używasz C lub C ++, możesz użyć arytmetyki wskaźnika, aby przyspieszyć. Zamiast przechowywać tablicę wskaźników w tablicach, przechowuj tablicę wskaźników, które zostały dostosowane first_column_in_row. (To może nie być przenośne)

amitp
źródło
Działa to, o ile wiem, jednak matematyka była naprawdę dziwna. Po wypróbowaniu kilku równań, które miały sens w mojej głowie, postanowiłem yIndex = y-((x%2==0)?(x/2-x):(-x/2)-1)po kilku próbach i błędach. Nie mam pojęcia, jak to działa.
PeeC
Zrób to yIndex = y-((x%2==0)?(-x/2):(-x/2)-1). x / 2 to btw oparte na liczbach całkowitych, więc nie ma potrzeby podłogowania.
PeeC
6

Osobiście wolałbym prostotę niż oszczędzanie pamięci. Nie optymalizuj, dopóki nie będzie potrzebny!

Jeśli nadal chcesz zaoszczędzić kilka bajtów, możesz to zrobić w następujący sposób:

wprowadź opis zdjęcia tutaj

  1. Przekrój równoległobok na pół, aby utworzyć dwa prawe trójkąty
  2. Zmień układ dwóch trójkątów, aby utworzyć prostokąt.
  3. (Uwaga: dodałem zielony pasek buforowy, aby matematyka działała poprawnie).

Kod Python do mapowania współrzędnych prostokątnych na współrzędne równoległoboku i odwrotnie:

# 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)
Leftium
źródło
2
możesz także przesunąć piksele pionowo w dół - na obrazie, który byłbyoffsetY = Math.floor ( (x+1)/2 )
Markus von Broady,