Meu jogo isométrico 2D usa um mapa de grade hexagonal. Em referência à imagem abaixo, como faço para girar as estruturas de hexágono azul claro em 60 graus ao redor dos hexágonos rosa?
EDITAR:
O hex principal é (0,0). Outros hexágonos são filhos, o número deles é fixo. Vou definir apenas uma posição (neste caso, à direita) e calcular outras direções, se necessário (canto inferior esquerdo, botão direito, canto superior direito, canto superior esquerdo e esquerdo). Outros hexes são definidos como: Package.Add (-1,0), Package.Add (-2,0) e assim por diante.
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;
}
Neste código Number
é o hex principal e Point
é o hex que eu quero girar, mas não funciona:
2d
rotation
maps
hexagonal-grid
ruzsoo
fonte
fonte
Respostas:
Como observa Martin Sojka , as rotações são mais simples se você converter para um sistema de coordenadas diferente, executar a rotação e depois voltar.
Eu uso um sistema de coordenadas diferente do Martin, rotulado
x,y,z
. Não há oscilação neste sistema, e é útil para muitos algoritmos hexadecimais. Neste sistema, você pode girar o hexágono ao0,0,0
“girar” as coordenadas e virar seus sinais:x,y,z
se transforma de-y,-z,-x
um lado e-z,-x,-y
do outro. Eu tenho um diagrama nesta página .(Sinto muito por x / y / z vs X / Y, mas eu uso x / y / z no meu site e você usa X / Y no seu código, portanto, nesta resposta o caso é importante! Então, eu vou usar
xx,yy,zz
como os nomes das variáveis abaixo para tentar facilitar a distinção.)Converta suas
X,Y
coordenadas nox,y,z
formato:Faça uma rotação de 60 ° de uma maneira ou de outra:
Converta as
x,y,z
costas em seuX,Y
:Por exemplo, se você começar com (X = -2, Y = 1) e quiser girar 60 ° para a direita, converterá:
depois gire
-2,1,1
60 ° para a direita com:como você vê aqui:
depois converta de
-1,2,-1
volta:Então (X = -2, Y = 1) gira 60 ° para a direita em (X = -2, Y = -1).
fonte
Vamos primeiro definir um novo número. Não se preocupe, é fácil.
Ou, para simplificar: f = √3 × i , sendo i a unidade imaginária . Com isso, uma rotação de 60 graus no sentido horário é o mesmo que multiplicação por 1/2 × (1 - f ) e rotação de 60 graus no sentido anti-horário, o mesmo que multiplicação por 1/2 × (1 + f ) . Se isso soa estranho, lembre-se de que a multiplicação por um número complexo é igual à rotação no plano 2D. Nós apenas "esmagamos" os números complexos na direção imaginária um pouco (por √3) para não ter que lidar com raízes quadradas ... ou não inteiros, nesse caso.
Também podemos escrever o ponto (a, b) como a + b × f .
Isso nos permite rotacionar qualquer ponto do avião; por exemplo, o ponto (2,0) = 2 + 0 × f gira para (1, -1), depois para (-1, -1), (-2,0), (-1,1), ( 1,1) e, finalmente, de volta a (2,0), simplesmente multiplicando-o.
Obviamente, precisamos de uma maneira de traduzir esses pontos de nossas coordenadas para aqueles em que fazemos as rotações e depois voltar. Para isso, é necessária outra informação: se o ponto em que fazemos a rotação for para a "esquerda" ou a "direita" da linha vertical. Por uma questão de simplicidade, declaramos que tem um valor de "oscilação" w de 0 se estiver à esquerda (como o centro da rotação [0,0] em suas duas figuras inferiores) e de 1 se estiver à direita disso. Isso amplia nossos pontos originais para serem tridimensionais; ( x , y , w ), com "w" sendo 0 ou 1 após a normalização. A função de normalização é:
NORM: ( x , y , w ) -> ( x + piso ( w / 2), y , w mod 2), com a operação "mod" definida de forma que retorne apenas valores positivos ou zero.
Nosso algoritmo agora tem a seguinte aparência:
Transforme nossos pontos ( a , b , c ) em suas posições em relação ao centro rotacional ( x , y , w ) calculando ( a - x , b - y , c - w ) e normalizando o resultado. Isso coloca o centro rotacional em (0,0,0) obviamente.
Transforme nossos pontos de suas coordenadas "nativas" para as coordenadas do complexo rotacional: ( a , b , c ) -> (2 × a + c , b ) = 2 × a + c + b × f
Gire nossos pontos multiplicando-os por um dos números de rotação acima, conforme necessário.
Transformar Ra de volta dos pontos das coordenadas rotacionais para os "nativos": ( r , s ) -> (piso ( r / 2), s , r mod 2), com "mod" definido como acima.
Volte a transformar os pontos na posição original, adicionando-os ao centro de rotação ( x , y , z ) e normalizando.
Uma versão simples de nossos números "triplex" baseados em f em C ++ seria assim:
fonte