Eksen Hizalanmış Mekansal Bölme: Boşluğu rastgele dikdörtgenlere böler misiniz?


11

3D uzay rastgele eksen hizalanmış kutu şekillere bölmek için bir yönteme ihtiyacım var. Şimdilik 2d alanını test amacıyla bölüyorum. Ortaya koyduğum en yakın yaklaşım, boyut olarak bir dikdörtgen (1, 1) tanımlamak ve sonra tüm mevcut dikdörtgenleri X ve Y ekseni arasında değişen iki eşit olmayan dikdörtgene özyineli olarak bölmekti.

resim açıklamasını buraya girin

Buradaki sorun açıktır. Bu yaklaşım uzun germe çizgileriyle sonuçlanır (kırmızı ile işaretlenmiştir)

resim açıklamasını buraya girin

Ne istiyorum daha organik görünümlü bir şey (bir örnek dahil)

Yukarıdan aşağıya veya soldan sağa uzun düz çizgiler görün.

resim açıklamasını buraya girin

Tek kısıtlama, boyutların ayrıntı düzeyini etkilemeden dikdörtgenin minimum boyutunu sınırlamak isteyebileceğimdir. yani en küçük doğrultu saniyeden 1 santimetre kare ise en küçük oda 2 metrekarelik bir alan olmamalıdır.

İdeal olarak algoritma aşağıdaki üç kısıtlamayı da karşılamalıdır:

  1. Dikdörtgenler sonsuz küçük değildir.
  2. Rekt boyutları, en küçük rekt boyutunun ayrık çarpımı değildir. örneğin, en küçük rektin 3 kare birimi olması halinde, büyük rektlerden 6, 9, 12 ve benzeri kare birimlerle sınırlandırılmaz ve bunun yerine 3,2 veya 4,7 olabilir).
  3. Algoritma polinom zamanında çalışır (hızlı hesaplanması gerekir).

Yanıtlar:


12

Belirttiğiniz yaklaşım basit ve kullanışlıdır, ancak gösterildiği gibi korkunç eserlerden muzdariptir. Bunu önlemek. Paralel bir büyüme algoritmasına ihtiyacınız var; tek iş parçacıklı bir model için, bir yuvarlak döngü yaklaşımı aşağıdaki gibidir:

  1. Harita alanınıza rastgele çeşitli noktalar yerleştirin. Gauss dağılımını kullanarak veya Voronoi Diyagramları için Lloyd gevşemesine göre rastgele yerleştirilmiş noktaları birbirinden uzaklaştırmak için yinelemeli bir gevşeme algoritması uygulayarak dağıtımlarını normalleştirin (çirkin kümelemeyi önler) . Bu noktalar, odanızın merkezindeki sentroidleri temsil eder.
  2. (Paralel / Tüm odalar için yuvarlak robin tekrarla) Her noktadan itibaren, küresel yineleme başına merkez noktasından hareket ederek 4 köşeyi dışa doğru (dikdörtgen bir oda) büyütün (aynı odalar için her eksende farklı oranlarda farklı oranlarda büyüyebilirsiniz ve bunun nasıl ortaya çıktığını görün - muhtemelen daha organik / çeşitli bir sonuç için). Bir noktada, dikdörtgenlerinizden bazıları birbirine bastırmaya başlayacaktır. Bu noktada, bu eksendeki büyümeyi sınırlayın, iki odanın bitişik kenarlarının tam olarak temas ettiğinden emin olun ve devam edin.
  3. Tüm oda, bitişik odalar veya haritanın sınırları ile sınırlı oluncaya kadar, her odayı aşamalı olarak büyüterek 2. adımı tekrarlayın.
  4. Bu yine de boş alanlar bırakacaktır. Sorun artık işgal edilmeyen alanların yerini bulmak ve oda yapmaktan biri haline geliyor. Aslında, temel alanınız (tamsayı dizinli) bir ızgaraysa (ve her büyüme yinelemesi bu ızgaraya yapışırsa), işgal edilen ve boş ızgara hücrelerinin listelerini tutabildiğinizden, bununla başa çıkmak çok daha kolaydır: Tüm odalarınızı yerleştirip büyüdüğünüzde, bitişik hücre gruplarından oluşan ayrı boşlukları bulmak için boş listede arama yapın. Kullanılmayan birçok boşluğun dikdörtgen olmayan şekilleri olacağından, dikdörtgen olmayan o alanın içinden rastgele bir hücre seçmeniz ve 2. adımdaki odalarda yaptığınız gibi maksimum boyutuna büyütmeniz gerekir. Tamamen dolana kadar dikdörtgen boşluk.
  5. Haritanız% 100 doluncaya kadar 4. adımı tekrarlayın.

