Mi juego isométrico 2D utiliza un mapa de cuadrícula hexagonal. En referencia a la imagen a continuación, ¿cómo giro las estructuras hexagonales azul claro en 60 grados alrededor de los hexágonos rosados?
EDITAR:
El hexágono principal es (0,0). Otros hexes son hijos, el conteo de ellos es fijo. Voy a definir solo una posición (en este caso es la derecha) y calcular otras direcciones si es necesario (izquierda-abajo, derecha-abajo, derecha-arriba, izquierda-arriba e izquierda). Otros hexes se definen como: Package.Add (-1,0), Package.Add (-2,0) y así sucesivamente.
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;
}
En este código Number
es el hexágono principal y Point
es el hexágono que quiero rotar, pero no funciona:
2d
rotation
maps
hexagonal-grid
ruzsoo
fuente
fuente
Respuestas:
Como señala Martin Sojka , las rotaciones son más simples si convierte a un sistema de coordenadas diferente, realiza la rotación y luego vuelve a convertir.
Yo uso un sistema de coordenadas diferente al de Martin, etiquetado
x,y,z
. No hay bamboleo en este sistema, y es útil para muchos algoritmos hexadecimales. En este sistema, puede rotar el hexágono0,0,0
"rotando" las coordenadas y volteando sus signos: sex,y,z
convierte en-y,-z,-x
un sentido y-z,-x,-y
otra. Tengo un diagrama en esta página .(Lamento lo de x / y / z vs X / Y, pero uso x / y / z en mi sitio y tú usas X / Y en tu código, ¡así que en esta respuesta el caso es importante! Así que voy a usar
xx,yy,zz
como los nombres de variables a continuación para intentar que sea más fácil distinguir).Convierta sus
X,Y
coordenadas alx,y,z
formato:Realice una rotación de 60 ° de una forma u otra:
Convertir el
x,y,z
espalda a suX,Y
:Por ejemplo, si comienza con (X = -2, Y = 1) y desea girar 60 ° a la derecha, convertiría:
luego rotar
-2,1,1
60 ° a la derecha con:como ves aquí:
luego convertir
-1,2,-1
nuevo:Entonces (X = -2, Y = 1) gira 60 ° a la derecha en (X = -2, Y = -1).
fuente
Primero definamos un nuevo número. No te preocupes, es fácil.
O, para decirlo simplemente: f = √3 × i , siendo i la unidad imaginaria . Con esto, una rotación de 60 grados en sentido horario es lo mismo que la multiplicación por 1/2 × (1 - f ) , y la rotación de 60 grados en sentido antihorario es lo mismo que la multiplicación por 1/2 × (1 + f ) . Si esto suena extraño, recuerde que la multiplicación por un número complejo es lo mismo que la rotación en el plano 2D. Simplemente "aplastamos" un poco los números complejos en la dirección imaginaria (por √3) para no tener que lidiar con raíces cuadradas ... o no enteros, para el caso.
También podemos escribir el punto (a, b) como a + b × f .
Esto nos permite rotar cualquier punto del plano; por ejemplo, el punto (2,0) = 2 + 0 × f gira a (1, -1), luego a (-1, -1), (-2,0), (-1,1), ( 1,1) y finalmente volver a (2,0), simplemente multiplicándolo.
Por supuesto, necesitamos una forma de traducir esos puntos de nuestras coordenadas a aquellos en los que hacemos las rotaciones, y luego nuevamente. Para esto, se necesita otra información: si el punto en el que hacemos la rotación es hacia la "izquierda" o la "derecha" de la línea vertical. Para simplificar, declaramos que tiene un valor de "oscilación" w de 0 si está a la izquierda (como el centro de la rotación [0,0] en las dos imágenes inferiores), y de 1 si está a la derecha de eso. Esto extiende nuestros puntos originales para ser tridimensionales; ( x , y , w ), con "w" siendo 0 o 1 después de la normalización. La función de normalización es:
NORM: ( x , y , w ) -> ( x + piso ( w / 2), y , w mod 2), con la operación "mod" definida de modo que solo devuelva valores positivos o cero.
Nuestro algoritmo ahora se ve de la siguiente manera:
Transforme nuestros puntos ( a , b , c ) en sus posiciones relativas al centro de rotación ( x , y , w ) calculando ( a - x , b - y , c - w ), luego normalizando el resultado. Esto pone el centro de rotación en (0,0,0) obviamente.
Transforme nuestros puntos de sus coordenadas "nativas" a las complejas rotacionales: ( a , b , c ) -> (2 × a + c , b ) = 2 × a + c + b × f
Gire nuestros puntos multiplicándolos con uno de los números de rotación anteriores, según sea necesario.
Ra-transforma los puntos de vuelta desde las coordenadas de rotación a sus "nativas": ( r , s ) -> (floor ( r / 2), s , r mod 2), con "mod" definido como arriba.
Vuelva a transformar los puntos a su posición original agregándolos al centro de rotación ( x , y , z ) y normalizando.
Una versión simple de nuestros números "triplex" basada en f en C ++ se vería así:
fuente