Construção de hexágono regular - como desenhar um hexágono. Como construir um hexágono regular Como desenhar um hexágono com um lápis

Existe um lápis perto de você? Dê uma olhada em sua seção transversal - é um hexágono regular ou, como também é chamado, um hexágono. A seção transversal de uma noz, um campo de xadrez hexagonal, algumas moléculas complexas de carbono (por exemplo, grafite), um floco de neve, um favo de mel e outros objetos também têm esse formato. Um hexágono regular gigante foi descoberto recentemente em Não parece estranho que a natureza use tantas vezes estruturas com esse formato específico para suas criações? Vamos olhar mais de perto.

Um hexágono regular é um polígono com seis lados iguais e ângulos iguais. Pelo curso escolar sabemos que possui as seguintes propriedades:

  • O comprimento dos seus lados corresponde ao raio do círculo circunscrito. De todos, apenas o hexágono regular possui esta propriedade.
  • Os ângulos são iguais entre si e cada medida é 120°.
  • O perímetro de um hexágono pode ser encontrado usando a fórmula P=6*R, se o raio do círculo descrito em torno dele for conhecido, ou P=4*√(3)*r, se o círculo estiver inscrito nele. R e r são os raios do círculo circunscrito e inscrito.
  • A área ocupada por um hexágono regular é determinada da seguinte forma: S=(3*√(3)*R 2)/2. Se o raio for desconhecido, substitua o comprimento de um dos lados - como se sabe, corresponde ao comprimento do raio do círculo circunscrito.

Um hexágono regular tem uma característica interessante, graças à qual se tornou tão difundido na natureza - é capaz de preencher qualquer superfície de um plano sem sobreposições ou lacunas. Existe ainda o chamado Lema Pal, segundo o qual um hexágono regular, cujo lado é igual a 1/√(3), é uma cobertura universal, ou seja, pode cobrir qualquer conjunto com diâmetro de uma unidade .

Agora vamos ver como construir um hexágono regular. Existem vários métodos, o mais simples dos quais envolve o uso de compasso, lápis e régua. Primeiro, desenhamos um círculo arbitrário com um compasso e, em seguida, marcamos um ponto em um local arbitrário desse círculo. Sem alterar o ângulo do compasso, colocamos a ponta neste ponto, marcamos o próximo entalhe no círculo e continuamos até obter todos os 6 pontos. Agora só falta conectá-los com segmentos retos e você obterá a figura desejada.

Na prática, há casos em que é necessário desenhar um grande hexágono. Por exemplo, em um teto de gesso cartonado de dois níveis, ao redor do local de montagem do lustre central, é necessário instalar seis pequenas lâmpadas no nível inferior. Bússolas deste tamanho serão muito, muito difíceis de encontrar. O que fazer neste caso? Como você desenha um círculo grande? Muito simples. Você precisa pegar um fio forte do comprimento necessário e amarrar uma de suas pontas oposta ao lápis. Agora só falta encontrar um auxiliar que pressione a segunda ponta do fio no teto no ponto desejado. É claro que, neste caso, pequenos erros são possíveis, mas é improvável que sejam notados por alguém de fora.

Contente:

Um hexágono regular, também chamado de hexágono perfeito, tem seis lados iguais e seis ângulos iguais. Você pode desenhar um hexágono com uma fita métrica e um transferidor, um hexágono áspero com um objeto redondo e uma régua, ou um hexágono ainda mais áspero com apenas um lápis e um pouco de intuição. Se você quiser saber como desenhar um hexágono de diferentes maneiras, continue lendo.

Passos

1 Desenhe um hexágono perfeito usando um compasso

  1. 1 Usando um compasso, desenhe um círculo. Insira o lápis na bússola. Estenda a bússola até a largura desejada do raio do seu círculo. O raio pode ter de alguns a dez centímetros de largura. Em seguida, coloque um compasso e um lápis no papel e desenhe um círculo.
    • Às vezes é mais fácil desenhar primeiro meio círculo e depois a outra metade.
  2. 2 Mova a agulha da bússola até a borda do círculo. Coloque-o no topo do círculo. Não altere o ângulo ou a posição da bússola.
  3. 3 Faça uma pequena marca a lápis na borda do círculo. Deixe-o distinto, mas não muito escuro, pois você irá apagá-lo mais tarde. Lembre-se de manter o ângulo definido para a bússola.
  4. 4 Mova a agulha da bússola até a marca que você acabou de fazer. Coloque a agulha diretamente na marca.
  5. 5 Faça outra marca de lápis na borda do círculo. Desta forma você fará uma segunda marca a uma certa distância da primeira marca. Continue se movendo em uma direção.
  6. 6 Use o mesmo método para fazer mais quatro marcas. Você deve retornar à marca original. Caso contrário, provavelmente o ângulo em que você segurou a bússola e fez suas marcas mudou. Isso pode ter acontecido porque você apertou com muita força ou, pelo contrário, afrouxou um pouco.
  7. 7 Conecte as marcas usando uma régua. Os seis locais onde suas marcas se cruzam com a borda do círculo são os seis vértices do hexágono. Usando uma régua e um lápis, desenhe linhas retas conectando as marcas adjacentes.
  8. 8 Apague o círculo, as marcas nas bordas do círculo e quaisquer outras marcas que você tenha feito. Depois de apagar todas as linhas de construção, seu hexágono perfeito deverá estar pronto.

