Використовуйте суму Міньковського
Хороший спосіб вирішити цю проблему , щоб розглянути перетин між лінією руху ( v ) переведені в початок координат ( V « ) і сума Маньківського від А повертається на 180 градусів на початку координат ( А» ) і його перешкоди (тільки B в даному випадку): А » ⊕ B .
У наступній картині I місце А ляпас-мазок в походженні довільної системи координат. Це спрощує розуміння того, що обертання A на 180 градусів призводить до A ' , а v переведений на початок дорівнює v' .
Сума Міньковського - зелений прямокутник, а точки перетину рухомого А та нерухомого В можна знайти, перетинаючи лінію ААВВ . Ці точки позначені синіми колами.
На наступному малюнку було використано інше походження і виявлені ті ж самі точки перетину.
Кілька рухомих AABB
Щоб зробити цю роботу для двох AABB, які рухаються лінійним способом протягом певного періоду часу, ви віднімаєте вектор швидкості B від вектора швидкості A і використовуєте його як відрізок лінії для перетину лінії AABB.
Псевдокод
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), або переходите до наступної фази: реакція на зіткнення.
Коли відбувається зіткнення, алгоритм перетину лінії AABB поверне або 1, або 2 точки перетину залежно від того, припиняє рух A всередині В або проходить через нього відповідно. (Це дисконтування вироджених випадків, коли A пасеться B уздовж їхніх боків або уздовж одного з відповідних кутів.)
Так чи інакше, перша точка перетину вздовж відрізка лінії є точкою зіткнення, ви переведете це назад у правильне положення у світовій системі координат (перше світло-синє коло на другому малюнку уздовж вихідного v , назвіть його p ), а потім вирішити (наприклад, для пружних зіткнень, відображаючи v вздовж нормального зіткнення в p ), яким буде фактичне положення для A в кінці кадру ( At + 1 ).
Якщо є більше, ніж просто 2 колайдери, це стане трохи складнішим, оскільки ви хочете зробити зіткнення для другої, відбитої, частини v також.