web-dev-qa-db-ja.com

最大のターゲットへの弾道を計算するためのアルゴリズム。 2跳弾

タイトルが悪いので申し訳ありませんが、私にはそれを表現するためのより良い方法がありませんでした...

Wii Playと呼ばれるWii上の任天堂(そうです!)によるこの素晴らしいゲーム があります。その中に9つのミニゲームがあり、私の好きなミニゲームは Tanks! と呼ばれています。自分を破壊することなくCOM敵の戦車を破壊することです。レベルのスクリーンショットは次のとおりです。

enter image description here

戦車を破壊する1つの方法は、弾丸を発射することです。 (壁とブロックに対して)跳弾する高速の弾丸を2回発射するこのライムグリーンの敵戦車があります。中央のライム戦車が、画像上に描いた緑の道に沿って弾丸を発射できるので、プレーヤーの戦車が現在の場所に留まっていると、どのようにして即座に破壊されるかがわかります。

私自身アマチュアプログラマーとして、私はLimeタンクがプレイヤータンクを打ち倒すためにどの方向に発砲すべきかをどのように決定できるのかと思っていました。

私はそれについて自分で考えましたが、可能なアルゴリズムを思いつきませんでした。彼らが誰かを刺激する場合に備えて、私の結論を説明します。説明の単純化のために、私はwall弾丸が跳ね返る可能性がある任意の表面であると仮定します。したがって、ブロックの孤立した長方形は4つの壁を形成します。

私は、弾丸の跳弾が常に平行四辺形の片側にあるか、平行四辺形の反対の頂点になる2つの点を結論付けました。射撃する敵戦車とそれが狙うプレイヤー戦車は、必ずしも他の2つの頂点ではありませんが、平行四辺形の4つの辺のいずれかと同一直線上にある線上に確実にあります。平行四辺形を形成する4つの可能な方法を次に示します。

enter image description here

HOR-VERは、弾丸が最初に水平の壁に当たり、次に垂直の壁に当たります。

そして、私は行き詰まっています。敵の戦車とプレイヤーの戦車を結ぶ線をマップの周りに移動して、壁が2発の平行四辺形を形成しているかどうかを確認しようと考えましたが、敵の戦車とプレイヤーの戦車は必ずしもそうではないため、これは常に機能するとは限りません平行四辺形の頂点と必ず一致します。

また、アルゴリズムの一般的なフローもわかりません。アルゴリズムは次の2つの構造のいずれかを使用しますか、それともこれらの両方に誤りがありますか?

  • 可能なパスを常に考え出し、常に最良のものとしてマークし(最短、最も不明瞭、最も避けられないもの、または複数の基準に基づく重み付けされた評価を組み合わせて)、残りは忘れてください。すべての計算の後に残ったものが、取るのに最適なものです。
  • 最初に、弾丸で最初に到達できるすべての壁を決定します(弾丸がこれらの壁のそれぞれに到達するために、他の壁に跳弾する必要はありません)。次に、これらの壁のそれぞれで到達可能なすべての範囲を決定します(遠くの点に到達できない場合があります)別の壁があなたの近くに立っている場合は跳弾のない壁)、そして跳弾で到達可能なすべての壁と、これらの壁で到達可能なすべての範囲を再度決定します。これらの4つのプロセスは、レイトレーシングと同様の方法で実行できます。各プロセス中に、プレイヤーの戦車がレイに当たった場合、そのレイに応じて弾道を計算します。

私の意見では、このアルゴリズムは次の理由で理解するのが困難です。

  • 弾丸はどの方向にも発砲できます。そして
  • 数学のように、壁には無限に多くの点があり、線上には無限に多くの点があります。

とにかく任天堂の人々はそれを作ったので、...アイデアを持っている人はいますか?

21
hello all

直接の視線を考えると、問題は明らかに取るに足らないものです。ただし、リフレクションを扱っています。レイトレーサーの一部として反射を実装する場合、一部の開口部を見落とす可能性があるため、シーンのどの部分が見えるかを正しく見つけることは困難です。 2つの有望な角度間の「バイナリ検索」も実行できません。反射により、実際に見える空間は連続的ではないため、ヒューリスティックな「Aの右側とBの左側にある場合、ターゲットが存在する必要があります。 AとBの間のソリューション」は許可されないであり、「クリエイティブ」なソリューションを見逃します。代わりに、仮想位置からトレーサーを再実行して反射を実装することをお勧めします-ミラーで見たときに発射タンクが見える位置

target |obstacle
   X   |
    \  |  X real position
     \   /
      \ /
   ----------- mirror surface
        \
         \
          X virtual position

利点は、ミラーリングされた光線が仮想位置から始まる直線になることです。私は次のスケッチでテクニックを説明しようとしました:

shooting around corners

