コミュニティアイコン プチコン 非公式コミュニティ トピック

アバター
こういち ◆.Id/aHiU36hu
2021/10/4 7:43
情報交換
多角形同士の当たり判定の取り方を僕たちはまだ知らない(当たり判定研究所)
目的:当たり判定はゲーム等の操作性を決める重要な要素である。見た目と実際の当たり判定が一致しない場合、ユーザーはストレスを感じる。
方形同士の当たり判定はSPHITSPや四分木により高速に判定できるが、複雑な図形の場合それらで大まかに判定した後、自力で細かな判定をする必要がある。
本トピックでは複雑な図形の当たり判定について考察や情報交換を行う。
参考:マルペケつくろーcom(http://marupeke296.com:80/COL_main.html)

コメント

アバター
こういち 2021/10/4 7:44 ◆.Id/aHiU36hu
サブルーチンの仕様
出力
当たり判定であるため、衝突したかどうかの情報は必須である。0の場合衝突しておらず、それ以外は衝突したものとする。
また、それ以外にも「どこから衝突したか」「衝突したか場所はどこか」の情報が必要な場合もある。その情報は法線ベクトル,座標として出力することにする。
変数名は
HIT,NormalR,NormalJ,CX,CYとする。NormalR,NormalJはNR,NJと略すかもしれない。
なお、衝突していない場合の法線と衝突座標の値は何でもいいものとする。

入力
入力として、重心の座標と、半径や頂点の位置ベクトルなどその図形を表現する情報を渡すことにする。頂点情報は時計回りに渡されるものとする。

サブルーチン名
SmileBASIC標準の当たり判定サブルーチンに倣い
(図形1)HIT(図形2)
のような命名とする
なお、先の法線ベクトルは図形1を基準としたものとする。
アバター
こういち 2021/10/4 7:45 ◆.Id/aHiU36hu
用語定義/基礎知識

ベクトル(vector)と座標(coordinate)
ベクトルとは、大きさと向きを持つ量である。コンピュータの世界ではX方向成分,Y成分で管理することが多い。トピック主はベクトルと複素数には親和性があると考えており、後の座標と区別する意味も込めて、ベクトルを表す変数名にR(Real),J(Imagenary)という語素を付けることにする。

座標とは、位置を表す量であり、大きさと向きに加え原点を持つ。座標の大きさが0になる点を原点と呼び、本トピックではただ一つ存在するものとする。
2点間の座標の差を位置ベクトルと呼び、本トピックでは座標と区別する。
座標を表す変数名にはX,Yという語素を付ける。
アバター
こういち 2021/10/4 7:46 ◆.Id/aHiU36hu
三平方の定理
三平方の定理と呼ばれる有名な定理がある。それについての解説は省略するとして、三平方の定理を用いると原点からの距離やベクトルの大きさを求めることが出来る。
なお、ベクトルの向きは逆三角関数のATAN()で求まるが、使う機会はあまりない。

DEF CABS(R,J) 'ベクトルの大きさ(complex absolute)
 RETURN SQR(R*R+J*J)
END
DEF DIST(X0,Y0,X1,Y1) '二点間の距離(distance)
 RETURN CABS(X1-X0,Y1-Y0)
END
アバター
SatoshiMcCloud 2021/10/4 23:56 ◆Z1qfV11i63Jr
「どこから衝突したか」を得るためには、衝突直前にどこに存在していたかの情報が必要だと思います。
図を描いてみましたが、この右列の絵だけを見てどこから衝突したかを予測するのは不可能だと思います。
アバター
こういち 2021/10/5 5:32 ◆.Id/aHiU36hu
SatoshiMcCloudさん
これは厄介ですね。
どちらにせよめり込みやすり抜けを考慮すると前フレームの情報を使って五角形で判定するしかなさそうですね。
それでも厄介なことに変わりはないですが。
あまりに高速な物体は「正しく判定できないもの」として割りきるしかなさそう(実際世の物理エンジンは速いとすり抜ける)
アバター
ツララ 2021/10/5 11:44 ◆ArUdBYOYME1V
当たり判定領域の中心の座標なりの移動情報をベクトルで持っていておけば
当たった方向は判別できるんじゃないんです?

あと、高速な物体のすり抜け防止は時間を「点」じゃなくて
「線」で取得・保持して判別する形式にすればいいだけなんじゃないんです?
連続性が切れると補完できなくて隙間が出来るのが見落としの原因なんでしょうし。
まぁこの辺は使用メモリとの相談になるんでしょうけど。

試行錯誤を尽くす前に”不可能”って割り切るのはどうかと思いますけどね。

実際、高速スクロールを実装するために
画面上のオブジェクト情報をライン毎にマップデータから文字列として文字列変数に格納して
INSTR命令でオブジェクトの位置を調べて
キャラクターの移動量の範囲内で衝突するかどうかを判別する処理とか試しに作ったことありますし。
仕様上、文字列変数の最大長以上の移動量だと流石に判別不能ですけど
それでもドット単位をキャラクター単位や画面単位にするとかの繰り込みを駆使すれば範囲の拡大の工夫の余地はまだありますし。
アバター
こういち 2021/10/5 12:38 ◆.Id/aHiU36hu
ツララさん
>当たり判定領域の中心の座標なりの移動情報をベクトルで持っていておけば
当たった方向は判別できるんじゃないんです?<
これもなんか反例がありそうで嫌な予感しますね。実用的には十分か。

線で判定するのは前のコメントに既に書いてありますね。高速な物体は諦めるという選択肢も十分ありだとは思います。メモリとか速度もそうですが、労力とか必要性とかも考えて(当然ながら高速で動く物体が存在しなければそんなケースは考える必要なんてない)
アバター
SatoshiMcCloud 2021/10/5 19:41 ◆Z1qfV11i63Jr
連続で指摘して恐縮ですが。
「頂点情報は時計回りに渡されるものとする」の部分、たとえば8の字みたいに辺と辺が交差していたらどうしましょう?
アバター
こういち 2021/10/5 21:32 ◆.Id/aHiU36hu
SatoshiMcCloudさん
WindowsのPolyPolygon関数みたいな感じで分割して渡すか、反転した部分は無視するか(砂時計の形だと三角形として判定される)ですね。ついでにへこみのある物体も同様。

ちなみに、先の反例はへこみのある物体しか見つけられなかったです。

それから、線で判定する方法。回転が入ってくると軌道が直線でなくなってア
アバター
Na 2021/10/5 22:20 ◆QoELVrBXBQCI
小さい図形なら図形の情報をvectorではなくbitmapで表現したほうが簡単な気がしました。
2つの図形の画像データを2次元配列で渡して、衝突しているかどうかを1ドットずつ調べるとか。
これだと遅いですかね

コメントを書く

  • こちらは「プチコン3号」「プチコンBIG」など、プチコンシリーズに関する話題を扱ったコミュニティです
  • プチコンシリーズにまったく関係ない書き込みはご遠慮下さい。削除の対象となります
  • こちらにはその他のゲームや雑談のコミュニティはなく、作る予定もありません (ひとりで管理できないため)。ごめんなさい
  • ユーザー登録なしで書き込みができます
  • 秘密の合い言葉は成りすましの防止 (トリップ機能)、書き込みの編集時の本人認証に使用します
  • 秘密の合い言葉に他人に推測されやすい言葉、他サービスと同じパスワードは入力しないでください。
  • 書き込むと、投稿時に入力したお名前と秘密の暗号が記憶され、ログイン状態になります

- WEB PATIO -