Bu iyi bir tavsiye. Dezavantajı, beni sonsuz küçük rektlerden korumak için muhtemelen hiçbir şey yapmamasıdır. Ne kadar küçük ve ne kadar büyük rektlerin olduğunu sınırlamak için bir şekilde ihtiyacım var. Şu anda başka bir yöntem üzerinde çalışıyorum. Sonuçları karşılaştıracağım ve güncelleyeceğim.
AturSams

@ArthurWulfWhite Daha sonra sorunuz yetersiz belirtildi ve güncellenmesi gerekiyor. Minimum oda büyüklüğünüz harita hücresi çözünürlüğünüz tarafından belirlenir; bu nedenle, minimum oda boyutunu alacak kadar kaba tanecik yaparsanız, daha sonra eksenleri kayan nokta temelinde ayarlayarak daha organik bir görünüm elde edebilirsiniz.
Mühendis

Haklısın! O kısmı yazdığımı sanıyordum. Ama bilmiyorum. Bu hata için özür dilerim. Evet, ızgara boyutunun farkındayım. Bir oda sadece ızgaranın izin verdiği kadar küçük olabilir.
AturSams

Tamam - umarım uygun bir çözüm bulursun. BTW "eksenleri ayarlamak" değil, "ızgara çizgilerini ayarlamak" demek istedim.
Mühendis

1
Aslında tam olarak böyle bir şey yapıyorum, beni düşündüğün kavramlara dayanarak. Sonuçları da burada paylaşacağım.
AturSams

2

Gördüğünüz gibi, bu eserlerin dünyasından kurtulmayı başardım. Fikir çok benzer.

  1. 2d boşluğunu eşit olmayan bir ızgaraya bölün. İki çizgi çok yakınsa birini kaldırın.
  2. Rastgele bir dikdörtgen seçin, y ekseni boyunca (yükseklik olarak) ve doğrudan komşusunun eksen y boyunca değiştirilip değiştirilmediğini kontrol edin. İkisi de değiştirilmedi, aralarındaki segmenti yeniden müzakere ettim (biri diğerine biraz alan bağışlayacak).
  3. 2. adımdaki ile aynı işlemi sadece diğer eksende yapın.
  4. Mümkün olduğunca çok değişiklik yapana kadar işlemi tekrarlayın.

Düzgün olmayan ızgara (1):

resim açıklamasını buraya girin

Eksen x (2) üzerinde müzakere:

resim açıklamasını buraya girin

Eksen y (3) üzerinde müzakere:

resim açıklamasını buraya girin

Sonuç (4):

resim açıklamasını buraya girin

resim açıklamasını buraya girin


Bu @Nick Wiggill
AturSams

2
İlk olarak, n * m bitişik hücre gruplarını rasgele tek bir dikdörtgene birleştirerek daha da geliştirilebilir. Bu, yukarıdaki çıktıda hala görünen alt ızgarayı maskeler. Bu büyük dikdörtgenlerle müzakere artık kenarlarından biri boyunca tüm hücreler üzerinde çalışmak zorunda.
DMGregory

TAMAM. Hala çok sayıda colinear sınır, daha fazla çalışacağım, ama çözümünüzü bulduğunuz için iyi! Yardımcı olmaktan mutluluk duyuyorum.
Mühendis

@DMGregory Bunu düşündüm ama küçük rektler ile büyük rektifler arasındaki oranın bir miktar tutarlı olmasını istedim. Bu bir doku ya da seviye olsaydı kesinlikle yapardım (Aslında bunu yapan önceki bir örneği var).
AturSams

@NickWiggill Colinear çizgilerini tamamen ortadan kaldırabilirim. Bu sadece algoritmayı değiştirmektir. Daha da geliştirmenin bir yolu olmalı (en son varyasyonla güncelleme)
AturSams
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.