Estou tentando fazer um pixel para coordenar a função de um mapa hexadecimal, mas não estou aprendendo a matemática corretamente, tudo o que tento parece um pouco complicado e os exemplos que encontrei foram baseados em mapas centralizados em círculo.
Por 'array array', quero dizer a maneira como os hexágonos são ordenados, veja a foto.
O resultado mais preciso que obtive foi com o código a seguir, mas ele ainda está desativado e piora quanto mais os valores aumentam:
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);
}
A tela começa com 0,0 no canto superior esquerdo, cada célula conhece seu centro.
Tudo o que preciso é de uma maneira de traduzir as coordenadas da tela em coordenadas hexadecimais. Como eu pude fazer isso?
fonte
Existem duas maneiras de lidar com esse problema, na minha opinião.
Use um melhor sistema de coordenadas. Você pode facilitar muito a matemática se for inteligente sobre como numerar os hexágonos. Amit Patel tem a referência definitiva em grades hexagonais. Você deseja procurar coordenadas axiais nessa página.
Emprestar código de alguém que já o resolveu. Eu tenho algum código que funciona, que tirei da fonte Battle for Wesnoth . Lembre-se de que minha versão tem a parte plana dos hexágonos na parte superior, então você terá que trocar xey.
fonte
Acho que a resposta de Michael Kristofik está correta, especialmente por mencionar o site de Amit Patel, mas eu queria compartilhar minha abordagem iniciante às grades Hex.
Esse código foi retirado de um projeto em que perdi o interesse e abandonei a escrita em JavaScript, mas a posição do mouse em hexadecimal funcionou muito bem. Eu usei * este artigo GameDev * para minhas referências. A partir desse site, o autor tinha uma imagem que mostrava como representar matematicamente todos os lados e posições do Hex.
Na minha classe de renderização, eu defini isso em um método que me permitiu definir qualquer comprimento do lado Hex que eu desejasse. Mostrado aqui porque alguns desses valores foram referenciados no pixel para o código de coordenadas hexadecimais.
Na classe de entrada do mouse, criei um método que aceitou as coordenadas xey da tela e retornei um objeto com a coordenada hexadecimal em que o pixel reside. * Observe que eu tinha uma "câmera" falsa, então compensações para a posição de renderização também estão incluídas.
Finalmente, aqui está uma captura de tela do meu projeto com a depuração da renderização ativada. Ele mostra as linhas vermelhas nas quais o código verifica as células Tipo A vs Tipo B, juntamente com as coordenadas Hex e os contornos das células.
Espero que isso ajude alguns.
fonte
Na verdade, eu encontrei uma solução sem matemática hexadecimal.
Como mencionei na pergunta, cada célula salva suas próprias cordas centrais, calculando o centro hexadecimal mais próximo das cordas de pixel, posso determinar a célula hexadecimal correspondente com precisão de pixel (ou muito próxima a ela).
Eu não acho que é a melhor maneira de fazer isso, pois tenho que iterar para cada célula e posso ver como isso pode ser desgastante, mas deixarei o código como uma solução alternativa:
fonte
0…cols-1
e todas as linhas0…rows-1
, você pode varrercol_guess - 1 … col_guess+1
erow_guess - 1 … row_guess + 1
. São apenas 9 hexágonos, portanto é rápido e não depende do tamanho do mapa.Aqui está a essência de uma implementação em C # de uma das técnicas publicadas no site de Amit Patel (tenho certeza que traduzir para Java não será um desafio):
O restante do projeto está disponível aqui como código aberto, incluindo as classes MatrixInt2D e VectorInt2D mencionadas acima:
http://hexgridutilities.codeplex.com/
Embora a implementação acima seja para hexágonos planos, a biblioteca HexgridUtilities inclui a opção de transpor a grade.
fonte
Encontrei uma abordagem simples e alternativa que usa a mesma lógica que um tabuleiro de xadrez regular. Ele cria um efeito de encaixe na grade com pontos no centro de cada bloco e em todo vértice (criando uma grade mais apertada e ignorando pontos alternados).
Essa abordagem funciona bem para jogos como Catan, onde os jogadores interagem com blocos e vértices, mas não é adequada para jogos nos quais os jogadores interagem apenas com blocos, pois retorna qual ponto central ou vértice as coordenadas estão mais próximas, em vez de qual bloco hexagonal o coordenadas estão dentro.
A geometria
Se você colocar pontos em uma grade com colunas que têm um quarto da largura de um bloco e linhas com metade da altura de um bloco, você obtém este padrão:
Se você modificar o código para pular cada segundo ponto em um padrão quadriculado (pular
if column % 2 + row % 2 == 1
), você terminará com este padrão:Implementação
Com essa geometria em mente, você pode criar uma matriz 2D (como faria com uma grade quadrada), armazenando as
x, y
coordenadas de cada ponto da grade (no primeiro diagrama) - algo como isto:Nota: Como normal, ao criar uma grade em torno dos pontos (em vez de colocar pontos nos próprios pontos), é necessário compensar a origem (subtraindo metade da largura de uma coluna
x
e metade da altura de uma linhay
).Agora que você
points
inicializou sua matriz 2D ( ), pode encontrar o ponto mais próximo do mouse da mesma forma que faria em uma grade quadrada, apenas tendo que ignorar todos os outros pontos para produzir o padrão no segundo diagrama:Isso funcionará, mas as coordenadas estão sendo arredondadas para o ponto mais próximo (ou nenhum ponto) com base no retângulo invisível em que o ponteiro está. Você realmente deseja uma zona circular em torno do ponto (para que o intervalo de snap seja igual em todas as direções). Agora que você sabe qual ponto verificar, pode facilmente encontrar a distância (usando o Teorema de Pitágoras). O círculo implícito ainda teria que caber dentro do retângulo delimitador original, limitando seu diâmetro máximo à largura de uma coluna (quarto da largura de um ladrilho), mas ainda é grande o suficiente para funcionar bem na prática.
fonte