Algoritmo para gerar arestas e vértices a partir da origem com multiplicidade máxima de 3


11

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:

  1. 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)
  2. As arestas NÃO se cruzam.
  3. 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)
  4. Nenhuma estrela / ponto deve ter uma multiplicidade superior a 3.
  5. 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:

  1. Gere aleatoriamente um ponto na vizinhança de outras estrelas que ainda não tenham uma multiplicidade de 3.
  2. Encontre a primeira estrela que ainda não possui uma multiplicidade de 3 que não gera conflito de arestas.
  3. 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:e etc, muitas estrelas ...


1
Um viajante deste universo provavelmente se moveria em uma direção, ou seja, se você ficar sem estrelas, teria que gerar estrelas em todas as direções desde a origem. Um usuário entediado pode quebrar seu banco de dados, em outras palavras. Você já considerou essa possibilidade (supondo que possa ser um problema)?
Neil

2
Também outro pensamento, a colocação das estrelas não precisa ser lembrada. Se você usar uma geração reproduzível de estrelas, poderá gerar as estrelas que o usuário poderá ver de forma que essas estrelas sejam geradas da mesma maneira no futuro. Ou seja, seu banco de dados só precisa salvar informações sobre estrelas. Sua posição é sua identidade.
Neil

1
O que você fará se cada estrela gerada tiver exatamente uma multiplicidade de 3, para que a etapa 1 falhe? Por que na sua imagem um ponto com uma multiplicidade de 4, isso é um erro?
Doc Brown

1
Não. Se você pode gerar estrelas de maneira previsível, será como se elas sempre estivessem lá se você sair e voltar. É apenas o algoritmo e a semente que não mudam.
Neil

2
@JF Nãoo céu de ninguém . O cara literalmente gera um universo. Ele salva apenas planetas que foram visitados por jogadores, e ainda assim os planetas existentes permanecem em seus mesmos lugares. Tudo se baseia no uso da semente adequada usada para gerar números aleatórios.
Neil

Respostas:


2

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,

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.