¿Cómo generar una red de calles de la ciudad?

16

Me gustaría crear un generador de ciudad para un juego, pero estoy enfrentando un problema al comienzo de la generación: el sistema de carreteras.

Como es un mundo medieval, no quiero un plan de red como muchas ciudades modernas. Idealmente, preferiría una generación seudoaleatoria de grandes avenidas y calles más pequeñas, donde podría perderse, pero con algo de lógica, no un laberinto completo.
Algo que se vería como una ciudad naturalmente cultivada.

Para simplificarlo, digamos que mis ciudades estarían en terrenos planos y estables, sin problemas de cruce o alivio del río. Podría intentar integrarlo a una solución después.

No decidí un tamaño o disposición precisos para mis ciudades, por lo que si tiene una solución que funcione solo con ciudades de forma precisa (cuadrado, círculo, rectángulo, etc.), la tomaría.

Aracthor
fuente
2
Es posible que desee ver el generador de ciudad procesal por software de introversión que hicieron para Subversion. Si bien el juego en sí se canceló, hay muchas imágenes de su generador.
Philipp
¿Tienes un ejemplo de lo que quieres (ejemplo de la vida real de tu período de tiempo objetivo, ejemplo de otro juego, boceto, etc.)? Hay muchas opciones entre 'no es una cuadrícula' y 'no es un laberinto completo'.
Pikalek
@Pikalek No doy más precisión porque no la tengo. No estoy buscando algo muy específico, cualquier ejemplo de generación que no genere ni un laberinto ni un plan de red podría satisfacerme.
Aracthor

Respuestas:

21

Un buen lugar para comenzar con la generación de ciudades procesales es el modelo de ciudades de Parish y Müller . Su documento presenta un Sistema L en el que las reglas relativas a la densidad de población y los patrones de carreteras (cuadrícula rectangular, radial y menor cambio de elevación) se combinan y luego se fijan para acomodar las restricciones locales, como los frentes de agua y la estética de la carretera. Si bien los resultados de este sistema son impresionantes, ha sido criticado por ser innecesariamente complicado . La solución alternativa de Barrett se repite en el blog de desarrollo de Repuestos de Rudzicz de la siguiente manera:

  • mantener una lista de carreteras "propuestas"
  • evaluarlos en algún orden
  • si son aceptables (con o sin algunas modificaciones menores)
  • almacenar cada camino aceptado mientras "propone" un puñado más de ramificaciones

Este enfoque elimina la mayor parte de la herencia de reescritura de símbolos heredada en Parish y el Sistema L de Müller. Puede ver una demostración de este enfoque aquí .

Un beneficio de este enfoque es que es independiente de la forma de la ciudad: puede agregar restricciones de contorno según sea necesario, por lo que la forma de su ciudad puede determinarse según las necesidades de diseño de su juego en lugar del algoritmo. Dependiendo del tamaño de su ciudad, esto podría ser lo suficientemente bueno como es. Aquí hay un resultado de la demostración anterior con un límite de segmento de 100: ingrese la descripción de la imagen aquí Pero si necesita algo grande, puede tener problemas; Aquí hay un resultado con un límite de segmento de 500: ingrese la descripción de la imagen aquí

En parte, puede ajustar esto cambiando las reglas de ramificación de la carretera, evitando ángulos de 90 grados, etc. Si su diseño aún es demasiado regular, aquí está mi corrección:

Transforma tu cuadrícula de ciudad en un gráfico donde cada calle es un borde y cada intersección es un nodo. A continuación, use el algoritmo que prefiera para convertir el gráfico en un laberinto . Aquí está el último ejemplo convertido en un laberinto: ingrese la descripción de la imagen aquí

Ahora la salida tiene el problema opuesto, es demasiado laberinto. Pero ahora podemos aplicar un par de técnicas del funcionamiento secreto del generador de mazmorras de Jamis Buck . Primero, aumente la escasez eliminando algunos pasillos sin salida. A continuación, aumente la conectividad agregando caminos que creen bucles (es decir, introduzcan ciclos en el gráfico). Aquí hay un resultado de ejemplo: ingrese la descripción de la imagen aquí

Nota: es posible lograr el mismo resultado final directamente desde la etapa de diseño orientada a la cuadrícula anterior (antes de generar el laberinto), solo aplicando eliminaciones de bordes a la cuadrícula de la ciudad. El problema con ese enfoque es que debes asegurarte de que eliminar un borde no divida la ciudad y, por lo tanto, no puedas alcanzar partes.

