Используйте сумму Минковского
Хороший способ решить эту проблему , чтобы рассмотреть пересечение между линией движения ( v ) переведены в начало координат ( V « ) и сумма Минковского от А поворачивается на 180 градусов в начале координат ( А» ) и его препятствия (только B в данном случае): А» ⊕ B .
На следующем рисунке я помещаю A smack-dab в начало произвольной системы координат. Это упрощает понимание, поскольку вращение A на 180 градусов приводит к A ' , а v, переведенная в начало координат, равна v' .
Сумма Минковского - это зеленый прямоугольник, и точки пересечения движущегося A и неподвижного B можно найти, выполнив пересечение линии-AABB . Эти точки отмечены синими кругами.
На следующем рисунке было использовано другое происхождение и найдены те же точки пересечения.
Несколько движущихся 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 свое движение внутри B или проходит через него соответственно. (Это не относится к вырожденным случаям, когда A пасет B вдоль своих сторон или вдоль одного из их соответствующих углов.)
В любом случае, первая точка пересечения вдоль отрезка линии - это точка столкновения, вы бы перевели ее обратно в правильную позицию в мировой системе координат (первый голубой круг на втором рисунке вдоль исходного v , назовите его p ) и затем решите (например, для упругих столкновений, отражая v вдоль нормали столкновения в точке p ), какой будет фактическая позиция для A в конце кадра ( At + 1 ).
Если имеется более двух коллайдеров, это будет немного сложнее, так как вы захотите обнаружить коллизию и для второй отраженной части v .