İki vokselin birbirine bağlı olup olmadığını görmek için algoritma


11

Aşağıdaki sorun için iyi bir algoritma arıyorum: 3D (iki boş veya dolu olabilir) voksel ızgara göz önüne alındığında, iki bitişik olmayan voksel seçerseniz, onlar birbirine bağlı olup olmadığını bilmek istiyorum diğer vokseller.

Örneğin (durumu 2B olarak göstermek için), burada # dolu bir karedir:

  1 2 3
a # # #
b # #
c # # #

A3 ve c3 seçersem, bağlanıp bağlanmadıklarını mümkün olduğunca çabuk belirlemek istiyorum; dolu pikseller arasında a3 ve c3 arasında bir yol varsa. (Gerçek durum elbette bir 3D voksel kılavuzundadır.)

Floodfill algoritmalarına ve yol bulma algoritmalarına baktım, ama hangisini seçeceğimi bilmiyorum. Her ikisi de gereksiz çalışır: Taşkın dolgu tüm vokselleri doldurmaya çalışır, ancak buna gerek yoktur. Yol bulma algoritmaları genellikle gerekli olmayan en kısa yolu bulmakla da ilgilidir. Ben sadece orada olmadığını bilmek gerekir olduğunu bir yolu.

Hangi algoritmayı kullanmalıyım?

Düzenleme: yorumlara dayanarak, aşağıdakileri eklemeliyim: voksellerin içeriği önceden bilinmemektedir ve ayrıca, bir vokselin kaldırılması (boşaltılması) voksel grubunun kırılmasına neden olup olmadığını tespit etmek için algoritma gereklidir iki veya daha fazla küçük gruba ayrılır.


: Sizin örnekte c3 için a3 den geçerli bir yol aşağıdaki olurdu c3->c2->b2->a2->a3?

doğru
Bram Vaessen

Yanıtlar:


12

A * iyi çalışır. Yol bulmak istediğiniz şeydir, en kısa yolu bulmak, herhangi bir yol bulmak kadar hızlı (veya daha hızlı). Bu durumda, bir başlangıç ​​ve bitiş noktanız varsa, A * muhtemelen en uygun olanıdır. Bu, aramayı hızlandırmak için ek bir sezgisel tarama yaptığınız anlamına gelir.

A * ile tipik olarak bulduğunuz ilk yol en kısa olanıdır, bu yüzden zaten bir yol bulduktan sonra ekstra iş yapmaz.

resim açıklamasını buraya girin

Bazı optimizasyonlar için cevabımı burada bulabilirsiniz .


o duvara
çarpıncaya

1
@ GameDev-er Evet, sezgisel yüzünden. Hiçbir engel olmasaydı, çok hızlı bir arama olurdu, neredeyse düz bir çizgi olurdu.
MichaelHouse

Düğümlerin daha iyi sıralanmasıyla, bu ilk önce son düğüme en yakın yolu genişletecektir. Düğümleri sipariş etmek için hızlı bir veri yapınız varsa, bunları en doğrudan yol için hedefe olan mesafeye göre sıralayın.
MichaelHouse

9

Bazı ön işlem yapmaya ve depolama maliyetini yemeye hazırsanız, vokselleri derleme sırasında bağlı gruplara bölmek 'hiç bir yol var mı' için açık bir cevap verir. Aynı gruptalarsa iki voksel arasında bir yol vardır. Buradaki sorun, grup bilgilerini bir yerde saklamanız gerektiğidir ve bu, veri düzeninize bağlıdır. Basit bir liste saklıyorsanız, bunu uzamsal olarak bağlı her grup için bir tane olmak üzere birden fazla listeye ayırabilirsiniz. Bir çeşit BVH'de organize ediyorsanız, "bu düğümdeki ve altındaki tüm vokseller X grubuna aittir" diyebiliyorsanız, muhtemelen oldukça iyi verimlilikler elde edebilirsiniz.

