日本語版
最新ニュース
科学&テクノロジー

衝突検出アルゴリズム · leanrada.com[0] 2023年8月5日 · 13分で読めます タグ: 何か ゲーム スイープ アンド プルーンは、ゲームの衝突検出をすばやく実装したいときに私がよく使うアルゴリズムです。これは素晴らしくエレガントなアルゴリズムだと思うので、それについて記事を書きました。 この投稿は多くの例と説明を含む長い記事であるため、2 つの部分に分かれています。次の特別なスプリングボードを使用して、特定の部分にジャンプできます。 残りの投稿では、私が第一原理と考えるものを絵に描き、それを次のように示そうとします。 インタラクティブデモ! さあ行こう! 衝突検出 ご存知のとおり、衝突検出の問題は、ビデオ ゲーム プログラミングでは非常に一般的です。これは、特定のゲーム メカニクスやシミュレーションを実装するための前提条件です。 衝突するクリボー これらのメカニズムには、キャラクター同士が通り抜けるのを防ぐ、 グンバ ぶつかったときに向きを変え、大きな細胞が小さな細胞を食べる アガー、またはほぼすべてのゲーム物理。これらすべてに何らかの衝突検出が必要です。 接触すると細胞が小さな細胞を消費する ここでは、最も単純なものから始めて、 掃除と剪定 アルゴリズム。空間分割や空間ツリーの細分化などの他のアプローチについては説明しません。 ボール。 これを使うよ 剛体ボールシミュレーション 記事全体を通してアルゴリズムを説明するために繰り返し使用される例として、次のものがあります。 では、始めましょう! これらの衝突をどのように検出するのでしょうか? 素朴なアプローチ 🐥 最も簡単な解決法は、衝突の可能性があるすべての物体のペアをテストすることです。つまり、 すべてのボールを他のすべてのボールと比較する。 for (let i = 0; i balls.length; i++) { const ball1 = balls[i]; for (let j = i + 1; j balls.length; j++) { const ball2 = balls[j]; if (intersects(ball1, ball2)) { bounce(ball1, ball2); } } } 上記のコードでは、内側のループが i + 1 重複したペアがカウントされるのを防ぐためです (AB と BA)。それ以外は、非常にシンプルな解決策です。 これらのチェックはタイムステップごとに実行され、ボールが衝突したときに正確に跳ね返ることが保証されます。 以下は、時間ステップごとに交差がテストされるペアを示す、速度を落としたハイライト表示のシミュレーションです。 ペアはハイライト表示されます テストを受ける際 intersects()。 そして、それは機能します。しかし、ボールが数個以上あると、パフォーマンスの問題が発生し始めます。 パフォーマンス、またはその欠如 この単純なアルゴリズムは の上2) 時間 ビッグオー用語つまり、入力が ん ボールの数に応じてアルゴリズムの実行時間は増加します。 四角 入力の んたくさんですね!📈 これは、 ん ボールは周りにあります (n * (n-1))/2 テストするペア、または 0.5n2 -0.5nたとえば、n = 5 の場合、ペアは合計 10 個になります。n = 10 の場合、ペアは 45 個になります。n = 15 の場合、ペアは 105 個になります (!)。などなど… Big O 記法を使用すると、この情報を簡潔な式に簡略化できます。 “の上2)” 入力が大きくなるとパフォーマンスが悪化することを(苦痛を伴うが)実証するために、n = 20 のシミュレーションを示します。 20個のボール = テストするペア190個 フレームごとに大量のテストが行​​われます。明らかに、単純なソリューションでは、多数のオブジェクトに対しては適切にスケーリングできません。 このソリューションをどのように改善できるでしょうか? 最悪の場合の実行時間は どれでも 衝突検出アルゴリズムは常に の上2)全てのオブジェクトが同時に交差し、n個のオブジェクトをそれぞれ処理する以外に選択肢がないときです。2 衝突。 したがって、平均的なケースと最良のケースを比較する方が実用的です。 そうは言っても、素朴なアルゴリズムは依然として Θ(n2) のために どれでも 実際の衝突回数に関係なく、改善の余地は大いにあります。 プロローグ: ソリューションの改善 通常、アルゴリズムを最適化するときは、 冗長または不必要な作業次に、その冗長性を統合する方法を見つけます。(企業っぽいですね。) まず最初に、 intersects() この関数はすべての候補ペアに対して呼び出されます。 典型的なオブジェクト交差テスト その実装として、私たちはこれらの束を手に入れます 不平等チェック: function intersects(object1, object2) { return object1.left object2.right && object1.right > object2.left && object1.top object2.bottom && object1.bottom > object2.top; } 上記のコードでは、 intersects() 関数は、2つのオブジェクトが交差するかどうかを、それぞれの方向の反対の境界を比較してチェックします。( このMDNの記事 より詳しい説明についてはこちらをご覧ください。 テストを構成要素のチェックに分解することができます。 object1.left object1.right > object2.left object1.top object1.bottom > object2.top 各チェックは、特定の方向の特定の軸のみを対象とします。 ここで重要なことは、 && オペレーターの 短絡評価これらのチェックのいずれかが偽であることが判明した場合、全体のテストは直ちに偽であると評価されます。 私たちの目標は、少なくとも 1つ これらのチェックは、可能な限り多くのテストで誤りになります。 これは、 分離軸定理これは、影が重ならない軸が少なくとも 1 つある場合、2 つのオブジェクトが衝突することはないことを意味します。 2番目のチェックだけに焦点を当ててみましょう – object1.right > object2.left残りのチェックについては心配しないでください。上で示唆したように、1 つの軸のみを最適化すると、後で大きな違いが生じる可能性があるため、今はこの 1 つのチェックに焦点を当てます。 複数のオブジェクトのコンテキストで考えてみましょう。水平構成の 3 つのオブジェクト (A、B、C) を考えてみましょう。 There are three potential pairs to be checked here: A-B, B-C, and A-C. Remember, we’re trying to find redundant work. Pretend we’re running all the pairs through the check, like so: A.right > B.left B.right > C.left A.right > C.left See any redundant work? Maybe abstractify it a little… A > B B > C A > C Voilà. Due to the transitive property of inequality, realise that we don’t need to run the third test! If we know that A > B and B > C are both false, then we would know that A > C is false as well. “If a ≤ b and b ≤ c, then a ≤ c.” the transitive property of inequality So in this example, we don’t really need to run intersects(A, C). intersects(A, B) intersects(B, C) We’ve skipped one intersects() call for free! ✨ I’m handwaving the fact that P.left ≤ P.right is implied for any object P. Nevertheless, working those details out would just mean more transitivity. You might be wondering how this contrived example could apply to general n-body collision detection. A smart reader such as you might also have realised that this skip only works if A, B, and C are in a particular order. What particular order? Try dragging the balls below to see when the optimisation applies and when it does not: intersects(A, B) intersects(B, C) intersects(A, C) ヒント: ボールをドラッグして、A‑B‑Cの順序で水平方向に並べます。 このスキップはA、B、Cの順序でのみ機能するのは事実ですが、これらのラベルは 任意! 一番左のボールを常に A、真ん中のボールを B、一番右のボールを C と呼ぶことにしたらどうなるでしょうか? そうすれば、最適化は常に適用可能になります! 🌌🧠 でも待ってください…オブジェクトに論理的な順序に従ってラベルを付けるというのは、本質的には✨並べ替え✨! オブジェクトのリストを毎回ソートしたらどうなるでしょうか? スキップされるテストの数はソートのコストに見合うでしょうか? 第1章 ソート ソート、不等式、最適化は密接に関連しています。 ソートされたリストを使用すると、不等式の推移的性質をまとめて利用することができます。

≤ a[1] ≤ a[2] ≤ ... ≤ a[n-1]" src="https://leanrada.com/notes/sweep-and-prune/sorted.png" caption="The inequality relationships of elements in a sorted list."/>ソートされたリスト内の要素の不等関係。 フレームごとにオブジェクトのリストをソートしなければならない場合でも、最も高速な一般的なソートアルゴリズムは O(n log n) 時間は確かに の上2)。 上記の 3 つのオブジェクトの例で示されているように、テストをスキップする機能を実現するには、オブジェクトのリストを x 位置で並べ替える必要があります。 しかし、オブジェクトはゼロ幅の点ではありません。 幅広のつまり、サイズがあり、x 軸の間隔を占めることを意味します。これは「幅」とも呼ばれます。オブジェクトが x 軸の間隔にまたがっている場合、x 位置で明確に並べ替えるにはどうすればよいでしょうか。 最小値で並べ替え x 幅の広いオブジェクトを並べ替える解決策は、…

衝突検出アルゴリズム · leanrada.com[0] 2023年8月5日 · 13分で読めます
            
            
            タグ:
              何か
              ゲーム
            

            スイープ アンド プルーンは、ゲームの衝突検出をすばやく実装したいときに私がよく使うアルゴリズムです。これは素晴らしくエレガントなアルゴリズムだと思うので、それについて記事を書きました。
            この投稿は多くの例と説明を含む長い記事であるため、2 つの部分に分かれています。次の特別なスプリングボードを使用して、特定の部分にジャンプできます。
            
            残りの投稿では、私が第一原理と考えるものを絵に描き、それを次のように示そうとします。 インタラクティブデモ! さあ行こう!
            
            衝突検出
            ご存知のとおり、衝突検出の問題は、ビデオ ゲーム プログラミングでは非常に一般的です。これは、特定のゲーム メカニクスやシミュレーションを実装するための前提条件です。
            
              衝突するクリボー
            
            
            これらのメカニズムには、キャラクター同士が通り抜けるのを防ぐ、 グンバ ぶつかったときに向きを変え、大きな細胞が小さな細胞を食べる アガー、またはほぼすべてのゲーム物理。これらすべてに何らかの衝突検出が必要です。
            
              接触すると細胞が小さな細胞を消費する
            
            
            ここでは、最も単純なものから始めて、 掃除と剪定  アルゴリズム。空間分割や空間ツリーの細分化などの他のアプローチについては説明しません。
            ボール。
            これを使うよ 剛体ボールシミュレーション 記事全体を通してアルゴリズムを説明するために繰り返し使用される例として、次のものがあります。
            

            では、始めましょう! これらの衝突をどのように検出するのでしょうか?
            素朴なアプローチ 🐥
            最も簡単な解決法は、衝突の可能性があるすべての物体のペアをテストすることです。つまり、 すべてのボールを他のすべてのボールと比較する。
            
for (let i = 0; i  balls.length; i++) {
  const ball1 = balls[i];
  
  for (let j = i + 1; j  balls.length; j++) {
    const ball2 = balls[j];
    
    if (intersects(ball1, ball2)) {
      bounce(ball1, ball2);
    }
  }
}
            上記のコードでは、内側のループが i + 1 重複したペアがカウントされるのを防ぐためです (AB と BA)。それ以外は、非常にシンプルな解決策です。
            これらのチェックはタイムステップごとに実行され、ボールが衝突したときに正確に跳ね返ることが保証されます。
            以下は、時間ステップごとに交差がテストされるペアを示す、速度を落としたハイライト表示のシミュレーションです。
            
              
              
                
                ペアはハイライト表示されます  テストを受ける際 intersects()。
              
            

            そして、それは機能します。しかし、ボールが数個以上あると、パフォーマンスの問題が発生し始めます。
            パフォーマンス、またはその欠如
            この単純なアルゴリズムは の上2)  時間 ビッグオー用語つまり、入力が ん ボールの数に応じてアルゴリズムの実行時間は増加します。 四角 入力の んたくさんですね!📈
            これは、 ん ボールは周りにあります (n * (n-1))/2 テストするペア、または 0.5n2 -0.5nたとえば、n = 5 の場合、ペアは合計 10 個になります。n = 10 の場合、ペアは 45 個になります。n = 15 の場合、ペアは 105 個になります (!)。などなど… Big O 記法を使用すると、この情報を簡潔な式に簡略化できます。 “の上2)”
            入力が大きくなるとパフォーマンスが悪化することを(苦痛を伴うが)実証するために、n = 20 のシミュレーションを示します。
            
              
              
                
                20個のボール = テストするペア190個
              
            

            フレームごとに大量のテストが行​​われます。明らかに、単純なソリューションでは、多数のオブジェクトに対しては適切にスケーリングできません。
            このソリューションをどのように改善できるでしょうか?
            
              最悪の場合の実行時間は どれでも 衝突検出アルゴリズムは常に の上2)全てのオブジェクトが同時に交差し、n個のオブジェクトをそれぞれ処理する以外に選択肢がないときです。2 衝突。
              したがって、平均的なケースと最良のケースを比較する方が実用的です。
              そうは言っても、素朴なアルゴリズムは依然として Θ(n2) のために どれでも 実際の衝突回数に関係なく、改善の余地は大いにあります。
            

            プロローグ: ソリューションの改善
            通常、アルゴリズムを最適化するときは、 冗長または不必要な作業次に、その冗長性を統合する方法を見つけます。(企業っぽいですね。)
            まず最初に、 intersects() この関数はすべての候補ペアに対して呼び出されます。 典型的なオブジェクト交差テスト その実装として、私たちはこれらの束を手に入れます 不平等チェック:
            function intersects(object1, object2) {
  
  return object1.left  object2.right
      && object1.right > object2.left
      && object1.top  object2.bottom
      && object1.bottom > object2.top;
}
            上記のコードでは、 intersects() 関数は、2つのオブジェクトが交差するかどうかを、それぞれの方向の反対の境界を比較してチェックします。( このMDNの記事 より詳しい説明についてはこちらをご覧ください。
            テストを構成要素のチェックに分解することができます。
            
              object1.left 
              object1.right > object2.left
              object1.top 
              object1.bottom > object2.top
            
            各チェックは、特定の方向の特定の軸のみを対象とします。
            ここで重要なことは、 && オペレーターの 短絡評価これらのチェックのいずれかが偽であることが判明した場合、全体のテストは直ちに偽であると評価されます。
            私たちの目標は、少なくとも 1つ これらのチェックは、可能な限り多くのテストで誤りになります。
            これは、 分離軸定理これは、影が重ならない軸が少なくとも 1 つある場合、2 つのオブジェクトが衝突することはないことを意味します。
            2番目のチェックだけに焦点を当ててみましょう – object1.right > object2.left残りのチェックについては心配しないでください。上で示唆したように、1 つの軸のみを最適化すると、後で大きな違いが生じる可能性があるため、今はこの 1 つのチェックに焦点を当てます。
            
              
            
            
            複数のオブジェクトのコンテキストで考えてみましょう。水平構成の 3 つのオブジェクト (A、B、C) を考えてみましょう。
            
              
              
            
            
            There are three potential pairs to be checked here: A-B, B-C, and A-C. Remember, we’re trying to find redundant work. Pretend we’re running all the pairs through the check, like so:
            A.right > B.left 
B.right > C.left 
A.right > C.left 
            See any redundant work? Maybe abstractify it a little…
            A > B 
B > C 
A > C 
            Voilà. Due to the transitive property of inequality, realise that we don’t need to run the third test! If we know that A > B and B > C are both false, then we would know that A > C is false as well.
            
              “If a ≤ b and b ≤ c, then a ≤ c.”
                the transitive property of inequality
              
            
            So in this example, we don’t really need to run intersects(A, C).
            
intersects(A, B) 


intersects(B, C) 




            We’ve skipped one intersects() call for free! ✨
            
              I’m handwaving the fact that P.left ≤ P.right is implied for any object P. Nevertheless, working those details out would just mean more transitivity.
            

            You might be wondering how this contrived example could apply to general n-body collision detection. A smart reader such as you might also have realised that this skip only works if A, B, and C are in a particular order.
            What particular order? Try dragging the balls below to see when the optimisation applies and when it does not:
            
              
              
intersects(A, B) 
intersects(B, C) 
intersects(A, C) 
            



            ヒント: ボールをドラッグして、A‑B‑Cの順序で水平方向に並べます。
            このスキップはA、B、Cの順序でのみ機能するのは事実ですが、これらのラベルは 任意! 一番左のボールを常に A、真ん中のボールを B、一番右のボールを C と呼ぶことにしたらどうなるでしょうか? そうすれば、最適化は常に適用可能になります! 🌌🧠
            でも待ってください…オブジェクトに論理的な順序に従ってラベルを付けるというのは、本質的には✨並べ替え✨! オブジェクトのリストを毎回ソートしたらどうなるでしょうか? スキップされるテストの数はソートのコストに見合うでしょうか?
            第1章 ソート
            ソート、不等式、最適化は密接に関連しています。 ソートされたリストを使用すると、不等式の推移的性質をまとめて利用することができます。

1724097300
2024-08-19 13:14:31

≤ a[1] ≤ a[2] ≤ … ≤ a[n-1]” src=”https://leanrada.com/notes/sweep-and-prune/sorted.png” caption=”The inequality relationships of elements in a sorted list.”/>ソートされたリスト内の要素の不等関係。

フレームごとにオブジェクトのリストをソートしなければならない場合でも、最も高速な一般的なソートアルゴリズムは O(n log n) 時間は確かに の上2

上記の 3 つのオブジェクトの例で示されているように、テストをスキップする機能を実現するには、オブジェクトのリストを x 位置で並べ替える必要があります。

しかし、オブジェクトはゼロ幅の点ではありません。 幅広のつまり、サイズがあり、x 軸の間隔を占めることを意味します。これは「幅」とも呼ばれます。オブジェクトが x 軸の間隔にまたがっている場合、x 位置で明確に並べ替えるにはどうすればよいでしょうか。

最小値で並べ替え x

幅の広いオブジェクトを並べ替える解決策は、 最小x (左端の x 座標)。この手法は、単純なアプローチを改善するために適用できます。

O(n)への最小限の変更のみで済みます。2) ソリューションです。ただし、かなりのテストがスキップされることになります。これについては後で説明します。

