Estou criando um jogo 2D para um site onde o universo pode crescer extremamente grande (basicamente infinitamente grande). Inicialmente, o universo é composto por 6 estrelas que estão a uma distância igual da origem (0, 0). Minha tarefa é ser capaz de gerar mais estrelas que terão "caminhos" (arestas) que se conectam. Como criar um algoritmo que atenda a essas restrições:
- Estrelas são geradas aleatoriamente para fora. (por exemplo, coordenadas (x, y) para novas estrelas vão lentamente para fora de (0, 0) em todas as direções, de preferência em formato espiral)
- As arestas NÃO se cruzam.
- Embora deva haver alguma variação, novas estrelas não devem estar muito longe ou muito próximas de outras estrelas. (Por exemplo, deve haver um raio mínimo)
- Nenhuma estrela / ponto deve ter uma multiplicidade superior a 3.
- Dado que tudo isso será armazenado em um banco de dados, o algoritmo não pode ser muito caro. Em outras palavras, eu adoraria alcançar algo de O (n) complexidade (não sei se isso é viável).
Essencialmente, o que estou procurando é uma galáxia de aparência espiral, onde as estrelas são pontos no gráfico e as viagens entre as estrelas são representadas por bordas entre essas estrelas.
As etapas específicas que preciso resolver são:
- Gere aleatoriamente um ponto na vizinhança de outras estrelas que ainda não tenham uma multiplicidade de 3.
- Encontre a primeira estrela que ainda não possui uma multiplicidade de 3 que não gera conflito de arestas.
- Se a estrela estiver a uma distância mínima de x unidades de distância, crie uma aresta entre os dois pontos.
Tentei procurar soluções, mas minhas habilidades matemáticas (e conhecimentos sobre teoria dos grafos) precisam de muito trabalho. Além disso, quaisquer recursos / links sobre esse assunto seriam muito apreciados.
Aqui está um pseudocódigo que eu estava pensando, mas não tenho certeza se isso funcionaria e tenho certeza de que não teria um desempenho muito bom depois de algumas 10.000 estrelas etc.
newStar = randomly generated (x, y) within radius of last star from origin
while(newStar has not been connected):
for (star in the known universe):
if(distance between newStar and star > x units):
if(star has < 3 multiplicity):
if(path from newStar to star does not intersect another path):
connect the star to the other star
break;
newStar = new random (x, y) coordinate
Além disso, se alguém tiver algum conselho sobre como eu devo armazenar isso em um banco de dados MySQL, também agradeceria.
Finalmente, caso nada faça sentido acima, incluí uma imagem do que gostaria de alcançar abaixo:
fonte
Respostas:
Sugestão: Mantenha a rede do universo interno perfeitamente ordenada, algorítmica e relativamente simples. Você só precisa que o universo pareça aleatório quando exibido na tela do usuário . Aplique apenas deslocamentos aleatórios nas posições em estrela para exibição do usuário.
Problema: A abordagem mais óbvia do cálculo de um deslocamento aleatório para cada estrela não fará um trabalho muito bom de ocultar a estrutura verdadeira subjacente. Você só pode randomizar estrelas em uma pequena quantidade antes que elas corram o risco de colidir umas com as outras ou cruzar caminhos.
Solução: Você pode aplicar grandes distorções aleatórias e obter um universo muito mais aleatório e interessante se aplicar aleatoriedade não local coordenada. Imagine colocar as estrelas em uma folha de borracha e imagine esticar e esmagar aleatoriamente diferentes partes da folha. Isso pode mudar um grupo inteiro de estrelas por uma longa distância. Eles nunca colidirão ou cruzarão porque estrelas próximas se esticam e se espremem em relação umas às outras.
Como fazer: Procure geradores de terreno fractal. Há muitos códigos gratuitos e abertos para isso. Você só precisa de um código básico que gere um valor de altura para cada ponto em um mapa. Nós vamos usá-lo de uma maneira diferente. Use esse código para gerar DOIS mapas independentes de altura do terreno. Comece com a verdadeira posição X, Y da estrela, observe o local em cada mapa, use um valor do mapa para compensar a posição de exibição X da estrela e use o outro valor do mapa para compensar a posição de exibição Y da estrela. Você terá que jogar com alguns dos fatores de escala, mas isso pode lhe dar o efeito de folha de borracha deformada aleatoriamente. As grandes variações na posição da estrela devem ocultar completamente as posições ordenadas subjacentes. A natureza fractal da aleatoriedade dará um efeito de aparência muito natural,
fonte