2 Desenhe um hexágono áspero usando um objeto redondo e uma régua

  1. 1 Trace a borda do copo com um lápis. Desta forma você desenhará um círculo. É muito importante desenhar a lápis, pois depois será necessário apagar todas as linhas auxiliares. Você também pode traçar um copo, uma jarra ou qualquer outra coisa que tenha uma base redonda.
  2. 2 Desenhe linhas horizontais no centro do seu círculo. Você pode usar uma régua, um livro - qualquer coisa com régua. Se você tiver uma régua, poderá marcar o meio calculando o comprimento vertical do círculo e dividindo-o ao meio.
  3. 3 Desenhe um “X” na metade do círculo, dividindo-o em seis seções iguais. Como você já traçou uma linha no meio do círculo, o X precisa ser mais largo do que alto para que as partes sejam iguais. Imagine dividir uma pizza em seis pedaços.
  4. 4 Faça triângulos de cada seção. Para fazer isso, use uma régua para desenhar uma linha reta abaixo da parte curva de cada seção, conectando-a às outras duas linhas para formar um triângulo. Faça isso com as cinco seções restantes. Pense nisso como fazer uma crosta em volta das fatias de pizza.
  5. 5 Apague todas as linhas auxiliares. As linhas-guia incluem o seu círculo, as três linhas que o dividiram em seções e outras marcas que você fez ao longo do caminho.

3 Desenhe um hexágono áspero usando um lápis

  1. 1 Desenhe uma linha horizontal. Para desenhar uma linha reta sem régua, basta desenhar o ponto inicial e final da sua linha horizontal. Em seguida, coloque o lápis no ponto inicial e desenhe a linha até o fim. O comprimento desta linha pode ser de apenas alguns centímetros.
  2. 2 Desenhe duas linhas diagonais a partir das extremidades da linha horizontal. A linha diagonal do lado esquerdo deve apontar para fora da mesma forma que a linha diagonal do lado direito. Você pode imaginar que essas linhas formam um ângulo de 120 graus em relação à linha horizontal.
  3. 3 Desenhe mais duas linhas horizontais provenientes das primeiras linhas horizontais desenhadas para dentro. Isso criará uma imagem espelhada das duas primeiras linhas diagonais. A linha inferior esquerda deve ser um reflexo da linha superior esquerda e a linha inferior direita deve ser um reflexo da linha superior direita. Enquanto as linhas horizontais superiores devem estar voltadas para fora, as inferiores devem estar voltadas para dentro, em direção à base.
  4. 4 Desenhe outra linha horizontal conectando as duas linhas diagonais inferiores. Desta forma você desenhará a base do seu hexágono. Idealmente, esta linha deve ser paralela à linha horizontal superior. Agora você completou seu hexágono.
  • O lápis e o compasso devem ser afiados para minimizar erros de marcas muito largas.
  • Ao usar o método da bússola, se você conectar cada marca em vez de todas as seis, obterá um triângulo equilátero.

Avisos

  • A bússola é um objeto bastante pontiagudo, tome muito cuidado com ela.

Princípio da Operação

  • Cada método o ajudará a desenhar um hexágono formado por seis triângulos equiláteros com raio igual ao comprimento de todos os lados. Os seis raios desenhados têm o mesmo comprimento e todas as linhas para criar o hexágono também têm o mesmo comprimento, uma vez que a largura do compasso não mudou. Devido ao fato dos seis triângulos serem equiláteros, os ângulos entre seus vértices são de 60 graus.

O que você vai precisar

  • Papel
  • Lápis
  • Governante
  • Par de bússolas
  • Algo que possa ser colocado sob o papel para evitar que a agulha da bússola escorregue.
  • Apagador

Um triângulo circunscrito regular é construído da seguinte forma(Figura 38). Do centro de um determinado círculo de raio R1 desenhe um círculo com raio R2 = 2R1 e divida-o em três partes iguais. Pontos de divisão A, B, C são os vértices de um triângulo regular circunscrito a um círculo de raio R1 .

Figura 38

Quadrilátero circunscrito regular (quadrado) pode ser construído usando um compasso e uma régua (Figura 39). Em um determinado círculo, dois diâmetros perpendiculares entre si são desenhados. Tomando como centros os pontos de intersecção dos diâmetros com o círculo, o raio do círculo R descrever arcos até que eles se cruzem em pontos A, B, C, D . Pontos A , B , C , D e são os vértices de um quadrado circunscrito a um determinado círculo.

Figura 39

Para construir um hexágono circunscrito regularé necessário primeiro construir os vértices do quadrado descrito na forma indicada acima (Figura 40, a). Simultaneamente com a determinação dos vértices do quadrado, um determinado círculo de raio R dividido em seis partes iguais nos pontos 1, 2, 3, 4, 5, 6 e desenhe os lados verticais do quadrado. Desenhando um círculo através dos pontos divisórios 2–5 E 3–6 linhas retas até se cruzarem com os lados verticais do quadrado (Figura 40, b), obtemos os vértices A, B, D, E descrito hexágono regular.

Figura 40

Outros picos C E F determinado usando um arco de círculo de raio O.A., que é realizado até cruzar com a continuação do diâmetro vertical de um determinado círculo.
3 EMPARELHAMENTOS

Vamos aprender como desenhar um prisma hexagonal em diferentes posições.

Estude diferentes formas de construir um hexágono regular, faça desenhos de hexágonos, verifique a exatidão de sua construção. Construa prismas hexagonais com base nos hexágonos.

Considere o prisma hexagonal da Fig. 3.52 e suas projeções ortogonais na Fig. 3,53. Na base de um prisma hexagonal (hexágono) existem hexágonos regulares, as faces laterais são retângulos idênticos. Para representar corretamente um hexágono em perspectiva, você deve primeiro aprender como representar corretamente sua base em perspectiva (Fig. 3.54). No hexágono da Fig. 3,55 vértices são designados por números de um a seis. Se você conectar os pontos 1 e 3, 4 e 6 com retas verticais, notará que essas retas, juntamente com o ponto central do círculo, dividem o diâmetro 5 - 2 em quatro segmentos iguais (esses segmentos são indicados por arcos ). Os lados opostos de um hexágono são paralelos entre si e a uma linha que passa por seu centro e conecta dois vértices (por exemplo, os lados 6 - 1 e 4 - 3 são paralelos à linha 5 - 2). Essas observações o ajudarão a construir um hexágono em perspectiva, bem como a verificar a exatidão dessa construção. Existem duas maneiras de construir um hexágono regular a partir de uma representação: com base em um círculo circunscrito e com base em um quadrado.

