Prosedürel olarak şehirler oluşturmak için L-Systems kullanma


10

Şu anda prosedürel olarak oluşturulmuş içeriğe çok odaklanan bir uygulama yapıyorum. Şimdiye kadar, simpleks gürültü kullanarak arazinin prosedürel neslini ve haritanın şeklini başarıyla uyguladım. Görünüşünden gerçekten memnunum. Şimdi aynısını şehirler için de yapmaya çalışıyorum. Sadece sokakların ve binaların 2B düzenini oluşturmam gerekiyor. Buna baktım ve çoğu insan L-Systems kullanmayı önerdi. Ancak başımı etraflarına dolamıyorum. Ben kavram olsun ama kod içine uygulama değil. Prosedürel olarak oluşturulmuş şehirler için L-Systems kod örnekleri veya şehirleri ele almanın diğer yolları hakkında önerileri olan var mı?



+1 L-Sistemleri için Yaşasın !
luser droog

Benzer bir şey yapmanın bir yolu, kavşakları temsil eden bir düğüm ızgarası oluşturmak, ardından bitişik düğümleri rastgele bağlamaktı. Labirent benzeri bir düzen oluşturur, ancak sokakların hepsi bağlı değildir, bu yüzden aslında gezinmek mümkün değildir.
user137

Şehir üreten L sistemleri için yaygın olarak atıfta bulunulan vasıflar Parish ve Müller'in makalesi: Şehirlerin Prosedür Modellemesi . Ayrıca mükemmel bir uygulama örneği buldum . Başlamak için iyi bir yer, ancak tam gereksiniminize bağlı olarak, bazı şeyleri değiştirmeniz gerekebilir.
Anders Ryndel

Yanıtlar:


20

L-Systems , söyleyebildiğim kadarıyla, ilginç, "organik" sonuçlar elde etmek için tekrar tekrar uygulayabileceğiniz bir dizi dilbilgisi benzeri ikame kuralıdır.

Bitkiler L-Systems'ın sıklıkla kullanıldığı yerlerdir, çünkü çok fazla tekrarlayan büyüme gösterirler (yani dal daha fazla dallara ayrılır). Basit bir örnek olarak, bir L-Sistemi kullanılarak oluşturulan bir "lolipop" ağacı göstereceğim:

variables : | o              (these are the things that will grow)
start  : o
         |                   (this is what we start with)
rules  : (o  o   o)         (these are the substitution rules that we apply
               \ /            one step at a time)

Yani 1. nesilde, sadece başladık:

o
|

2. nesilde, kuralların her birini takip eder ve mevcut parçaları kurallara göre değiştiririz. "Toplar" ı "iki çubuk ve top" ile değiştiriyoruz:

o   o
 \ /
  |

3. Nesil:

o o   o o
 \|   |/
   \ /
    |

Yakında güzel (berbat) büyük bir ağacımız olacak!

Bunu kodda yapmak için, rasgele bir sona ulaşana kadar aynı bölümlerdeki kuralları sürekli olarak uygulayarak veya yinelemeli olarak (yani DFS) yapabilirsiniz veya bunu bu örnekte yaptığımız gibi tekrarlı olarak (yani BFS) yapabilirsiniz , tüm öğeler üzerinde bir kural "geçirme" gerçekleştirme ve bir dizi adımı tekrarlama. Yani:

Tekrarlı:

tree = start
grow(tree, start)

func grow(tree, part)
    if this part of the tree is big enough
        stop
    if part is 'o'
        replace part with 'o\/o'
        grow(tree, the left 'o')
        grow(tree, the right 'o')

iteratif:

tree = start
for a number of iterations
    for each part in tree
        if part is 'o':
            replace with 'o\/o'