Xは射撃位置、(X)ターゲットをマークします。色付きの領域が表示されます。

  1. 直接の視線:ターゲットは見えません。ただし、サーフェス(1)と(2)を打つことはできます。

  2. 1つの反射。障害物内には2つの仮想発砲位置があります。下の位置はターゲットに直接LOSしているため、最初の発砲ソリューションがあります。弾道パスは、ターゲットと下のミラーサーフェスの間、および光線とミラーの衝突点と実際の発砲位置。

  3. 2つの反射:最初の反射からの上の仮想位置は、そのミラーサーフェスを通して下の障害物の一部を見ることができます。 2つの反射が許可されているので、この位置を下の障害物にミラーリングできます。位置は、(I)実際の位置、(II)最初の反射からの仮想位置、および(III)2番目の反射からの仮想位置としてマークされます。

    (III)から、LOSをターゲット(X)に直接持っているので、別の発砲解を見つけました。弾丸の経路は、2番目のミラー衝突点までX-III線に沿っており、次にミラー衝突点の間のIII-II線に沿っており、最後に最初のミラー衝突点から実際の位置IまでのII-I線に沿っています。

    実際には、最初の反射からの低い仮想位置も上の障害物に反映される可能性がありますが、これは直接的な解決策にはつながりません。

障害物のどの部分が表示されているか(したがって、弾丸を反映するために使用できるか)がわかると、深さ優先検索によるミラーリングの実装は簡単に思えます。適切なミラーサーフェスを見つけるには、 Nicky CaseのSight&Light で概説されている手法を使用できます:360ベクトルを試すのではなく–これは開口部を見逃す可能性があり、また無駄です–障害物の端にのみ光線を発射します。

9
amon

2つの壁の反射に対するカールビーレフェルトのアイデアを拡張するだけ: enter image description here

AとBが与えられます(タンク)。最初に、Aが見ることができるすべての壁と、Bが見ることができるすべての壁のリストをリストする必要があります。次に、最初の壁が最初の壁にあり、2番目の壁が最初の壁とは異なり、2番目のリストにあるペアを作成します。壁の可能なすべてのペアに対してこのテストを行う必要があります(候補を排除する方法が見つからない場合)。与えられた壁のペアのRとSを見つけたら、チェックします

1)AがRを直接見る場合

2)Rが壁1に属している場合(壁は単なるセグメントであり、ライン全体ではありません)

3)RがSに直接アクセスできる場合

4)Sがwall2に属する場合(壁は単なるセグメントであり、ライン全体ではありません)

5)SがBに直接アクセスできる場合。

RとSを見つけるには:wall1は知っているので、wall1に接する線方程式を決定できます。Rは壁1に接する線に属しているため、 Sと同様に、Rの2つの座標間に関係があります(Rは1自由度になります)(この点はwall2に接する線に属しているため、S座標間に関係があります)。これで2自由度が得られ、解を決定するために2つの追加の独立方程式が必要になります。 1つの方程式は次のとおりです。

(AA')/(RA')=(SS')/(RS')

他の方程式は:

(BB')/(SB')=(RR')/(SR')

上記の方程式では、A、A '、B、B'がわかっているか、直接計算できることに注意してください。 R 'およびS'は、RおよびSの座標と壁方程式の関数です。計算を終えていなかったので、方程式がどのようになるかわかりません。

7
Mandrill

跳弾を離れる角度は、跳ね返る角度と同じでなければならないという事実を利用できます。 y座標がcである特定の水平壁と、座標が(a,b)および(d,e)である2つの固定タンクの場合、下の方程式を満たす角度は1つだけです。

diagram of equation

xを解いて、壁に沿って目的の距離を取得します。 2つの壁は同じように機能します。 2つの方程式と2つの未知数があります。

3
Karl Bielefeldt

あなたは光線の方向を示すきちんとした図表を持っているので、反射面のペアを決定する方法の詳細を残します。

最初のサーフェスにヒットする必要があるサーフェス[〜#〜] a [〜#〜]を呼び出し、2番目のサーフェスを[〜#〜] b [〜#〜]

[〜#〜] b [〜#〜]の(目に見える)エッジをで撃ってみてください[〜#〜] a [〜#〜]。言い換えれば、鏡を見た場合、[〜#〜] b [〜#〜]の端の反射が見られる点を決定します-終了[〜#〜] a [〜#〜]。これは簡単に実行できるはずです。処理する反射点は1つだけです。

これで、[〜#〜] b [〜#〜]の(可視)エッジに当たる2つの光線がわかりました。それらを呼びましょうエッジ光線反射を計算しますB;それらは行く必要がありますあなたの目標を過ぎたどこか。ターゲットがそれらの間にあるそれらの間にある、つまり一方の光線の左側にあるが他方の光線の右側にあるか、またはその逆かを判断できます。これは 直線の一般方程式 を使用して行うのは簡単です。

ターゲットがEdge光線の間にない場合、中間光線でターゲットに当たることはできません。別のペアのサーフェスを選択します。

ターゲットが光線の間にある場合、バイナリ検索を使用して中間のヒット光線を探します。エッジ光線に対応する2つの発射角度があり、それらの間に打撃角度があります。ターゲットのangular発砲ポイントから見た直径が過度に小さくない場合、当たる光線の方向が見つかるまで数回の反復が必要になります。

ここに写真があります:

rays

ここでは、2つのEdge光線が赤と青で示されています。どうやら、あなたは赤いものよりも小さい角度で放射された光線を見つけることができますが、その光線は緑色のターゲットに当たるように赤いものよりも大きいです。

1
9000