ミンコフスキー和を使用する
この問題を解決するための良い方法は、運動の線との交点を考慮することである(V)の原点(に翻訳V「)とミンコフスキー和のAは、原点(で180度回転A」)とその障害物(単にBこの場合):A」 ⊕ B。
次の図では、任意の座標系の原点にA smack-dabを配置しています。この180度の結果によりAを回転させるように理解簡素化A「及びVの原点に翻訳に等しいV」を。
ミンコフスキー和は緑色の長方形であり、線AAA交差を行うことにより、移動Aと静止Bの交点を見つけることができます。これらのポイントには青い丸が付いています。
次の図では、異なる原点が使用されており、同じ交差点が見つかりました。
複数の移動AABB
特定の期間中に直線的に移動する2つのAABBに対してこれを機能させるには、Aの速度ベクトルからBの速度ベクトルを減算し、それをラインとAAAB交差のラインセグメントとして使用します。
擬似コード
def normalize(aabb):
return {x1: min(aabb.x1, aabb.x2), x2: max(aabb.x1, aabb.x2),
y1: min(aabb.y1, aabb.y2), y2: max(aabb.y1, aabb.y2),
def rotate_about_origin(aabb):
return normalize({x1: -aabb.x1, x2: -aabb.x2
y1: -aabb.y1, y2: -aabb.y2})
# given normalized aabb's
def minkowski_sum(aabb1, aabb2):
return {x1: aabb1.x1+aabb2.x1, x2: aabb1.x2+aabb2.x2,
y1: aabb1.y1+aabb2.y1, y2: aabb1.y2+aabb2.y2}
def get_line_segment_from_origin(v):
return {x1: 0, y1: 0, x2: v.x, y2: v.y}
def moving_objects_with_aabb_intersection(object1, object2):
A = object1.get_aabb()
B = object2.get_aabb()
# get A'⊕B
rotated_A = rotate_about_origin(A)
sum_aabb = minkowski_sum(rotated_A, B)
# get v'
total_relative_velocity = vector_subtract(object1.get_relative_velocity(), object2.get_relative_velocity())
line_segment = get_line_segment_from_origin(total_relative_velocity)
# call your favorite line clipping algorithm
return line_aabb_intersection(line_segment, sum_aabb)
衝突応答
ゲームプレイに応じて、よりきめ細かい衝突検出を実行するか(AABBにメッシュが含まれる場合があります)、次のフェーズである衝突応答に進みます。
衝突がある場合、line-AABB-intersectionアルゴリズムは、AがB内での移動を終了するか、Bを通過するかによって、それぞれ1つまたは2つの交差点を返します。(これは、Aが側面またはそれぞれのコーナーの1つに沿ってBをかすめる縮退ケースを割引きます。)
いずれにせよ、線分に沿った最初の交点は衝突点です。これをワールド座標系の正しい位置に変換します(元のvに沿った2番目の画像の最初の水色の円、pと呼びます))そして、フレームの端でのAの実際の位置がどの位置になるか(At + 1)を決定します(例えば、pの衝突法線に沿ってvを反射することにより弾性衝突の場合)。
コライダーが2つ以上ある場合、vの 2番目の反射部分についても衝突検出を行いたいため、これはもう少し複雑になります。