Baseado em um círculo circunscrito. Veja a Fig. 3,56. Todos os vértices de um hexágono regular pertencem a uma circunferência cujo raio é igual ao lado do hexágono.


Hexágono horizontal. Desenhe uma elipse horizontal de abertura arbitrária, ou seja, um círculo circunscrito em perspectiva. Agora você precisa encontrar seis pontos nele, que são os vértices do hexágono. Desenhe qualquer diâmetro de um determinado círculo através de seu centro (Fig. 3.57). Os pontos extremos do diâmetro - 5 e 2, situados na elipse, são os vértices do hexágono. Para encontrar os vértices restantes, é necessário dividir esse diâmetro em quatro segmentos iguais. O diâmetro já foi dividido pelo ponto central do círculo em dois raios, resta apenas dividir cada raio ao meio. Num desenho em perspectiva, todos os quatro segmentos se contraem uniformemente à medida que se afastam do observador (Fig. 3.58). Agora desenhe através dos pontos médios dos raios - pontos A e B - linhas retas perpendiculares à linha reta 5 - 2. Você pode encontrar sua direção usando tangentes à elipse nos pontos 5 e 2 (Fig. 3.59). Essas tangentes serão perpendiculares ao diâmetro 5 - 2, e as retas traçadas através dos pontos A e B paralelas a essas tangentes também serão perpendiculares à reta 5 - 2. Designe os pontos obtidos na intersecção dessas retas com a elipse como 1, 3, 4, 6 (Fig. 3.60). Conecte todos os seis vértices com linhas retas (Fig. 3.61).

Verifique a exatidão de sua construção de diferentes maneiras. Se a construção estiver correta, então as linhas que conectam os vértices opostos do hexágono se cruzam no centro do círculo (Fig. 3.62), e os lados opostos do hexágono são paralelos aos diâmetros correspondentes (Fig. 3.63). Outro método de verificação é mostrado na Fig. 3,64.

Hexágono vertical. Nesse hexágono, as retas que conectam os pontos 7 e 3, b e 4, bem como as tangentes ao círculo circunscrito nos pontos 5 e 2, têm direção vertical e a mantêm no desenho em perspectiva. Assim, traçando duas tangentes verticais à elipse, encontramos os pontos 5 e 2 (pontos de tangência). Conecte-os com uma linha reta e depois divida o diâmetro resultante 5 - 2 em 4 segmentos iguais, levando em consideração suas reduções de perspectiva (Fig. 3.65). Desenhe linhas verticais através dos pontos A e B e, em sua interseção com a elipse, encontre os pontos 1,3,6l4. Em seguida, conecte os pontos 1 - 6 sequencialmente com linhas retas (Fig. 3.66). Verifique a exatidão da construção do hexágono da mesma forma que no exemplo anterior.

O método descrito de construção de um hexágono permite-nos obter esta figura baseada num círculo, que é mais fácil de representar em perspectiva do que um quadrado de determinadas proporções. Portanto, este método de construção de um hexágono parece ser o mais preciso e universal. O método de construção quadrado facilita a representação de um hexágono no caso em que já exista um cubo no desenho, ou seja, quando são determinadas as proporções do quadrado e a direção de seus lados.

Baseado em um quadrado. Veja a Fig. 3,67. Um hexágono inscrito em um quadrado é igual ao lado do quadrado na direção horizontal 5 - 2 e menor que seu comprimento na direção vertical.

Hexágono vertical. Desenhe um quadrado vertical em perspectiva. Desenhe uma linha reta através da intersecção das diagonais paralelas aos seus lados horizontais. Divida o segmento resultante 5 - 2 em quatro partes iguais e desenhe linhas verticais através dos pontos A e B (Fig. 3.68). As linhas que delimitam o hexágono na parte superior e inferior não coincidem com os lados do quadrado. Desenhe-os a uma certa distância (1114 a) dos lados horizontais do quadrado e paralelos a eles. Conectando os pontos 1 e 3 assim encontrados com o ponto 2, e os pontos 6 e 4 com o ponto 5, obtemos um hexágono (Fig. 3.69).

Um hexágono horizontal é construído na mesma sequência (Fig. 3.70 e 3.71).

Este método de construção só é adequado para hexágonos com abertura suficiente. Se a abertura do hexágono for insignificante, é melhor usar o método baseado no círculo circunscrito. Para verificar um hexágono construído através de um quadrado, você pode usar métodos já conhecidos.

Além disso, há outra maneira - descrever um círculo ao redor do hexágono resultante (no seu desenho - uma elipse). Todos os vértices do hexágono devem pertencer a esta elipse.

Depois de dominar as habilidades de desenho de um hexágono, você estará livre para desenhar um prisma hexagonal. Observe atentamente o diagrama da Fig. 3.72, bem como diagramas para construção de prismas hexagonais baseados em um círculo circunscrito (Fig. 3.73; 3.74 e 3.75) e baseados em um quadrado (Fig. 3.76; 3.77 e 3.78). Desenhe hexágonos verticais e horizontais de maneiras diferentes. No desenho de um hexágono vertical, os lados longos das faces laterais serão linhas retas verticais paralelas entre si, e o hexágono da base será mais aberto quanto mais longe estiver da linha do horizonte. No desenho de um hexágono horizontal, os lados longos das faces laterais convergirão no ponto de fuga no horizonte, e a abertura do hexágono base será maior quanto mais longe estiver do observador. Ao representar um hexágono, certifique-se também de que as arestas paralelas de ambas as bases convergem em perspectiva (Fig. 3.79; 3.80).