L-Systems'ın birçok kullanımı, alt bölümü kullanarak "büyüme" adımını gerçekleştirir - yani, parçalar "büyüdükçe" küçülür, daha büyük parçalar bölünür. Aksi takdirde, büyüyen sisteminiz üst üste gelmeye başlayabilir. Lolipop ağacı örneğimde göreceksiniz, sihirli bir şekilde iki dalın yeni dalların şeklini değiştirerek ortada örtüşmemesini sağladım. Alt bölümü kullanarak şehir örneğini yapalım :

variables: block_vertical block_horizontal road_vertical road_horizontal
start: block_vertical
rules: (block_vertical  block_horizontal road_vertical block_horizontal)
       (block_horizontal  block_vertical road_horizontal block_vertical)

Bu bir dakika içinde anlamlı olacaktır.

Nesil 1:

+--------------------+
|                    |
|                    |
|                    |
|        V           |
|                    |
|                    |
|                    |
+--------------------+

Tek, sıkıcı bir dikey blok. (V dikey anlamına gelir.)

Nesil 2: Dikey bloğu, ortada dikey bir yol olan yatay bloklarla değiştiriyoruz

+--------------------+
|       r            |
|       r            |
|       r            |
|   H   r      H     |
|       r            |
|       r            |
|       r            |
+--------------------+

R yol anlamına gelir! Bölmeyi rastgele dağıttım, PCG'de sıkıcı düzenli parçalar istemiyoruz.

3. Nesil: Yatay blokları, yatay yollarla ayrılmış dikey bloklarla değiştiriyoruz. Mevcut yollar kalır; onlar için kural yok.

+--------------------+
|   V   r            |
|       r            |
|rrrrrrrr            |
|       r      V     |
|   V   r            |
|       rrrrrrrrrrrrr|
|       r      V     |
+--------------------+

Yolların birbirine nasıl bağlandığına dikkat edin, bu güzel. Bunu yeterince kez tekrarlayın ve böyle bir şeyle sonuçlanacaksınız ( ilgili bir cevabı açıkça yırttı ):

resim açıklamasını buraya girin

Dikkat etmediğim çok fazla ayrıntı olduğunu ve bu sonucun "açık bir şekilde" ortaya çıktığını görüyorsunuz - gerçek şehirler biraz farklı görünüyor. PCG'yi eğlenceli / zor yapan budur. Sonuçlarınızı değiştirmek ve iyileştirmek için yapabileceğiniz sonsuz şeyler var, ancak L-Systems ile ilgisi olmadığından, bu cevabı burada bırakacağım; umarım bu başlamanıza yardımcı olur.

* - Dilbilgisi ve PCG bitki örtüsü gibi belirli türlerle karşılaşmış olmama rağmen, L-Sistemlerini resmi olarak incelemedim; Herhangi bir tanım veya kavram yanlış alırsam lütfen beni düzeltin


1

@ congusbongus yanıtı mükemmel, birkaç şey ekleyeyim.

Bloklar, onları sınırlayan tüm yollara göre inşaat alanlarına bölünmelidir. Her yerde yol olduğunda, genel desen bir halkadır. Örneğin bu bağlantıya bakın: http://oldurbanist.blogspot.fr/2012/01/city-blocks-spaces-in-between.html

(Yoğunluğa bağlı olarak, halka merkezinde boşluk olmayabilir, bkz. Kowloon).

Blokları yaptıktan sonra binaları oluşturmanız gerekir. Onlar biraz zor ve iki geçişli nesil gerektirir. Kısmen birbirine bağımlıdırlar: jeneratörünüz bir sonraki bina yan duvarının önünde bir pencere oluşturmamalıdır.

Buna hayat katmak için, nesli arazi veya ekonomik harita gibi ortamlarla etkilemek isteyebilirsiniz: Yollar (San Francisco hariç) düz gitmek yerine büyük tepelerin etrafında gezinme eğilimi gösterir ve ev türleri ağırdır içinde bulundukları şehrin etkisinden etkilenir.

iyi eğlenceler.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.