まず、変更されたコード:

+ 
+ sortByLeft(balls);
+ 
  
  for (let i = 0; i  balls.length; i++) {
    const ball1 = balls[i];
    
    for (let j = i + 1; j  balls.length; j++) {
      const ball2 = balls[j];
+ 
+     
+     if (ball2.left > ball1.right) break;
+ 
      
      if (intersects(ball1, ball2)) {
        bounce(ball1, ball2);
      }
    }
  }

これは単純なソリューションとほとんど同じですが、コードが 2 行追加されている点のみが異なります。

最初の行 sortByLeft(balls) ボールの左端の x 座標に基づいてランキング付けし、リストを単純に並べ替えます。

function sortByLeft(balls) {
  balls.sort((a,b) => a.left - b.left);
}

そして、内側のループには、次のブレークがあります。

if (ball2.left > ball1.right) break;

それを詳しく見てみましょう。

まず、リストはソートされていることがわかっているので、次の文は任意の正の整数に対して成り立ちます。
c:

balls[j + c].left >= balls[j].left

交差テストの最初のオペランドから導出されるブレーク条件が true の場合、交差をテストしている現在のペアが失敗する可能性が早期に示されます。

balls2.left > ball1.right
または balls[j].left > ball1.right

しかし、さらに意味があります。もしそれが本当なら、上記の 2 つの不等式を組み合わせると…