Grades hexagonais (grades hexagonais) são usadas em alguns jogos, mas não são tão simples ou comuns quanto as grades retangulares. Tenho coletado recursos em malhas hexadecimais há quase 20 anos e escrevi este guia para as abordagens mais elegantes, implementadas no código mais simples. Este artigo faz uso extensivo dos guias de Charles Fu e Clark Verbrugge. Descreverei as diferentes maneiras de criar malhas hexagonais, seus relacionamentos e os algoritmos mais comuns. Muitas partes deste artigo são interativas: selecionar um tipo de grade altera os diagramas, códigos e textos correspondentes. (Nota por.: isso se aplica apenas ao original, aconselho que o estude. Na tradução, todas as informações do original são preservadas, mas sem interatividade.).

Os exemplos de código no artigo são escritos em pseudocódigo, portanto são mais fáceis de ler e entender para escrever sua própria implementação.

Geometria

Hexágonos são polígonos de seis lados. Os hexágonos regulares têm todos os lados (arestas) do mesmo comprimento. Trabalharemos apenas com hexágonos regulares. Normalmente, as malhas hexagonais usam orientações horizontal (parte superior pontiaguda) e vertical (parte superior plana).


Hexágonos com topos planos (esquerda) e pontiagudos (direita)

Os hexágonos têm 6 faces. Cada face é comum a dois hexágonos. Os hexágonos têm 6 pontos de canto. Cada ponto de canto é comum a três hexágonos. Você pode ler mais sobre centros, arestas e pontos de canto em meu artigo sobre peças de malha (quadrados, hexágonos e triângulos).

Ângulos

Em um hexágono regular, os ângulos internos são 120°. Existem seis "cunhas", cada uma das quais é um triângulo equilátero com ângulos internos de 60°. Ponto de canto eu está localizado a uma distância de (60° * i) + 30°, unidades de tamanho do centro centro. No código:

Função hex_corner (centro, tamanho, i): var ângulo_deg = 60 * i + 30 var ângulo_rad = PI / 180 * ângulo_deg ponto de retorno (centro.x + tamanho * cos (ângulo_rad), centro.y + tamanho * sin (ângulo_rad) )
Para preencher um hexágono, você precisa obter os vértices do polígono de hex_corner(…, 0) para hex_corner(…, 5) . Para desenhar o contorno do hexágono, você precisa usar esses vértices e depois desenhar a linha novamente em hex_corner(..., 0) .

A diferença entre as duas orientações é que x e y são trocados, resultando em uma mudança nos ângulos: hexágonos de topo plano têm ângulos de 0°, 60°, 120°, 180°, 240°, 300° e topo pontiagudo hexágonos têm ângulos de 30°, 90°, 150°, 210°, 270°, 330°.


Cantos de hexágonos com topos planos e pontiagudos

Tamanho e localização

Agora queremos colocar vários hexágonos juntos. Na orientação horizontal, a altura do hexágono é height = size * 2 . A distância vertical entre hexágonos adjacentes é vert = altura * 3/4.

Largura do hexágono largura = sqrt(3)/2 * altura . A distância horizontal entre hexágonos adjacentes é horiz = largura.

Alguns jogos usam pixel art para hexágonos, o que não corresponde exatamente aos hexágonos regulares. As fórmulas de ângulo e posicionamento descritas nesta seção não corresponderão às dimensões de tais hexágonos. O restante do artigo que descreve algoritmos de malha hexadecimal se aplica mesmo se os hexágonos estiverem ligeiramente esticados ou comprimidos.



Sistemas coordenados

Vamos começar a montar os hexágonos em uma grade. No caso de grades de quadrados, só existe uma forma óbvia de montagem. Para hexágonos, existem muitas abordagens. Eu recomendo usar coordenadas cúbicas como sua representação principal. Coordenadas axiais ou coordenadas de deslocamento devem ser usadas para armazenar mapas e exibir coordenadas ao usuário.

Coordenadas de deslocamento

A abordagem mais comum é compensar cada coluna ou linha subsequente. As colunas são designadas col ou q. As linhas são denotadas por row ou r . Você pode compensar colunas/linhas ímpares ou pares, de modo que hexágonos horizontais e verticais tenham duas opções cada.


Arranjo horizontal "ímpar-r"


Arranjo horizontal “par-r”


Arranjo vertical "ímpar-q"


Arranjo vertical “par-q”

Coordenadas cúbicas

Outra maneira de observar grades hexagonais é vê-las como três eixos principais, não dois, como em grades de quadrados. Eles exibem uma simetria elegante.

Vamos pegar uma grade de cubos e vamos cortar isso plano diagonal em x + y + z = 0. Esta é uma ideia estranha, mas nos ajudará a simplificar os algoritmos de malha hexagonal. Em particular, poderemos utilizar operações padrão de coordenadas cartesianas: soma e subtração de coordenadas, multiplicação e divisão por uma quantidade escalar, bem como distâncias.

Observe os três eixos principais na grade de cubos e sua relação com os seis diagonal direções da grade hexagonal. Os eixos diagonais da grade correspondem à direção principal da grade hexagonal.


Hexágonos


cubos

Como já temos algoritmos para malhas quadradas e cúbicas, o uso de coordenadas cúbicas nos permite adaptar esses algoritmos para malhas hexagonais. Usarei esse sistema para a maioria dos algoritmos do artigo. Para usar os algoritmos com um sistema de coordenadas diferente, eu converto as coordenadas cúbicas, executo o algoritmo e depois as converto novamente.

Aprenda como as coordenadas cúbicas funcionam para uma malha hexagonal. Ao selecionar hexágonos, as coordenadas cúbicas correspondentes aos três eixos são destacadas.

  1. Cada direção da grade do cubo corresponde a linhas em uma grade de hexágonos. Tente selecionar um hexágono com z igual a 0, 1, 2, 3 para ver a conexão. A linha está marcada em azul. Tente o mesmo para x (verde) e y (roxo).
  2. Cada direção da grade hexagonal é uma combinação de duas direções da grade cúbica. Por exemplo, o "norte" de uma grade hexagonal fica entre +y e -z , então cada passo do "norte" aumenta y em 1 e diminui z em 1.