Alternatif olarak, bazı uzamsal ön-ayırma yapabilir ve her bağlı grup için daha küçük bir 'hub' voksel seti saklayabilirsiniz. Daha sonra kaynağınızdan yol bulabilir ve vokselleri en yakın hub vokseline hedefleyebilirsiniz, bu da yolu hesaplamak için çok daha kısa / daha ucuz olmalıdır. Bir vokselden hub vokseline bir yol bulabilirseniz, voksel hub voksel grubunun bir parçasıdır. Bu hub voksellerin akıllıca seçilmesiyle yol geçişlerinin sayısını en aza indirebilirsiniz. Örneğin, bir kürenin merkezinde sadece bir hub voksel olabilir, ancak uzun ince bir grubun uzunluğu boyunca her X vokselde bir hub voksel olabilir. Kaynak ve hedef vokseller uzunluğun her iki ucundaysa, bir hub bulmak için en fazla X voksel gitmek zorundadırlar ve uzunluğun başlangıcı ile bitişi arasında çok sayıda voksel olsa da,

Her şey voksel gruplarınızın ne kadar patolojik olduğuna bağlıdır: eğer çok sayıda ufacık bağlantısı kesilmiş grup bekliyorsanız, depolama maliyetindeki artış sadece yol bulmanın performans vuruşundan büyük ölçüde ağır basacaktır. Nispeten az sayıda bağlantılı grup, ancak tek topolojiden bekliyorsanız, saf yol bulma çok pahalı olabilir ve depolama maliyeti ve minimum yol bulma çok daha ucuz bir seçenektir.


1
Bu doğru cevaptır, ancak verimli bir şekilde uygulamak için bir liste olarak saklanmamalıdır. Her voksel için birleşim bulma algoritmasını kullanarak ayarladığınız "temsili vokseline" işaret eden bir işaretçi ekleyin. Bu, voksel başına sabit depolama maliyetidir ve temel olarak hesaplama maliyeti için kenar sayısında doğrusaldır.
Neil G

İlginç fikirler, ancak durumu zorlaştırabilecek iki şey var. Birincisi, voksel ızgarasının içeriğinin önceden bilinmediği, bu nedenle hub vokselleri yapmak için, hangi voksellerin hub olması gerektiğini belirleyebilecek bir algoritmaya da ihtiyacım var.
Bram Vaessen

1
İkinci sorun, bir vokselin çıkarılmasından hemen sonra algoritmanın, vokselin çıkarılması nedeniyle parçası olduğu grubun daha küçük gruplara bölünüp bölünmediğini belirlemek için gerekli olmasıdır.
Bram Vaessen

@BramVaessen Eğer tüm ikili bağlantı ilişkilerini - ve özellikle de grupların ayrılıp ayrılmadığını - arıyorsanız , bu sadece ulaşılabilirlikten biraz farklı bir konudur (yine de ulaşılabilirlik en kolay yoludur); 'Sorunun arkasındaki soruna' daha iyi yanıtlar verebileceğinden, orijinal soruya özel olarak neyin peşinde olduğuyla ilgili daha fazla ayrıntı eklemenizi öneririm.
Steven Stadnicki

Temiz tutmak için, ilk sorunumu burada farklı bir soruda sordum gamedev.stackexchange.com/questions/50953/…
Bram Vaessen

4

Voksellere çok aşina değilim, ancak A * gibi en iyi ilk arama algoritmasını kullanarak oldukça iyi bir performans elde edebileceğinizi hayal edebiliyorum. Bu örnekte A * kullanmanın problemi, sezgisel olanın normalde kullanacağı, sadece 'herhangi bir yolu' mümkün olduğunca çabuk değil, en kısa yolu bulmaya öncelik vermek üzere tasarlanmasıdır.

Daha az sayıda düğümü genişleten alternatif bir sezgisel tarama kullanarak şansınız olabilir.

f (p) = g (p) + w (p) * h (p)

burada w> = 1. hedefe yaklaştıkça 'w' değerini düşürürsünüz, böylece aradığınız voksele yaklaştıkça 'g' yol maliyetine daha yüksek bir öncelik verirsiniz.

Umarım bu yardımcı olur!

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.