balls[j + c].left >= balls[j].left > ball1.right

そして推移的性質により、次の文も真となります。

balls[j + c].left > ball1.right

つまり、ボールの交差テストは
balls[j + c]
不合格になる可能性もあります。ボールを個別にテストしなくても、このことはわかります。さまざまなボールがテストから除外されました。

結論として、現在の ボール2
balls[j]

現在のものと重なり合うのを止める ボール1、その後さらに ボール2反復中のs
balls[j + c]
重複しないことが保証される ボール1 同様に。言い換えると、内側のループが遠すぎる場合は停止します。

最後に、デモを紹介します。

強調表示されたペア テストされたとき intersects()

かなりすごいですよね! かなり速くなりました。

いくつかの観察:

  • リストはソートされているため、テストは左から右に実行されます。
  • さらに重要なのは、単純なアプローチよりも明らかにテストが少なくなることです。📉 これは、ペアを x 軸で重なるものに効果的に制限する上記の最適化によるものです。

時間の複雑さを分析してみましょう。👓

ソートは、マージソートやクイックソートのような「最速」のソートアルゴリズムを採用すると、 O(n log n) 学期。

2レベルのループは、早期のブレークにより平均すると O(n+m) の場合 どこ メートル はxの重なりの総数です。これはnに縮退する可能性があります2 しかし、上で述べたように、平均と最良のケースを見る方が有用です。最良の場合、ループは次のようになります。 の上)重複がない場合には余分な処理を無駄にしません。平均的には O(n+m) の場合