Pikalek
fuente
6

Si busca planes de ciudades medievales / antiguas en Google , encontrará muchas variaciones diferentes, principalmente basadas en los orígenes de la ciudad (por ejemplo, asentamiento aleatorio versus posición militar organizada).

Supongo que estás buscando un asentamiento más natural / caótico.

Para estos, probaría un enfoque como este:

  • Comience con una carretera principal que vaya de un extremo al otro (e idealmente conecte algunos otros asentamientos. Si lo desea, cree un tercer camino para obtener un cruce en el que comenzar su asentamiento.
  • Coloque algunas casas a lo largo del camino (solo en un lado).
  • Ahora amplíe ese camino a lo largo de las casas y agregue un hito importante en el otro lado (generalmente una iglesia, pero esto también podría ser un molino o similar). Este será su centro / mercado.
  • Ahora elija dos posiciones fuera del área con las casas y cree un nuevo camino que encierre las casas.
  • Opcionalmente, cree algunos aliados más pequeños entre las casas que conectan la carretera vieja y la nueva.
  • Ahora repita hasta que esté satisfecho con su "núcleo":
    • Agregue algunas casas más.
    • Agregue otro camino que los encierra.
    • Agregue callejones que conectan las carreteras.
  • Una vez que estés contento con eso, habrás terminado. Si se supone que es una ciudad, ciérrela con muros y repita los últimos pasos varias veces más, agregando casas adicionales fuera de los muros.
Mario
fuente
3

En primer lugar, hay muchísimas maneras de hacer la generación de procedimientos y ninguna de ellas es fácil en absoluto, haré una especie de enfoque sobre cómo podría hacer que funcione, depende de usted tomarlo, modificarlo o descartarlo.

Pseudocódigo en JS ya que es más fácil de entender.

1º defina un punto de entrada, ya que desea construir una ciudad medieval comenzaremos con un cuadrado, así que digamos que su ciudad tendrá 300 unidades cuadradas y el cuadrado estará en el medio (representado con una X).

       300
________________
|               |
|               |
|               | 300
|       X       |
|               |
|               |
|_______________|

const square = [ 150, 150 ];

2º ahora vamos a las avenidas, habrá un número aleatorio de ellas, serán rectas y comenzarán desde el cuadrado del medio o desde otras avenidas

let avenues = [] // will contain start and end [[sx,sy],[ex,ey]]
const n_avenues = RANDOM(4, 8); // number of avenues
const n_av_from_square = RANDOM(0, avenues); // starting in the square

for av in av_from_square
  avenues.push(square, [RANDOM(0, 200) + 100, RANDOM(0, 200) + 100])
  // we want avenues to have, at least 100 units length, thats why we randomize just te last 200 units of the whole town size

Esto debería darte una plaza y un par de calles principales

       300
________________
|   \\          |
|    \\         |
|     \\        | 300
|       X=====  |
|               |
|               |
|_______________|

Ahora tenemos que establecer las avenidas que no comienzan en la plaza principal, se cruzarán con las otras avenidas

for av in (n_avenues - av_from_square){
  const av_to_intersect = avenues[RANDOM(0,avenues.length)];

  //check av_to... and get a perpendicular vector (explained bellow)
  av[0] = [ av_to_intersect[0][1], - av_to_intersect[0][0] ];
  av[1] = [ av_to_intersect[1][1], - av_to_intersect[1][0] ];

}

Para obtener vectores perpendiculares, debe intercambiar los cables x, y y negar la nueva y:

swiped == x: noswiped.y, y: -1 * (noswiped.x)

En este momento deberías tener algo similar a esto, ¿no parece una ciudad? :PAG

       300
________________
|   \\  //      |
|    \\//  ||   |
|     \\   ||   | 300
|    //\X=====  |
|   //     ||   |
|          ||   |
|_______________|

3º ahora solo tienes que interconectar las avenidas con calles cortas, además, puedes generar cuadrados aleatorios a lo largo de la ciudad y hacer lo mismo que todos los anteriores, o simplemente generar pequeñas calles de algunos cuadrados secundarios, depende de ti.

Recuerde, cuanto más cortas son sus calles, más caótica se ve la ciudad.

PRDeving
fuente