Maksimum çokluk 3 ile kenarlardan dışa doğru Kenar ve Köşe oluşturmak için algoritma


11

Ben evrenin son derece büyük (temelde sonsuz büyük) büyüyebileceği bir web sitesi için 2d oyun yaratıyorum. Başlangıçta, evren, başlangıç ​​noktasına eşit mesafe olan 6 yıldızdan oluşur (0, 0). Benim görevim, birbirine bağlanan “yollar” (kenarlar) olacak daha fazla yıldız üretebilmek. Bu kısıtlamaları karşılayan bir algoritmayı nasıl tasarlayabilirim:

  1. Yıldızlar rastgele dışarı doğru üretilir. (örneğin, yeni yıldızlar için (x, y) koordinatları yavaşça (0, 0) 'dan yavaşça tüm yönlere, tercihen spiral biçimde dışarı çıkacaktır)
  2. Kenarlar geçmeyecektir.
  3. Bir miktar farklılık olsa da, yeni yıldızlar diğer yıldızlara çok uzak veya çok yakın olmamalıdır. (Örneğin minimum bir yarıçap olmalıdır)
  4. Hiçbir yıldızın / noktanın çokluğu 3'ten fazla olmamalıdır.
  5. Tüm bunların bir Veritabanında saklanacağı göz önüne alındığında, algoritma çok pahalıya mal olamaz. Başka bir deyişle, O (n) karmaşıklığı elde etmek isterim (bunun mümkün olup olmadığını bilmiyorum).

Esasen, yıldızların grafikte noktalar olduğu ve yıldızlar arasındaki seyahatin bu yıldızlar arasındaki kenarlarla gösterildiği spiral görünümlü bir galaksidir.

Çözmem gereken belirli adımlar:

  1. Rastgele diğer 3 yıldızların komşu çevresinde henüz çokluğu 3 olmayan bir nokta oluşturun.
  2. Henüz kenar çatışması oluşturmayacak 3 çokluğuna sahip olmayan ilk yıldızı bulun.
  3. Yıldız x birimlik uzaklığa en az uzaksa, iki nokta arasında bir kenar oluşturun.

Çözüm aramaya çalıştım, ancak matematik becerilerimin (ve Grafik Teorisi hakkındaki bilgimin) çok fazla çalışmaya ihtiyacı var. Ayrıca, bu konuyla ilgili herhangi bir kaynak / bağlantı çok takdir edilecektir.

İşte düşündüğüm bazı sözde kod, ama bu bile işe yarayacağından emin değilim ve birkaç 10.000 vb yıldızdan sonra çok iyi performans göstermeyeceğinden eminim.

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

Ayrıca, kimse nasıl bir MySQL veritabanında bu saklamak gerekir hakkında herhangi bir tavsiye varsa, ben de takdir ediyorum.

Son olarak, yukarıda hiçbir şeyin mantıklı olmaması durumunda, aşağıda elde etmek istediklerimin bir görüntüsünü ekledim:ve vb, bir sürü yıldız ...


1
Bu evrenin bir gezgini muhtemelen bir yöne doğru hareket ederdi, yani yıldızlarınız biterse, her yönden yıldız üretmeniz gerekir. Sıkılmış bir kullanıcı veritabanınızı bozabilir, başka bir deyişle. Bu olasılığı düşündünüz mü (bunun bir sorun olabileceğini varsayarak)?
Neil

2
Ayrıca başka bir düşünce, yıldızların yerleştirilmesinin hatırlanması gerekmez. Tekrarlanabilir bir yıldız nesli kullanırsanız, kullanıcının görebileceği yıldızları, bu yıldızlar gelecekte de aynı şekilde oluşturulacak şekilde oluşturabilirsiniz. Yani, veritabanınızın sadece yıldızlarla ilgili bilgileri kaydetmesi gerekir. Konumu onun kimliğidir.
Neil

1
Oluşturulan her yıldızın tam olarak 3 çokluğu varsa ne yapacaksınız, bu yüzden adım 1 başarısız olur? Herhangi bir resminizde neden 4 çokluk ile bir nokta, bu bir hata mı?
Doc Brown

1
Hayır. Eğer tahmin edilebilir bir şekilde yıldız üretebilirseniz, o zaman gidip geri dönerseniz hep orada olmuş gibi olurlar. Değişmeyen sadece algoritma ve tohumdur.
Neil

2
@JF Bakın No Man's Sky . Adam tam anlamıyla bir evren üretir. Sadece oyuncular tarafından ziyaret edilen gezegenleri kaydeder, ancak mevcut gezegenler aynı noktalarda kalırlar. Her şey rastgele sayılar üretmek için kullanılan uygun tohumu kullanmaya dayanır.
Neil

Yanıtlar:


2

Öneri: İç evren ağını mükemmel bir şekilde düzenli, algoritmik ve nispeten basit tutun. Evrenin yalnızca kullanıcı ekranında görüntülendiğinde rastgele görünmesi gerekir . Kullanıcı görüntüsü için yalnızca yıldız konumlarına rastgele ofsetler uygulayın.

Sorun: Her yıldız için rastgele bir ofset hesaplamanın en belirgin yaklaşımı, altta yatan gerçek yapıyı gizlemek için çok iyi bir iş yapmayacaktır. Yıldızları, birbirleriyle çarpışma veya geçiş yollarıyla çarpışma riski taşımadan önce yalnızca küçük bir miktarda rastgele dağıtabilirsiniz.

Çözüm: Koordineli yerel olmayan rasgelelik uygularsanız büyük rasgele bozulmalar uygulayabilir ve çok daha rasgele ve ilginç görünen bir evren elde edebilirsiniz. Yıldızları kauçuk bir tabakaya yerleştirdiğinizi ve tabakanın farklı bölümlerini rastgele uzadığını ve ezdiğini hayal edin. Bu, tüm yıldız gruplarını uzun bir mesafeye kaydırabilir. Asla çarpışmayacak veya çarpışmayacaklar çünkü yakındaki yıldızlar birbirlerine göre geriliyor ve eziliyor.

Nasıl yapılır: Fraktal arazi jeneratörlerine bakın. Bunun için birçok ücretsiz ve açık kod var. Yalnızca bir haritadaki her nokta için bir yükseklik değeri oluşturan temel koda ihtiyacınız vardır. Bunu farklı bir şekilde kullanacağız. İKİ bağımsız arazi yüksekliği haritası oluşturmak için bu kodu kullanın. Yıldızın gerçek X, Y konumu ile başlayın, her haritada o konuma bakın, yıldızın X görüntüleme konumunu dengelemek için bir harita değeri kullanın ve yıldızın Y görüntüleme konumunu dengelemek için diğer harita değerini kullanın. Bazı ölçeklendirme faktörleri ile oynamak zorunda kalacaksınız, ancak bu size rastgele çarpık kauçuk levha etkisi verebilir. Yıldız pozisyonundaki büyük varyasyonlar, alttaki sıralı pozisyonları tamamen gizlemelidir. Rasgeleliğin fraktal doğası çok doğal görünümlü bir etki verecektir,

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.