平均的なケースとは、オブジェクトがほぼ均等に分散され、オブジェクトごとに交差が 2、3 回しか発生しない世界を指します。これは、プラットフォーム ゲームや横スクロール ゲームなどの比較的単純なビデオ ゲームでは妥当な仮定だと思います。

実行時間の注釈が付いたコードは次のとおりです。


sortByLeft(balls);


for (let i = 0; i  balls.length; i++) {
  const ball1 = balls[i];
  
  for (let j = i + 1; j  balls.length; j++) {
    const ball2 = balls[j];
    if (ball2.left > ball1.right) break;
    if (intersects(ball1, ball2)) {
      bounce(ball1, ball2);
    }
  }
}

これらを足すと O(nlogn+m) は、

これは、単純なアプローチに比べて非常に優れた改善です。 の上2、 なぜなら [1] n 対数 nはるかに小さい よりも 2 そして [2] 部分的に出力ベースであり、重複の数に応じて、必要以上に処理することはありません。

ビッグチートシート

さらに、ソートアルゴリズムの選択も改善できる可能性があります。次の部分でそれについて検討します( n 対数 n!)。

適切な衝突検出アルゴリズムを見つけようとしてここまで来たのなら、読むのをやめて上記の設計を採用してください。これはプログラミングの労力と実行時のパフォーマンスの完璧なバランスです。これがどのように開発されるのか知りたい場合、またはもっとインタラクティブなデモを見たい場合は、次の部分を読んでください。