As coordenadas cúbicas são uma escolha razoável para um sistema de coordenadas de grade hexagonal. A condição é x + y + z = 0, portanto deve ser preservada nos algoritmos. A condição também garante que sempre haverá uma coordenada canônica para cada hexágono.

Existem muitos sistemas de coordenadas diferentes para cubos e hexágonos. Em alguns deles a condição é diferente de x + y + z = 0. Mostrei apenas um dos muitos sistemas. Você também pode criar coordenadas cúbicas com x-y , y-z , z-x , que possuem seu próprio conjunto de propriedades interessantes, mas não irei abordá-las aqui.

Mas você poderia argumentar que não deseja armazenar três números para as coordenadas porque não sabe como armazenar o mapa dessa forma.

Coordenadas axiais

Um sistema de coordenadas axiais, às vezes chamado de sistema de coordenadas "trapezoidal", é construído a partir de duas ou três coordenadas de um sistema de coordenadas cúbico. Como temos a condição x + y + z = 0, a terceira coordenada não é necessária. As coordenadas axiais são úteis para armazenar mapas e exibir coordenadas ao usuário. Tal como acontece com as coordenadas cúbicas, você pode usar as operações padrão de adição, subtração, multiplicação e divisão de coordenadas cartesianas.

Existem muitos sistemas de coordenadas cúbicas e muitos axiais. Não cobrirei todas as combinações neste guia. Selecionarei duas variáveis, q (coluna) e r (linha). Nos diagramas deste artigo, q corresponde a x e r corresponde a z, mas esta correspondência é arbitrária porque você pode girar e girar os diagramas para obter diferentes correspondências.

A vantagem deste sistema sobre as grades de deslocamento é que os algoritmos são mais compreensíveis. A desvantagem do sistema é que armazenar um cartão retangular é um pouco estranho; veja a seção sobre como salvar mapas. Alguns algoritmos são ainda mais claros em coordenadas cúbicas, mas como temos a condição x + y + z = 0, podemos calcular a terceira coordenada implícita e utilizá-la nestes algoritmos. Em meus projetos eu chamo os eixos de q, r, s, então a condição se parece com q + r + s = 0, e posso calcular s = -q - r quando necessário.

Eixos

As coordenadas de deslocamento são a primeira coisa em que a maioria das pessoas pensa porque são iguais às coordenadas cartesianas padrão usadas para grades quadradas. Infelizmente, um dos dois eixos deve ir na contramão e isso acaba complicando as coisas. Os sistemas de cubo e eixo vão longe e possuem algoritmos mais simples, mas o armazenamento em cartão é um pouco mais complexo. Existe outro sistema denominado “alternado” ou “dual”, mas não o consideraremos aqui; alguns acham mais fácil trabalhar do que cúbico ou axial.


Coordenadas de deslocamento, cúbicas e axiais

Eixoé a direção na qual a coordenada correspondente está aumentando. Perpendicular a um eixo é a linha na qual a coordenada permanece constante. Os diagramas de grade acima mostram linhas perpendiculares.

Transformação de coordenadas

É provável que você use coordenadas axiais ou de deslocamento em seu projeto, mas muitos algoritmos são mais facilmente expressos em coordenadas cúbicas. Portanto, precisamos ser capazes de converter coordenadas entre sistemas.

As coordenadas axiais estão intimamente relacionadas às coordenadas cúbicas, portanto a conversão é simples:

# converte coordenadas cúbicas em axiais q = x r = z # converte coordenadas axiais em cúbicas x = q z = r y = -x-z
No código, essas duas funções podem ser escritas da seguinte forma:

Função cube_to_hex (h): # axial var q = h.x var r = h.z return Hex (q, r) função hex_to_cube (h): # cube var x = h.q var z = h.r var y = -x-z return Cube (x, y ,z)
As coordenadas de deslocamento são um pouco mais complicadas:

Hexágonos adjacentes

Dado um hexágono, a que seis hexágonos ele está próximo? Como seria de esperar, a resposta é mais fácil em coordenadas cúbicas, bastante fácil em coordenadas axiais e um pouco mais difícil em coordenadas de deslocamento. Você também pode precisar calcular seis hexágonos “diagonais”.

Coordenadas cúbicas

Mover um espaço em coordenadas hexadecimais faz com que uma das três coordenadas cúbicas mude para +1 e a outra para -1 (a soma deve permanecer 0). Em +1, três coordenadas possíveis podem mudar, e em -1, as duas restantes. Isso nos dá seis mudanças possíveis. Cada um corresponde a uma das direções do hexágono. A maneira mais simples e rápida é pré-calcular as alterações e colocá-las em uma tabela de coordenadas cúbicas Cube(dx, dy, dz) em tempo de compilação:

Direções Var = [Cubo(+1, -1, 0), Cubo(+1, 0, -1), Cubo(0, +1, -1), Cubo(-1, +1, 0), Cubo( -1, 0, +1), Cubo (0, -1, +1)] função cube_direction (direção): retornar direções função cube_neighbor (hex, direção): retornar cube_add (hex, cube_direction (direção))

Coordenadas axiais

Como antes, usamos o sistema cúbico para começar. Vamos pegar a tabela Cube(dx, dy, dz) e transformá-la na tabela Hex(dq, dr):

Direções Var = [Hex(+1, 0), Hex(+1, -1), Hex(0, -1), Hex(-1, 0), Hex(-1, +1), Hex(0, +1)] função hex_direction (direção): retornar direções função hex_neighbor (hex, direção): var dir = hex_direction (direção) retornar Hex (hex.q + dir.q, hex.r + dir.r)

Coordenadas de deslocamento

Nas coordenadas axiais, fazemos alterações dependendo de onde estamos na grade. Se estivermos em uma coluna/linha deslocada, a regra será diferente do caso de uma coluna/linha sem deslocamento.

