Moja izometryczna gra 2D wykorzystuje sześciokątną mapę siatki. W odniesieniu do poniższego obrazu, w jaki sposób mogę obrócić jasnoniebieskie struktury sześciokątne o 60 stopni wokół różowych sześciokątów?
EDYTOWAĆ:
Główny hex to (0,0). Inne heksy są dziećmi, ich liczba jest ustalona. Zdefiniuję tylko jedną pozycję (w tym przypadku jej prawą) i w razie potrzeby obliczę inne kierunki (lewy dolny, prawy botom, prawy górny, lewy górny i lewy). Inne heksy są zdefiniowane jak: Package.Add (-1,0), Package.Add (-2,0) i tak dalej.
switch(Direction)
{
case DirRightDown:
if(Number.Y % 2 && Point.X % 2)
Number.X += 1;
Number.Y += Point.X + Point.Y / 2;
Number.X += Point.X / 2 - Point.Y / 1.5;
break;
}
W tym kodzie Number
jest heks główny i Point
to heks, który chcę obrócić, ale nie działa:
2d
rotation
maps
hexagonal-grid
ruzsoo
źródło
źródło
Odpowiedzi:
Jak zauważa Martin Sojka , obroty są prostsze, jeśli przekonwertujesz na inny układ współrzędnych, wykonasz obrót, a następnie przekonwertujesz z powrotem.
Używam innego układu współrzędnych niż Martin, oznaczonego etykietą
x,y,z
. W tym systemie nie ma wahań i jest przydatny w przypadku wielu algorytmów szesnastkowych. W tym systemie możesz obracać hex za0,0,0
pomocą „obracania” współrzędnych i odwracania ich znaków:x,y,z
zmienia się w-y,-z,-x
jedną stronę i-z,-x,-y
drugą stronę. Mam schemat na tej stronie .(Przykro mi z powodu x / y / z vs X / Y, ale używam x / y / z na mojej stronie i używasz X / Y w kodzie, więc w tej odpowiedzi sprawa ma znaczenie! Więc zamierzam użyć
xx,yy,zz
jako nazwy zmiennych poniżej, aby ułatwić ich rozróżnienie).Konwertuj swoje
X,Y
współrzędne nax,y,z
format:Wykonaj obrót o 60 ° w jedną lub drugą stronę:
Konwertuj z
x,y,z
powrotem naX,Y
:Na przykład, jeśli zaczniesz od (X = -2, Y = 1) i chcesz obrócić o 60 ° w prawo, przekonwertujesz:
następnie obróć o
-2,1,1
60 ° w prawo za pomocą:jak widzisz tutaj:
następnie przekonwertuj z
-1,2,-1
powrotem:Więc (X = -2, Y = 1) obraca się o 60 ° w prawo w (X = -2, Y = -1).
źródło
Najpierw zdefiniujmy nowy numer. Nie martw się, to łatwe.
Lub, mówiąc prosto: f = √3 × i , przy czym i jest jednostką urojoną . Dzięki temu obrót o 60 stopni w kierunku zgodnym z ruchem wskazówek zegara jest taki sam jak pomnożenie przez 1/2 × (1 - f ) , a obrót o 60 stopni w kierunku przeciwnym do ruchu wskazówek zegara jest taki sam jak pomnożenie przez 1/2 × (1 + f ) . Jeśli brzmi to dziwnie, pamiętaj, że mnożenie przez liczbę zespoloną jest takie samo jak obrót w płaszczyźnie 2D. Po prostu „wyciskamy” liczby zespolone w wyobrażonym kierunku nieco (o √3), aby nie mieć do czynienia z pierwiastkami kwadratowymi ... ani z liczbami całkowitymi.
Możemy również zapisać punkt (a, b) jako a + b × f .
To pozwala nam obrócić dowolny punkt na płaszczyźnie; na przykład punkt (2,0) = 2 + 0 × f zmienia się na (1, -1), a następnie na (-1, -1), (-2,0), (-1,1), ( 1,1) i wreszcie wróć do (2,0), po prostu mnożąc go.
Oczywiście potrzebujemy sposobu na przeniesienie tych punktów ze współrzędnych na te, w których wykonujemy obrót, a następnie z powrotem. W tym celu potrzebna jest jeszcze jedna informacja: jeśli punkt, który wykonujemy, obraca się wokół „lewej” lub „prawej” linii pionowej. Dla uproszczenia deklarujemy, że ma on wartość „wahania” w 0, jeśli znajduje się po jego lewej stronie (jak środek obrotu [0,0] na dwóch dolnych obrazach), i 1, jeśli znajduje się po prawej stronie z tego. To rozszerza nasze pierwotne punkty na trójwymiarowe; ( x , y , w ), przy czym „w” wynosi 0 lub 1 po normalizacji. Funkcja normalizacji to:
NORM: ( x , y , w ) -> ( x + floor ( w / 2), y , w mod 2), przy zdefiniowanej operacji „mod” tak, że zwraca tylko wartości dodatnie lub zero.
Nasz algorytm wygląda teraz następująco:
Przekształć nasze punkty ( a , b , c ) w ich pozycje względem środka obrotu ( x , y , w ), obliczając ( a - x , b - y , c - w ), a następnie normalizując wynik. To oczywiście ustawia środek obrotu na (0,0,0).
Przekształć nasze punkty z ich „rodzimych” współrzędnych na obrotowe zespoły złożone: ( a , b , c ) -> (2 × a + c , b ) = 2 × a + c + b × f
Obróć nasze punkty, mnożąc je w razie potrzeby przez jedną z powyższych liczb obrotowych.
Ra przekształca punkty z powrotem ze współrzędnych obrotowych na ich „rodzime”: ( r , s ) -> (floor ( r / 2), s , r mod 2), z „mod” zdefiniowanym jak powyżej.
Ponownie przekształć punkty z powrotem do ich pierwotnej pozycji, dodając je do środka obrotu ( x , y , z ) i normalizując.
Prosta wersja z naszych numerów „potrójnych” oparty f w C ++ będzie wyglądać następująco:
źródło