視覚的な比較

これまでに説明した戦略を並べて比較してみましょう。フレームごとに必要な交差テストの数を確認してください。🔍 n = 10

(表示されていないもの: ソートのコスト。交差テストは十分にコストがかかるとだけ言っておきます。)

これで最初の部分は終わりです。この 2 行のコードが間違いなく MVP でした。

より高度なバージョンと比較するとどうなりますか?

パート2に続きます。

#衝突検出アルゴリズム #leanrada.com0 #2023年8月5日span #13分で読めます #pタグ #span #classtagcomponent #pcategory #titlealgorithm #stylebackground #6bfbfa #color #097d7c何かspan #span #classtagcomponent #pcategory #stylebackground #b7eaa6 #color #336920ゲームspan #pスイープ #アンド #プルーンはゲームの衝突検出をすばやく実装したいときに私がよく使うアルゴリズムですこれは素晴らしくエレガントなアルゴリズムだと思うのでそれについて記事を書きましたp #pこの投稿は多くの例と説明を含む長い記事であるため2 #つの部分に分かれています次の特別なスプリングボードを使用して特定の部分にジャンプできますp #p残りの投稿では私が第一原理と考えるものを絵に描きそれを次のように示そうとします #strongインタラクティブデモstrong #さあ行こうp #idcollisiondetection衝突検出h2 #pご存知のとおり衝突検出の問題はビデオ #ゲーム #プログラミングでは非常に一般的ですこれは特定のゲーム #メカニクスやシミュレーションを実装するための前提条件ですp #div #classblogmedia #blogmediadefault #img #loadinglazy #width100 #dataplaceholder #styleaspectratio #1.3333333333333333background #6888f8 #classblogmediaelement #altマリオとクリボーがぶつかり合うビデオ #srchttpsleanrada.comnotessweepandprunemario.gif #captionGoombas #collidingspan #classblogmediacaption衝突するクリボーspan #div #pこれらのメカニズムにはキャラクター同士が通り抜けるのを防ぐ #target_blank #target_blank #classtextlink #hrefhttpsyoutu.beKy69PjyHCqgグンバa #ぶつかったときに向きを変え大きな細胞が小さな細胞を食べる #target_blank #target_blank #classtextlink #hrefhttpsagar.ioアガーaまたはほぼすべてのゲーム物理これらすべてに何らかの衝突検出が必要ですp #div #classblogmedia #blogmediadefault #img #loadinglazy #width100 #dataplaceholder #styleaspectratio #1.3333333333333333background #f8f8f8 #classblogmediaelement #alt細胞が小さな細胞を食べる #agar.io #のビデオ #srchttpsleanrada.comnotessweepandpruneagario.gif #captionCells #consuming #smaller #cells #contactspan #classblogmediacaption接触すると細胞が小さな細胞を消費するspan #div #pここでは最も単純なものから始めて #target_blank #target_blank #classtextlink #hrefhttpsen.wikipedia.orgwikiSweep_and_prunestrong掃除と剪定stronga #アルゴリズム空間分割や空間ツリーの細分化などの他のアプローチについては説明しませんp #pボールp #pこれを使うよ #strong剛体ボールシミュレーションstrong #記事全体を通してアルゴリズムを説明するために繰り返し使用される例として次のものがありますp #pでは始めましょう #これらの衝突をどのように検出するのでしょうかp #idnaiveapproach素朴なアプローチ #p最も簡単な解決法は衝突の可能性があるすべての物体のペアをテストすることですつまり #emすべてのボールを他のすべてのボールと比較するemp #pre #classcodeblock #code #classcodeblockcodespan #classtoken #keywordforspan #span #classtoken #punctuationspanspan #classtoken #keywordletspan #span #classtoken #operatorspan #span #classtoken #number0spanspan #classtoken #punctuationspan #span #classtoken #operator #ballsspan #classtoken #punctuation.spanlengthspan #classtoken #punctuationspan #ispan #classtoken #operatorspanspan #classtoken #punctuationspan #span #classtoken #punctuationspan #span #classtoken #keywordconstspan #ball1 #span #classtoken #operatorspan #ballsspan #classtoken #punctuationspanispan #classtoken #punctuationspanspan #classtoken #punctuationspan #span #classtoken #keywordforspan #span #classtoken #punctuationspanspan #classtoken #keywordletspan #span #classtoken #operatorspan #span #classtoken #operatorspan #span #classtoken #number1spanspan #classtoken #punctuationspan #span #classtoken #operator #ballsspan #classtoken #punctuation.spanlengthspan #classtoken #punctuationspan #jspan #classtoken #operatorspanspan #classtoken #punctuationspan #span #classtoken #punctuationspan #span #classtoken #keywordconstspan #ball2 #span #classtoken #operatorspan #ballsspan #classtoken #punctuationspanjspan #classtoken #punctuationspanspan #classtoken #punctuationspan #span #classtoken #keywordifspan #span #classtoken #punctuationspanspan #classtoken #functionintersectsspanspan #classtoken #punctuationspanball1span #classtoken #punctuationspan #ball2span #classtoken #punctuationspanspan #classtoken #punctuationspan #span #classtoken #punctuationspan #span #classtoken #functionbouncespanspan #classtoken #punctuationspanball1span #classtoken #punctuationspan #ball2span #classtoken #punctuationspanspan #classtoken #punctuationspan #span #classtoken #punctuationspan #span #classtoken #punctuationspanspan #classtoken #punctuationspanspanspancodepre #p上記のコードでは内側のループが #codei #1code #重複したペアがカウントされるのを防ぐためです #と #BAそれ以外は非常にシンプルな解決策ですp #pこれらのチェックはタイムステップごとに実行されボールが衝突したときに正確に跳ね返ることが保証されますp #p以下は時間ステップごとに交差がテストされるペアを示す速度を落としたハイライト表示のシミュレーションですp #div #classdemorow #sapdemoclient #class #datarssinteractive #altdemo #collision #detection #algorithm #pairwise #strategy #strategypairwise #skipinterval4 #decorationschecks4c8 #ペアはハイライト表示されます #span #arialabela #connecting #green #line #stylecolor4c8 #classpairlegend #テストを受ける際 #codeintersectscode #div #pそしてそれは機能しますしかしボールが数個以上あるとパフォーマンスの問題が発生し始めますp #idperformanceorlackthereofパフォーマンスまたはその欠如h2 #pこの単純なアルゴリズムは #emstrongの上sup2supstrongem #時間 #target_blank #target_blank #classtextlink #hrefhttpsen.wikipedia.orgwikiBig_O_notationビッグオー用語aつまり入力が #emんem #ボールの数に応じてアルゴリズムの実行時間は増加します #em四角em #入力の #emんemたくさんですねp #pこれは #emんem #ボールは周りにあります #emn #n12em #テストするペアまたは #em0.5nsup2sup #0.5nemたとえばn #の場合ペアは合計 #個になりますn #の場合ペアは #個になりますn #の場合ペアは #個になります #などなど.. #Big #記法を使用するとこの情報を簡潔な式に簡略化できます #emの上sup2supemp #p入力が大きくなるとパフォーマンスが悪化することを苦痛を伴うが実証するためにn #のシミュレーションを示しますp #div #classdemorow #sapdemoclient #class #datarssinteractive #altdemo #collision #detection #algorithm #pairwise #strategy #balls20 #strategypairwise #skipinterval4 #decorationschecks4c8 #20個のボール #テストするペア190個 #div #pフレームごとに大量のテストが行われます明らかに単純なソリューションでは多数のオブジェクトに対しては適切にスケーリングできませんp #pこのソリューションをどのように改善できるでしょうかp #span #classboxnote #p最悪の場合の実行時間は #emどれでもem #衝突検出アルゴリズムは常に #emの上sup2supem全てのオブジェクトが同時に交差しn個のオブジェクトをそれぞれ処理する以外に選択肢がないときですsup2sup #衝突p #pしたがって平均的なケースと最良のケースを比較する方が実用的ですp #pそうは言っても素朴なアルゴリズムは依然として #emΘnsup2supem #のために #emどれでもem #実際の衝突回数に関係なく改善の余地は大いにありますp #span #idprologueimprovingthesolutionプロローグ #ソリューションの改善h2 #p通常アルゴリズムを最適化するときは #strong冗長または不必要な作業strong次にその冗長性を統合する方法を見つけます企業っぽいですねp #pまず最初に #codeintersectscode #この関数はすべての候補ペアに対して呼び出されます #target_blank #target_blank #classtextlink #hrefhttpsgdbooks.gitbooks.io3dcollisionscontentChapter2static_aabb_aabb.html典型的なオブジェクト交差テストa #その実装として私たちはこれらの束を手に入れます #strong不平等チェックstrongp #pre #classcodeblock #code #classcodeblockcodespan #classtoken #keywordfunctionspan #span #classtoken #functionintersectsspanspan #classtoken #punctuationspanspan #classtoken #parameterobject1span #classtoken #punctuationspan #object2spanspan #classtoken #punctuationspan #span #classtoken #punctuationspan #span #classtoken #keywordreturnspan #object1span #classtoken #punctuation.spanleft #span #classtoken #operator #object2span #classtoken #punctuation.spanright #span #classtoken #operatorspan #object1span #classtoken #punctuation.spanright #span #classtoken #operatorspan #object2span #classtoken #punctuation.spanleft #span #classtoken #operatorspan #object1span #classtoken #punctuation.spantop #span #classtoken #operator #object2span #classtoken #punctuation.spanbottom #span #classtoken #operatorspan #object1span #classtoken #punctuation.spanbottom #span #classtoken #operatorspan #object2span #classtoken #punctuation.spantopspan #classtoken #punctuationspanspan #classtoken #punctuationspanspanspancodepre #p上記のコードでは #codeintersectscode #関数は2つのオブジェクトが交差するかどうかをそれぞれの方向の反対の境界を比較してチェックします #target_blank #target_blank #classtextlink #hrefhttpsdeveloper.mozilla.orgenUSdocsGamesTechniques3D_collision_detectionaabb_vs._aabbこのMDNの記事a #より詳しい説明についてはこちらをご覧くださいp #pテストを構成要素のチェックに分解することができますp #licodeobject1.left #codeli #licodeobject1.right #object2.leftcodeli #licodeobject1.top #codeli #licodeobject1.bottom #object2.topcodeli #p各チェックは特定の方向の特定の軸のみを対象としますp #pここで重要なことは #codecode #オペレーターの #target_blank #target_blank #classtextlink #hrefhttpsen.wikipedia.orgwikiShortcircuit_evaluation短絡評価aこれらのチェックのいずれかが偽であることが判明した場合全体のテストは直ちに偽であると評価されますp #p私たちの目標は少なくとも #em1つem #これらのチェックは可能な限り多くのテストで誤りになりますp #pspan #classboxnote #これは #target_blank #target_blank #classtextlink #hrefhttpspersonal.math.vt.edumrlugosat.html分離軸定理aこれは影が重ならない軸が少なくとも #つある場合2 #つのオブジェクトが衝突することはないことを意味しますspanp #p2番目のチェックだけに焦点を当ててみましょう #codeobject1.right #object2.leftcode残りのチェックについては心配しないでください上で示唆したように1 #つの軸のみを最適化すると後で大きな違いが生じる可能性があるため今はこの #つのチェックに焦点を当てますp #div #classblogmedia #blogmediadefault #img #srcsethttpsleanrada.comgen_notes_sweep_and_prune_surprisetool_200.generated.jpg #200w #sizes #200px #spec200 #loadinglazy #width100 #dataplaceholder #styleaspectratio #1.2127659574468086background #classblogmediaelement #alt漫画のネズミがこれは後で役に立つサプライズツールだよと言っている静止画 #srchttpsleanrada.comnotessweepandprunesurprisetool.jpg #div #p複数のオブジェクトのコンテキストで考えてみましょう水平構成の #つのオブジェクト #ABC #を考えてみましょうp #div #classblogmedia #blogmediadefault #img #srcsethttpsleanrada.comnotessweepandpruneabc.png #664w #sizes #664px #spec100 #loadinglazy #width100 #dataplaceholder #styleaspectratio #2.034749034749035background #f8f8f8 #classblogmediaelement #altThree #objects #left #srchttpsleanrada.comnotessweepandpruneabc.png #div #pThere #potential #pairs #checked #Remember #find #redundant #work #Pretend #running #pairs #check #sop #pre #classcodeblock #code #classcodeblockcodespan #classtoken #constantAspanspan #classtoken #punctuation.spanright #span #classtoken #operatorspan #span #classtoken #constantBspanspan #classtoken #punctuation.spanleft #span #classtoken #constantBspanspan #classtoken #punctuation.spanright #span #classtoken #operatorspan #span #classtoken #constantCspanspan #classtoken #punctuation.spanleft #span #classtoken #constantAspanspan #classtoken #punctuation.spanright #span #classtoken #operatorspan #span #classtoken #constantCspanspan #classtoken #punctuation.spanleft #codepre #pSee #redundant #work #abstractify #littlep #pre #classcodeblock #code #classcodeblockcodespan #classtoken #constantAspan #span #classtoken #operatorspan #span #classtoken #constantBspan #span #classtoken #constantBspan #span #classtoken #operatorspan #span #classtoken #constantCspan #span #classtoken #constantAspan #span #classtoken #operatorspan #span #classtoken #constantCspan #codepre #pVoilà #Due #target_blank #target_blank #classtextlink #hrefhttpswww.mathwords.comttransitive_property_inequalities.htmstrongtransitive #property #inequalitystronga #realise #dont #run #strongthird #teststrong #emIf #codeABcode #codeBCcode #codefalsecode #codeACcode #codefalsecode #well.emp #blockquote #pIf #citethe #transitive #property #inequalitycite #blockquote #pSo #dont #run #codeintersectsA #Ccode.p #pre #classcodeblock #code #classcodeblockcodespan #classtoken #functionintersectsspanspan #classtoken #punctuationspanspan #classtoken #constantAspanspan #classtoken #punctuationspan #span #classtoken #constantBspanspan #classtoken #punctuationspan #span #classtoken #functionintersectsspanspan #classtoken #punctuationspanspan #classtoken #constantBspanspan #classtoken #punctuationspan #span #classtoken #constantCspanspan #classtoken #punctuationspan #codepre #pWeve #skipped #codeintersectscode #call #free #span #classboxnote #handwaving #fact #codeP.left #P.rightcode #implied #object #working #details #transitivity #span #pYou #wondering #contrived #apply #general #nbody #collision #detection #smart #reader #realised #skip #works #strongparticular #orderstrong.p #pWhat #order #span #classdraghintdraggingspan #balls #optimisation #applies #notp #div #classdemorow #sapdemoclient #class #sapdemodraggable #datarssinteractive #altinteractive #diagram #showing #specific #mechanism #idabcdemo #balls150250503001505545027560 #strategysapnativesort #static #draggable #labelsABC #rainbow #pre #classcodeblock #stylewidth #maxwidth #600pxcode #classcodeblockcodespan #classtoken #functionintersectsspanspan #classtoken #punctuationspanspan #classtoken #constantAspanspan #classtoken #punctuationspan #span #classtoken #constantBspanspan #classtoken #punctuationspan #span #classtoken #functionintersectsspanspan #classtoken #punctuationspanspan #classtoken #constantBspanspan #classtoken #punctuationspan #span #classtoken #constantCspanspan #classtoken #punctuationspan #span #classabcdemointersectsacrun #styledisplay #nonespan #classtoken #functionintersectsspanspan #classtoken #punctuationspanspan #classtoken #constantAspanspan #classtoken #punctuationspan #span #classtoken #constantCspanspan #classtoken #punctuationspan #spancodepre #div #pspan #classboxnote #strongヒントstrong #ボールをドラッグしてABCの順序で水平方向に並べますspanp #pこのスキップはABCの順序でのみ機能するのは事実ですがこれらのラベルは #em任意em #一番左のボールを常に #A真ん中のボールを #B一番右のボールを #と呼ぶことにしたらどうなるでしょうか #そうすれば最適化は常に適用可能になります #pでも待ってくださいオブジェクトに論理的な順序に従ってラベルを付けるというのは本質的にはstrong並べ替えstrong #オブジェクトのリストを毎回ソートしたらどうなるでしょうか #スキップされるテストの数はソートのコストに見合うでしょうかp #idchapter1sorting第1章 #ソートh2 #pソート不等式最適化は密接に関連しています #emソートされたリストを使用すると不等式の推移的性質をまとめて利用することができますemp #div #classblogmedia #blogmediadefault #img #srcsethttpsleanrada.comgen_notes_sweep_and_prune_sorted_664.generated.png #664w #sizes #664px #spec100 #loadinglazy #width100 #dataplaceholder #styleaspectratio #10background #f8f8f8 #classblogmediaelement #alt1つの

執筆者について: nipponese

Nipponese News編集部は、国内外のニュースを日本語で分かりやすくお届けします。