Como antes, criamos uma tabela de números que precisam ser adicionados a col e row . Porém, desta vez teremos dois arrays, um para as colunas/linhas ímpares e outro para as pares. Observe (1,1) na imagem do mapa de grade acima e observe como a coluna e a linha mudam conforme você se move em cada uma das seis direções. Agora vamos repetir o processo para (2,2) . As tabelas e o código serão diferentes para cada um dos quatro tipos de grades de deslocamento; aqui está o código correspondente para cada tipo de grade.

Ímpar-r
var direções = [ [ Hex(+1, 0), Hex(0, -1), Hex(-1, -1), Hex(-1, 0), Hex(-1, +1), Hex(0 , +1) ], [ Hex(+1, 0), Hex(+1, -1), Hex(0, -1), Hex(-1, 0), Hex(0, +1), Hex( +1, +1) ] ] função offset_neighbor (hex, direção): var paridade = hex.row & 1 var dir = direções retornar Hex (hex.col + dir.col, hex.row + dir.row)


Par-r
var direções = [ [ Hex(+1, 0), Hex(+1, -1), Hex(0, -1), Hex(-1, 0), Hex(0, +1), Hex(+1 , +1) ], [ Hex(+1, 0), Hex(0, -1), Hex(-1, -1), Hex(-1, 0), Hex(-1, +1), Hex (0, +1) ] ] função offset_neighbor (hex, direção): var paridade = hex.row & 1 var dir = direções retornar Hex (hex.col + dir.col, hex.row + dir.row)


Grade para linhas pares (PAR) e ímpares (ÍMPAR)

Ímpar-q
var direções = [ [ Hex(+1, 0), Hex(+1, -1), Hex(0, -1), Hex(-1, -1), Hex(-1, 0), Hex(0) , +1) ], [ Hex(+1, +1), Hex(+1, 0), Hex(0, -1), Hex(-1, 0), Hex(-1, +1), Hex (0, +1) ] ] função offset_neighbor (hex, direção): var paridade = hex.col & 1 var dir = direções retornar Hex (hex.col + dir.col, hex.row + dir.row)


Par-q
var direções = [ [ Hex(+1, +1), Hex(+1, 0), Hex(0, -1), Hex(-1, 0), Hex(-1, +1), Hex(0 , +1) ], [ Hex(+1, 0), Hex(+1, -1), Hex(0, -1), Hex(-1, -1), Hex(-1, 0), Hex (0, +1) ] ] função offset_neighbor (hex, direção): var paridade = hex.col & 1 var dir = direções retornar Hex (hex.col + dir.col, hex.row + dir.row)


Grade para colunas pares (PAR) e ímpares (ÍMPAR)

Diagonais

Mover-se no espaço "diagonal" em coordenadas hexadecimais altera uma das três coordenadas cúbicas em ±2 e as outras duas em ∓1 (a soma deve permanecer 0).

Var diagonais = [Cubo(+2, -1, -1), Cubo(+1, +1, -2), Cubo(-1, +2, -1), Cubo(-2, +1, +1 ), Cubo (-1, -1, +2), Cubo (+1, -2, +1)] função cube_diagonal_neighbor (hex, direção): retornar cube_add (hex, diagonais)
Como antes, podemos converter essas coordenadas em coordenadas axiais eliminando uma das três coordenadas, ou convertê-las em coordenadas de deslocamento calculando primeiro os resultados.


Distâncias

Coordenadas cúbicas

No sistema de coordenadas cúbicas, cada hexágono é um cubo no espaço tridimensional. Hexágonos adjacentes são espaçados em 1 na grade hexagonal, mas espaçados em 2 na grade cúbica. Isso simplifica o cálculo de distâncias. Em uma grade de quadrados, as distâncias de Manhattan são abs(dx) + abs(dy) . Em uma grade de cubos, as distâncias de Manhattan são abs(dx) + abs(dy) + abs(dz) . A distância na grade hexagonal é igual à metade deles:

Função cube_distance(a, b): return (abs(a.x - b.x) + abs(a.y - b.y) + abs(a.z - b.z)) / 2
O equivalente a esta notação seria dizer que uma das três coordenadas deve ser a soma das outras duas, e então considerar isso como a distância. Você pode escolher a forma de redução pela metade ou a forma de valor máximo abaixo, mas elas dão o mesmo resultado:

Função cube_distance(a, b): return max(abs(a.x - b.x), abs(a.y - b.y), abs(a.z - b.z))
Na figura, os valores máximos estão destacados em cores. Observe também que cada cor representa uma das seis direções “diagonais”.

GIFs


Coordenadas axiais

No sistema axial, a terceira coordenada é expressa implicitamente. Vamos converter de axial para cúbico para calcular a distância:

Função hex_distance(a, b): var ac = hex_to_cube(a) var bc = hex_to_cube(b) return cube_distance(ac, bc)
Se o compilador estiver embutido (inline) hex_to_cube e cube_distance no seu caso, ele irá gerar um código como este:

Função hex_distance(a, b): return (abs(a.q - b.q) + abs(a.q + a.r - b.q - b.r) + abs(a.r - b.r)) / 2
Existem muitas maneiras diferentes de escrever as distâncias entre hexágonos em coordenadas axiais, mas independentemente do método de escrita a distância entre hexágonos no sistema axial é extraída da distância de Manhattan no sistema cúbico. Por exemplo, a "diferença de diferenças" descrita é obtida escrevendo a.q + a.r - b.q - b.r como a.q - b.q + a.r - b.r e usando a forma de valor máximo em vez da forma de bissecção cube_distance . Eles são todos semelhantes se você observar a conexão com coordenadas cúbicas.

Coordenadas de deslocamento

Tal como acontece com as coordenadas axiais, convertemos as coordenadas de deslocamento em coordenadas cúbicas e depois usamos a distância cúbica.

Função offset_distance(a, b): var ac = offset_to_cube(a) var bc = offset_to_cube(b) return cube_distance(ac, bc)
Usaremos o mesmo padrão para muitos dos algoritmos: converter hexágonos em cubos, executar a versão cúbica do algoritmo e converter os resultados cúbicos em coordenadas hexágonos (coordenadas axiais ou de deslocamento).

