2つのボクセルが相互接続されているかどうかを確認するアルゴリズム


11

私は次の問題に適したアルゴリズムを探しています:ボクセルの3Dグリッド(空または塗りつぶされている可能性があります)を前提として、隣接していない2つのボクセルを選択した場合、それらが互いに接続されているかどうかを知りたい他のボクセル。

たとえば(2Dで状況を示すため)、#は塗りつぶされた正方形です。

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

私がa3とc3を選択した場合、それらが接続されているかどうかをできるだけ早く判別したいと思います。塗りつぶされたピクセルを通るa3とc3の間にパスがある場合。(実際の状況は、もちろん3Dボクセルグリッド内にあります。)

フラッドフィルアルゴリズムとパスファインディングアルゴリズムを見てきましたが、どちらを選択するかわかりません。どちらも不必要な作業を行います。フラッドフィルはすべてのボクセルを埋めようとしますが、これは必要ありません。パス検索アルゴリズムは通常、最短パスの検索に関係していますが、これも必要ではありません。道あるかどうかを知るだけです。

どのアルゴリズムを使用する必要がありますか?

編集:コメントに基づいて、以下を追加する必要があると思います:ボクセルの内容は事前に不明であり、ボクセルの削除(空にする)によってボクセルのグループが壊れるかどうかを検出するアルゴリズムも必要です2つ以上の小さなグループに分けます。


あなたの例では、a3からc3への有効なパスは次のようになりますc3->c2->b2->a2->a3

正解です
Bram Vaessen 2013年

回答:


12

A *は問題なく動作します。経路探索はあなたが望むものであり、最短経路を見つけることは、どんな経路を見つけることよりも同じくらい速い(または速い)です。この状況では、開始点と終了点がある場合、A *がおそらく最も適しています。これは、検索を高速化する追加のヒューリスティックがあることを意味します。

通常、A *を使用すると、最初に見つかったパスが最短になるため、既にパスが見つかった後は余分な作業は行われません。

ここに画像の説明を入力してください

いくつかの最適化については、ここで私の答えを確認してください


それはその壁に当たるまで実際に前方に発射するように見え、それは一種の
ゾッと

1
@ GameDev-erはい、それはヒューリスティックなためです。障害物がなければ、非常に高速な検索となり、ほぼ直線になります。
MichaelHouse

ノードをより適切にソートすると、最後のノードに最も近いパスが最初に拡張されます。ノードを順序付けるための高速データ構造がある場合は、最も直接的なパスのターゲットまでの距離でノードを並べ替えます。
MichaelHouse

9

事前処理を行ってストレージコストを消費する準備ができている場合は、ビルド時にボクセルを接続されたグループに分割することで、「パスがあるか」に対する明確な答えが得られます。2つのボクセルが同じグループにある場合、それらの間にパスがあります。それに関する問題は明らかに、グループ情報をどこかに保存する必要があることであり、それはデータレイアウトに依存します。単純なリストを保存している場合は、空間的に接続されたグループごとに1つずつ、複数のリストに分割できます。ある種のBVHで整理している場合、「このノードとその下のすべてのボクセルはグループXに属している」と言えば、おそらくある程度の効率が得られるでしょう。

または、空間的な事前分割を行い、接続されたグループごとに「ハブ」ボクセルのいくつかの小さなセットを保存することもできます。次に、ソースボクセルとターゲットボクセルから最も近いハブボクセルにパスを検索できます。ボクセルからハブボクセルへのパスを見つけることができる場合、ボクセルはハブボクセルのグループの一部です。これらのハブボクセルをスマートに選択すると、パストラバーサルの数を最小限に抑えることができます。たとえば、球の中心にはハブボクセルが1つしかない場合がありますが、細長いグループには、その長さに沿ってXボクセルごとにハブボクセルがある場合があります。ソースとターゲットのボクセルが長さのどちらかの端にある場合、ハブを見つけるために最大X個のボクセルに移動するだけでよく、長さの開始と終了の間に膨大な数のボクセルがある場合でも、

それはすべて、ボクセルグループがどれほど病的であるかに依存します。多数の小さめの切断されたグループが予想される場合、ストレージコストの増加は、パスファインディングだけのパフォーマンスヒットを大幅に上回ります。接続グループが比較的少ないがトポロジが奇妙であると予想される場合、単純なパス検索は非常に高価になる可能性があり、ストレージコストと最小限のパス検索ははるかに安価なオプションです。


1
これは正解ですが、効率的に実装するには、リストとして保存しないでください。union-findアルゴリズムを使用して設定した「代表的なボクセル」を指す各ボクセルへのポインターを追加します。これはボクセルごとの一定のストレージコストであり、基本的には計算コストのエッジ数に比例します。
Neil G

興味深いアイデアですが、状況を複雑にする可能性のあることが2つあります。1つ目は、ボクセルグリッドの内容が事前にわかっていないため、ハブボクセルを作成するために、どのボクセルをハブにするかを決定できるアルゴリズムも必要です。
Bram Vaessen、2013年

1
2番目の問題は、1つのボクセルを削除した直後に、そのボクセルを削除したことにより、その一部であったグループが小さなグループに分割されているかどうかを判断するためのアルゴリズムが必要になることです。
Bram Vaessen

@BramVaessen すべてのペアワイズ相互接続関係を探している場合、特にグループが「分割」されているかどうかは、単純に到達可能性とは多少異なる問題です(ただし、到達可能性が最も簡単な方法です)。「質問の背後にある問題」に対するより適切な回答が得られる可能性があるため、元の質問の具体的な内容を詳しく説明することをお勧めします。
Steven Stadnicki

きれいに保つために、私は別の質問にここで私の最初の問題を求めているgamedev.stackexchange.com/questions/50953/...
ブラムVaessen

4

ボクセルについてはあまり詳しくありませんが、A *などの最優先の検索アルゴリズムを使用すると、かなり良いパフォーマンスが得られると思います。このインスタンスでA *を使用する場合の問題は、通常使用するヒューリスティックは、「任意のパス」だけでなく、最短のパスをできるだけ早く見つけることを優先するように設計されていることです。

次のようなより少ないノードを展開する別のヒューリスティックを使用して運が良いかもしれません。

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

ここで、w> = 1.は、目標に近づくほど 'w'の値を減らします。これにより、目的のボクセルに近づくほど、パスコスト 'g'に高い優先順位を与えます。

これがお役に立てば幸いです!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.