2Dスペースにタイルコーナーが表示されるかどうかを確認するにはどうすればよいですか?


7

私は戦争の霧を実行しようとしています、そして私はトラブルに遭遇しました。プレイヤーが特定の半径内の各タイルのコーナーを見ることができるかどうかを確認したいのですが、コーナーのビジョンが遮られるかどうかを確認する方法がわかりません。これを行う簡単な方法はありますか?私は線を描き、線のあるタイルがルージュのように塗りつぶされたブロックであるかどうかを確認するシステムを使用しましたが、ルージュのようにタイルの一部を見ることができるため、この方法が適しているかどうかはわかりませんはいまたはいいえタイプのものです。

たとえば、黒いタイルが白いタイルのビューを部分的に遮っています。 それでの粗さは最高です

赤い線はプレーヤーがコーナーを見ることができることを示し、青い線はコーナーが見えないことを示します(黒がそれを妨げているため)。


あなたが話している状況の図は、この質問を明確にするのに役立ちます。
MichaelHouse

回答:


3

Nickの答えを少し具体化する:DDAアルゴリズム(3次元でも同様に機能する)の背後にあるコアコンセプトは、グリッドの各軸について、その軸の次の「交差点」を追跡するということです。行パラメーター。アルゴリズムの各ステップは、次の交差点(2次元での単純な比較)を持つ軸を見つけ、適切なステップを実行し、各軸の次の交差値を更新することで構成されます。 DDAイラスト

ここの行は '(x、y)=(x0、y0)+ t *(m、n)'と書くことができます。ここで、m = x1-x0およびn = y1-y0です。グリッドセルの次元がgxとgyの場合、dx — 1つのグリッドセルと交差するのにかかる距離(tパラメーターの観点から)—少しの代数で見つけることができます。方程式のペアxから= x0 + m t、(x + gx)= x0 + m(t + dx)gx = m * dx、つまりdx = gx / mになります。同様に、dy = gy / n。アルゴリズムは、next_x(ラインに沿って次の赤い点までの距離)とnext_y(ラインに沿って次の青い点までの距離)を追跡し、別の交差点にぶつかるたびに更新するため、中央ループは次のようになります:

while ( cur_t < t_max) {
  if ( next_x < next_y ) {
    cell_x++;
    cur_t += next_x;
    next_y -= next_x;
    next_x = dx;
  } else {
    cell_y++;
    cur_t += next_y;
    next_x -= next_y;
    next_y = dy;
  }
  // Process the cell (cell_x, cell_y)
}

このコードには多くの詳細がないことに注意してください。たとえば、next_xやnext_yを初期化する方法はわかりません。垂直線や水平線などの特殊なケースを扱いやすくするために、ほとんどの分割を排除する方法があります。cell_xとcell_yをインクリメントするかデクリメントするかは、ラインがどの象限にあるかによって異なります。この例のラインでは、m(x1-x0)が負であるため、ティックごとに実際にcell_xを減少させることに注意してください。また、ラインがエッジで遷移するのではなく、セル間のコーナーを正確に通過するケースをどのように処理するかを決定する必要もあります。うまくいかない可能性のある小さな詳細がたくさんあり、それは多くのテストを必要とします。それでも、うまくいけば、これにより、アルゴリズムのコアアイデアが何であるかがわかるようになります。


1

John AmanatidesとAndrew WooのDDA(Digital Differential Analyser)アルゴリズムは、必要なものを提供します。私はモバイルにいるので、このページを閉じずにリンクを取得するのは面倒です。DDAはO(n * m)です。ここで、nは光線/角度に沿って歩くタイルの数、mは角度の数です。

タイルのより小さな部分がさらに表示されるかどうかを確認する必要がある場合(詳細)、各タイルを個別のグリッドに分割し、そのレベルでDDAチェックを実行することもできます。

私が見ることができる唯一の実質的に異なる代替案は、レイキャストスキャン(ラインとラインの交差チェック)です。これは、O(n * m)で、nは対象領域内のタイルエッジの数、mはテストする離散角度の数です。円形スイープごとに(このアプローチを使用しても解決の問題がまだ存在することを意味します)。各タイルには複数のエッジがあるため、DDAの方が効率的です。

頭に浮かぶ最後のアプローチの1つは、関心のある限られた領域内の個々のグリッド交点に対して個々の光線角度を設定することにより、レイキャストスキャンを適応させることです。こうすることで、グリッド内でオクルージョンが発生する場所を正確に特定できます(オクルージョンラインは常にコーナーを通過するため)。ただし、光線の角度を定義するインタースティシャルポイントの数が手に負えないように、関心領域を大幅に制限する必要があります。

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