Desenhando linhas

Como traçar uma linha de um hexágono a outro? Estou usando interpolação linear para desenhar linhas. A linha é amostrada uniformemente em N+1 pontos e é calculado em quais hexágonos essas amostras estão.

GIFs


  1. Primeiro calculamos N, que será a distância em hexágonos entre os pontos finais.
  2. Em seguida, amostramos N+1 pontos uniformemente entre os pontos A e B. Usando interpolação linear, determinamos que para valores de i de 0 a N incluindo-os, cada ponto será A + (B - A) * 1,0/N * eu . Na figura, esses pontos de controle são mostrados em azul. O resultado são coordenadas de ponto flutuante.
  3. Vamos converter cada ponto de controle (float) novamente em hexágonos (int). O algoritmo é denominado cube_round (veja abaixo).
Junte tudo para traçar uma linha de A a B:

Função lerp(a, b, t): // para float retorna a + (b - a) * t função cube_lerp(a, b, t): // para hexágonos retorna Cube(lerp(a.x, b.x, t), lerp(a.y, by, t), lerp(a.z, b.z, t)) função cube_linedraw(a, b): var N = cube_distance(a, b) var resultados = para cada 0 ≤ i ≤ N: results.append( cube_round(cube_lerp(a, b, 1.0/N * i))) retorna resultados
Notas:

  • Há casos em que cube_lerp retorna um ponto que está exatamente na aresta entre dois hexágonos. Então cube_round move-o em uma direção ou outra. As linhas ficam melhores se forem movidas em uma direção. Isso pode ser feito adicionando um cubo hexagonal "épsilon" (1e-6, 1e-6, -2e-6) a um ou ambos os pontos de extremidade antes de iniciar o loop. Isso irá “empurrar” a linha em uma direção para que ela não atinja as bordas.
  • O algoritmo de linha DDA em grades quadradas iguala N à distância máxima ao longo de cada um dos eixos. Fazemos a mesma coisa no espaço cúbico, que é semelhante à distância numa grelha hexagonal.
  • A função cube_lerp deve retornar um cubo com coordenadas flutuantes. Se você estiver programando em uma linguagem de tipo estaticamente, não poderá usar o tipo Cube. Em vez disso, você pode definir um tipo FloatCube ou incorporar uma função em seu código de desenho de linha se não quiser definir outro tipo.
  • Você pode otimizar o código por cube_lerp embutido e então calcular B.x-A.x , B.x-A.y e 1.0/N fora do loop. A multiplicação pode ser convertida em soma repetida. O resultado será algo como um algoritmo de linha DDA.
  • Eu uso coordenadas axiais ou cúbicas para desenhar linhas, mas se você quiser trabalhar com coordenadas de deslocamento, dê uma olhada.
  • Existem muitas opções para desenhar linhas. Às vezes é necessário "revestir". Recebi um código para desenhar linhas supercobertas em hexágonos, mas ainda não investiguei.

Alcance móvel

Faixa de coordenadas

Dado um centro de hexágono e um alcance N, quais hexágonos estão a N passos dele?

Podemos fazer o inverso da fórmula da distância entre hexágonos distance = max(abs(dx), abs(dy), abs(dz)) . Para encontrar todos os hexágonos dentro de N precisamos de max(abs(dx), abs(dy), abs(dz)) ≤ N . Isso significa que todos os três valores são necessários: abs(dx) ≤ N e abs(dy) ≤ N e abs(dz) ≤ N . Removendo o valor absoluto, obtemos -N ≤ dx ≤ N e -N ≤ dy ≤ N e -N ≤ dz ≤ N . No código, este será um loop aninhado:

Resultados Var = para cada -N ≤ dx ≤ N: para cada -N ≤ dy ≤ N: para cada -N ≤ dz ≤ N: se dx + dy + dz = 0: results.append(cube_add(center, Cube(dx , dy, dz)))
Este ciclo funcionará, mas será bastante ineficaz. De todos os valores dz pelos quais percorremos, apenas um realmente satisfaz a condição do cubo dx + dy + dz = 0. Em vez disso, calcularemos diretamente o valor de dz satisfazendo a condição:

Resultados Var = para cada -N ≤ dx ≤ N: para cada max(-N, -dx-N) ≤ dy ≤ min(N, -dx+N): var dz = -dx-dy results.append(cube_add( centro, Cubo(dx, dy, dz)))
Este ciclo passa apenas ao longo das coordenadas necessárias. Na figura, cada intervalo é um par de linhas. Cada linha é uma desigualdade. Tomamos todos os hexágonos que satisfazem as seis desigualdades.

GIFs


Intervalos sobrepostos

Se precisar encontrar hexágonos que estejam em vários intervalos, você poderá cruzar os intervalos antes de gerar uma lista de hexágonos.

Você pode abordar esse problema do ponto de vista da álgebra ou da geometria. Algebricamente, cada região é expressa como condições de desigualdade da forma -N ≤ dx ≤ N , e precisamos encontrar a intersecção dessas condições. Geometricamente, cada região é um cubo no espaço 3D, e cruzaremos dois cubos no espaço 3D para obter um cubóide no espaço 3D. Em seguida, projetamos de volta no plano x + y + z = 0 para obter hexágonos. Vou resolver esse problema algebricamente.

Primeiro, reescrevemos a condição -N ≤ dx ≤ N na forma mais geral x min ≤ x ≤ x max e tomamos x min = center.x - N e x max = center.x + N . Vamos fazer o mesmo para y e z, resultando na forma geral do código da seção anterior:

