Algoritmo para generar bordes y vértices hacia afuera desde el origen con una multiplicidad máxima de 3

11

Estoy creando un juego 2D para un sitio web donde el universo puede crecer extremadamente grande (básicamente infinitamente grande). Inicialmente, el universo está compuesto de 6 estrellas que están a la misma distancia del origen (0, 0). Mi tarea es poder generar más estrellas que tengan "caminos" (bordes) que se conecten entre sí. ¿Cómo puedo diseñar un algoritmo que cumpla con estas restricciones?

  1. Las estrellas se generan aleatoriamente hacia afuera. (por ejemplo, las coordenadas (x, y) para las nuevas estrellas irán lentamente hacia afuera desde (0, 0) en todas las direcciones, preferiblemente en formato espiral)
  2. Los bordes NO se cruzarán.
  3. Aunque debería haber alguna variación, las nuevas estrellas no deberían estar demasiado lejos o demasiado cerca de otras estrellas. (Por ejemplo, debe haber un radio mínimo)
  4. Ninguna estrella / punto debe tener una multiplicidad de más de 3.
  5. Dado que todo esto se almacenará en una base de datos, el algoritmo no puede ser demasiado costoso. En otras palabras, me encantaría lograr algo de complejidad O (n) (no sé si esto es factible).

Esencialmente, lo que estoy buscando es una galaxia de aspecto espiral donde las estrellas son puntos en el gráfico y el viaje entre estrellas está representado por bordes entre esas estrellas.

Los pasos particulares que necesito resolver son:

  1. Genera aleatoriamente un punto en la vecindad vecina de otras estrellas que aún no tienen una multiplicidad de 3.
  2. Encuentra la primera estrella que aún no tiene una multiplicidad de 3 que no generará conflicto de borde.
  3. Si la estrella está a una distancia mínima de x unidades de distancia, cree un borde entre los dos puntos.

Traté de buscar soluciones, pero mis habilidades matemáticas (y conocimiento en teoría de gráficos) necesitan mucho trabajo. Además, cualquier recurso / enlace sobre este asunto sería muy apreciado.

Aquí hay un pseudocódigo en el que estaba pensando, pero no estoy seguro de si esto incluso funcionaría y estoy seguro de que no funcionaría terriblemente bien después de unas 10,000 estrellas, 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

Además, si alguien tiene algún consejo sobre cómo debo almacenar esto en una base de datos MySQL, también agradecería eso.

Finalmente, en caso de que nada tenga sentido arriba, he incluido una imagen de lo que me gustaría lograr a continuación:y etc, muchas estrellas ...

John F.
fuente
1
Un viajero de este universo probablemente se movería en una dirección, lo que significa que si te quedas sin estrellas, deberías generar estrellas en todas las direcciones desde el origen. Un usuario aburrido podría romper su base de datos, en otras palabras. ¿Ha considerado esta posibilidad (suponiendo que pueda ser un problema)?
Neil
2
También otro pensamiento, la colocación de las estrellas no necesita ser recordada. Si utiliza una generación reproducible de estrellas, podría generar las estrellas que el usuario podría ver de tal manera que esas estrellas se generarán de la misma manera en el futuro. Es decir, su base de datos solo necesita guardar información sobre las estrellas. Su posición es su identidad.
Neil
1
¿Qué harás si cada estrella generada tiene exactamente una multiplicidad de 3, por lo que el paso 1 fallará? ¿Por qué en su imagen hay un punto con una multiplicidad de 4, es un error?
Doc Brown
1
No. Si puedes generar estrellas de una manera predecible, será como si siempre hubieran estado allí si te vas y luego regresas. Es solo el algoritmo y la semilla lo que no cambia.
Neil
2
@JF See No Man's Sky . El chico literalmente genera un universo. Solo salva los planetas que han sido visitados por los jugadores y, sin embargo, los planetas existentes permanecen en sus mismos lugares respectivos. Todo se basa en el uso de la semilla adecuada utilizada para generar números aleatorios.
Neil

Respuestas:

2

Sugerencia: Mantenga la red del universo interno perfectamente ordenada, algorítmica y relativamente simple. Solo necesita que el universo se vea aleatorio cuando se muestra en la pantalla del usuario . Solo aplique compensaciones aleatorias a las posiciones de estrella para la visualización del usuario.

Problema: el enfoque más obvio de calcular un desplazamiento aleatorio para cada estrella no hará un muy buen trabajo al ocultar la verdadera estructura subyacente. Solo puedes aleatorizar las estrellas en una pequeña cantidad antes de que corran el riesgo de chocar entre sí o cruzarse.

Solución: puede aplicar grandes distorsiones aleatorias y obtener un universo mucho más aleatorio e interesante si aplica aleatoriedad coordinada no local. Imagine colocar las estrellas en una lámina de goma e imagine estirar y aplastar al azar diferentes partes de la lámina. Eso puede desplazar grupos enteros de estrellas a larga distancia. Nunca chocarán ni se cruzarán porque las estrellas cercanas se estiran y aplastan en relación entre sí.

Cómo hacerlo: busca generadores de terreno fractal. Hay un montón de código libre y abierto para ello. Solo necesita un código básico que genere un valor de altura para cada punto en un mapa. Vamos a usarlo de una manera diferente. Use ese código para generar DOS mapas independientes de altura del terreno. Comience con la verdadera posición X, Y de la estrella, mire esa ubicación en cada mapa, use un valor de mapa para compensar la posición de visualización X de la estrella y use el otro valor del mapa para compensar la posición de visualización Y de la estrella. Tendrás que jugar con algunos de los factores de escala, pero eso puede darte el efecto de lámina de goma deformado al azar. Las grandes variaciones en la posición de la estrella deberían ocultar completamente las posiciones ordenadas subyacentes. La naturaleza fractal de la aleatoriedad dará un efecto muy natural,

Alsee
fuente