Estoy tratando de hacer un píxel para coordinar la función de un mapa hexadecimal, pero no entiendo las matemáticas correctamente, todo lo que intento parece estar un poco fuera de lugar, y los ejemplos que he encontrado se basan en mapas centrados en círculos.
Por 'basado en matriz' me refiero a la forma en que se ordenan los hexágonos, ver foto.
El resultado más preciso que obtuve fue con el siguiente código, pero aún está apagado y empeora cuanto más aumentan los valores:
public HexCell<T> coordsToHexCell(float x, float y){
final float size = this.size; // cell size
float q = (float) ((1f/3f* Math.sqrt(3) * x - 1f/3f * y) / size);
float r = 2f/3f * y / size;
return getHexCell((int) r, (int) q);
}
La pantalla comienza con 0,0 en la parte superior izquierda, cada celda conoce su centro.
Todo lo que necesito es una forma de traducir las coordenadas de la pantalla en coordenadas hexadecimales. ¿Cómo podría hacer eso?
fuente
Hay dos formas de manejar este problema, en mi opinión.
Utiliza un mejor sistema de coordenadas. Puede hacer que las matemáticas sean mucho más fáciles para usted si es inteligente acerca de cómo numerar los hexes. Amit Patel tiene la referencia definitiva sobre rejillas hexagonales. Querrá buscar coordenadas axiales en esa página.
Pedir prestado el código de alguien que ya lo resolvió. Tengo un código que funciona, que saqué de la fuente de Battle for Wesnoth . Tenga en cuenta que mi versión tiene la parte plana de los hexágonos en la parte superior, por lo que tendrá que intercambiar x e y.
fuente
Creo que la respuesta de Michael Kristofik es correcta, especialmente por mencionar el sitio web de Amit Patel, pero quería compartir mi enfoque de novato a las redes hexagonales.
Este código fue tomado de un proyecto en el que perdí interés y abandoné escrito en JavaScript, pero la posición del mouse en el mosaico hexadecimal funcionó muy bien. Usé * este artículo de GameDev * para mis referencias. Desde ese sitio web, el autor tenía esta imagen que mostraba cómo representar matemáticamente todos los lados y posiciones del maleficio.
En mi clase de renderizado, tenía esto definido en un método que me permitía establecer cualquier longitud del lado Hex que quisiera. Aquí se muestra porque algunos de estos valores fueron referenciados en el código de coordenadas píxel a hexadecimal.
En la clase de entrada del mouse, creé un método que aceptaba una coordenada x e y de pantalla, y devolvía un objeto con la coordenada Hex dentro de la cual reside el píxel. * Tenga en cuenta que tenía una "cámara" falsa, por lo que también se incluyen las compensaciones para la posición de renderizado.
Finalmente, aquí hay una captura de pantalla de mi proyecto con la depuración del render activada. Muestra las líneas rojas donde el código verifica las celdas Tipo A frente a Tipo B junto con las coordenadas Hex y los contornos de las celdas.
Espero que esto ayude un poco.
fuente
En realidad encontré una solución sin matemática hexadecimal.
Como mencioné en la pregunta, cada celda guarda sus propias coordenadas centrales, calculando el centro hexadecimal más cercano a las coordenadas de píxel puedo determinar la correspondiente celda hexadecimal con precisión de píxel (o muy cerca de ella).
No creo que sea la mejor manera de hacerlo, ya que tengo que iterar en cada celda y puedo ver cómo eso podría ser gravoso, pero dejaré el código como una solución alternativa:
fuente
0…cols-1
y todas las filas0…rows-1
, puede escanearcol_guess - 1 … col_guess+1
yrow_guess - 1 … row_guess + 1
. Eso es solo 9 hexes, por lo que es rápido y no depende del tamaño del mapa.Aquí están las agallas de una implementación en C # de una de las técnicas publicadas en el sitio web de Amit Patel (estoy seguro de que traducir a Java no será un desafío):
El resto del proyecto está disponible aquí como Open Source, incluidas las clases MatrixInt2D y VectorInt2D mencionadas anteriormente:
http://hexgridutilities.codeplex.com/
Aunque la implementación anterior es para hexes de superficie plana, la biblioteca HexgridUtilities incluye la opción de transponer la cuadrícula.
fuente
Encontré un enfoque simple y alternativo que usa la misma lógica que un tablero de ajedrez regular. Crea un efecto de ajuste a la cuadrícula con puntos en el centro de cada mosaico y en cada vértice (al crear una cuadrícula más ajustada e ignorar los puntos alternos).
Este enfoque funciona bien para juegos como Catan, donde los jugadores interactúan con fichas y vértices, pero no es adecuado para juegos donde los jugadores solo interactúan con fichas, ya que devuelve qué punto central o vértice a las coordenadas están más cerca, en lugar de qué ficha hexagonal Las coordenadas están dentro.
La geometría
Si coloca puntos en una cuadrícula con columnas que son un cuarto del ancho de un mosaico y filas que son la mitad de la altura de un mosaico, obtendrá este patrón:
Si luego modifica el código para omitir cada segundo punto en un patrón de tablero de ajedrez (omitir
if column % 2 + row % 2 == 1
), terminará con este patrón:Implementación
Con esa geometría en mente, puede crear una matriz 2D (tal como lo haría con una cuadrícula cuadrada), almacenando las
x, y
coordenadas para cada punto en la cuadrícula (desde el primer diagrama), algo como esto:Nota: Como es normal, cuando crea una cuadrícula alrededor de los puntos (en lugar de colocar puntos en los puntos mismos), debe compensar el origen (restando la mitad del ancho de una columna
x
y la mitad de la altura de una filay
).Ahora que tiene su matriz 2D (
points
) inicializada, puede encontrar el punto más cercano al mouse tal como lo haría en una cuadrícula cuadrada, solo teniendo que ignorar cualquier otro punto para producir el patrón en el segundo diagrama:Eso funcionará, pero las coordenadas se están redondeando al punto más cercano (o sin punto) en función del rectángulo invisible dentro del puntero. Realmente desea una zona circular alrededor del punto (por lo que el rango de ajuste es igual en todas las direcciones). Ahora que sabe qué punto verificar, puede encontrar fácilmente la distancia (usando el Teorema de Pitágoras). El círculo implícito aún tendría que caber dentro del rectángulo delimitador original, limitando su diámetro máximo al ancho de una columna (un cuarto del ancho de un mosaico), pero aún es lo suficientemente grande como para funcionar bien en la práctica.
fuente