Resultados Var = para cada xmin ≤ x ≤ xmax: para cada max(ymin, -x-zmax) ≤ y ≤ min(ymax, -x-zmin): var z = -x-y results.append(Cube(x, y, z))
A interseção de dois intervalos a ≤ x ≤ b e c ≤ x ≤ d é max(a, c) ≤ x ≤ min(b, d) . Como a área dos hexágonos é expressa como intervalos sobre x, y, z, podemos cruzar cada um dos intervalos x, y, z separadamente e então usar um loop aninhado para gerar uma lista de hexágonos na interseção. Para uma área de hexágonos, tomamos x min = H.x - N e x max = H.x + N , da mesma forma para y e z . Para a intersecção de duas regiões hexagonais, tomamos x min = max(H1.x - N, H2.x - N) e x max = min(H1.x + N, H2.x + N), da mesma forma para y e z. O mesmo padrão funciona para a intersecção de três ou mais áreas.

GIFs


Obstáculos

Se houver obstáculos, a maneira mais fácil é preencher uma limitação de distância (pesquisa em largura). Na figura abaixo nos limitamos a quatro movimentos. No código, franjas[k] é uma matriz de todos os hexágonos que podem ser alcançados em k etapas. Cada vez que passamos pelo loop principal, expandimos o nível k-1 em nível k.

Função cube_reachable(início, movimento): var visitado = set() adiciona início ao visitado var fringes = fringes.append() para cada 1< k ≤ movement: fringes.append() for each cube in fringes: for each 0 ≤ dir < 6: var neighbor = cube_neighbor(cube, dir) if neighbor not in visited, not blocked: add neighbor to visited fringes[k].append(neighbor) return visited

Voltas

Dado um vetor hexágono (a diferença entre dois hexágonos), podemos precisar girá-lo para que aponte para outro hexágono. Isso é fácil de fazer com coordenadas cúbicas se você seguir uma rotação de 1/6 do círculo.

Uma rotação de 60° para a direita move cada coordenada uma posição para a direita:

[x, y, z] para [-z, -x, -y]
Uma rotação de 60° para a esquerda move cada coordenada uma posição para a esquerda:

[x, y, z] para [-y, -z, -x]



“Tendo brincado” [no artigo original] com o diagrama, você pode ver que cada rotação é de 60° mudanças sinais e “gira” fisicamente as coordenadas. Após uma rotação de 120°, os sinais voltam a ser os mesmos. Uma rotação de 180° muda de sinal, mas as coordenadas retornam à sua posição original.

Aqui está a sequência completa de rotação da posição P em torno da posição central C, resultando em uma nova posição R:

  1. Converta as posições P e C em coordenadas cúbicas.
  2. Calculando um vetor subtraindo o centro: P_from_C = P - C = Cube(P.x - C.x, P.y - C.y, P.z - C.z) .
  3. Gire o vetor P_from_C conforme descrito acima e atribua ao vetor final a designação R_from_C .
  4. Convertendo o vetor de volta à posição adicionando o centro: R = R_from_C + C = Cube(R_from_C.x + C.x, R_from_C.y + C.y, R_from_C.z + C.z) .
  5. Converte a posição cúbica R de volta para o sistema de coordenadas desejado.
Existem vários estágios de transformação, mas cada um deles é bastante simples. É possível encurtar algumas dessas etapas definindo a rotação diretamente em coordenadas axiais, mas vetores hexadecimais não funcionam com coordenadas de deslocamento e não sei como encurtar as etapas para coordenadas de deslocamento. Veja também a discussão sobre stackexchange para outras maneiras de calcular a rotação.

argolas

Anel simples

Para descobrir se um determinado hexágono pertence a um anel com um determinado raio, você precisa calcular a distância desse hexágono ao centro e descobrir se é igual ao raio. Para obter uma lista de todos esses hexágonos, você precisa dar passos de raio a partir do centro e, em seguida, seguir os vetores girados ao longo do caminho ao longo do anel.

Função cube_ring(center, radius): var results = # este código não funciona para radius == 0; você entende por quê? var cube = cube_add(center, cube_scale(cube_direction(4), radius)) para cada 0 ≤ i< 6: for each 0 ≤ j < radius: results.append(cube) cube = cube_neighbor(cube, i) return results
Neste código, o cubo começa em um anel, mostrado com uma seta grande do centro para o canto do diagrama. Escolhi o ângulo 4 para começar porque corresponde ao caminho em que meus números de direção estão se movendo. Você pode precisar de um ângulo inicial diferente. Em cada estágio do loop interno, o cubo move um hexágono ao redor do anel. Após 6 * passos de raio, ele termina onde começou.


Anéis espirais

Percorrendo os anéis em espiral, podemos preencher as partes internas dos anéis:

Função cube_spiral (centro, raio): var resultados = para cada 1 ≤ k ≤ raio: resultados = resultados + cube_ring (centro, k) retorna resultados



A área de um grande hexágono é a soma de todos os círculos mais 1 para o centro. Use esta fórmula para calcular a área.

Atravessar hexágonos desta forma também pode ser usado para calcular a amplitude de movimento (veja acima).

Área de visibilidade

O que é visível de uma determinada posição a uma determinada distância e não está bloqueado por obstáculos? A maneira mais simples de determinar isso é traçar uma linha para cada hexágono em um determinado intervalo. Se a linha não atingir as paredes, você verá um hexágono. Mova o mouse sobre os hexágonos [no diagrama do artigo original] para ver como as linhas são desenhadas para esses hexágonos e as paredes onde as linhas se encontram.

Esse algoritmo pode ser lento em grandes áreas, mas é fácil de implementar, por isso recomendo começar com ele.

GIFs



Existem muitas definições diferentes de visibilidade. Quer ver o centro de outro hexágono a partir do centro do hexágono original? Quer ver alguma parte de outro hexágono a partir do centro do hexágono original? Talvez qualquer parte de outro hexágono de qualquer ponto do hexágono inicial? Os obstáculos que obstruem sua visão são menores que um hexágono completo? O escopo é um conceito mais complicado e variado do que parece à primeira vista. Vamos começar com o algoritmo mais simples, mas espere que ele calcule corretamente a resposta em seu projeto. Há até casos em que um algoritmo simples produz resultados ilógicos.

Quero expandir este guia no futuro. Eu tenho