Выяснить, какая сторона 2D AABBxAABB столкнулась?

Я делаю клон прорыва/разбивания кирпичей/арканоида (opengl-es/android), и я довольно долго застрял в своем коде обнаружения столкновений. Как следует из названия: как определить, какой стороной кирпича ударил мяч?

Поскольку мне нужно только инвертировать скорость в определенном направлении, x или y, при попадании в кирпич я мог бы подумать:

 if(speedY < 0) : left, upper or right
 else : left, bottom or right
 if(speedX < 0) : bottom, right or upper
 else : bottom, left or upper  

однако это не уводит меня далеко в решении, столкнулся ли он вертикально или горизонтально, и с этим, в каком направлении я должен послать мяч дальше.

Я просмотрел некоторые примеры кода в Интернете, однако они часто очень расплывчаты, сложны или не по теме для меня.


person user717572    schedule 27.10.2011    source источник


Ответы (2)


Ну, если вы знаете положение кирпича и положение мяча, вы можете провести тесты на каждом объекте, чтобы определить сторону кирпича.

Предполагая стандартное происхождение Java в верхнем левом углу:

   +----+
( )|    |
   +----+

Если Max-X мяча ‹ Min-X кирпича, вы знаете, что он должен быть с левой стороны, и наоборот с правой и левой. Вы также должны проверить значения Y для столкновений сверху и снизу.

Конечно, это предполагает, что вы сначала заработали обнаружение столкновений.


ИЗМЕНИТЬ


Это выдержка из моего движка Collision, это всего лишь небольшая часть для примера, но именно так я проверяю, находится ли объект слева от объекта, с которым он сталкивается.

else if ((oCenter.getX() < sCenter.getX()) 
        && ((oCenter.getY() < (sCenter.getY() + sourceHalfHeight)) 
        && (oCenter.getY() > (sCenter.getY() - sourceHalfHeight))))
    return LEFT;

В моем примере здесь oCenter — это Point2D, и это центр шара. sCenter это Point2D и это центр прямоугольной формы. sourceHalfHeight составляет половину высоты прямоугольной формы (объект с центральной точкой sCenter).

Алгоритм псевдокода:

if (the center X of the ball < the center X of the rectangle
        AND the center Y of the ball is BETWEEN the max Y and min Y of the rectangle)
    then the ball is to the LEFT of the rectangle
end if
person Brandon Buck    schedule 27.10.2011
comment
с помощью вашего метода, проверяя, если ball.maxX ‹ кирпич.minX вообще не будет никакого столкновения. Или я неправильно понимаю? - person user717572; 28.10.2011
comment
@ user717572 Да, вы правы, однако я просто привел простой пример того, как определить, с какой стороной объекта столкнулся мяч. Сравнения немного сложнее, но идея попалась. - person Brandon Buck; 28.10.2011

Дело в том, что вы не можете знать это только по скорости, так как мяч может попасть в 2 разные стороны в 2 разных раза, оба раза с одинаковой скоростью в одном и том же направлении.

Пример: первая линия попадает в верхнюю часть, вторая — в боковую, но обе имеют одинаковую скорость и направление.

      /
     /   /
 _____  /
|_____| 

Вам нужно будет использовать положение мяча и сравнить его с каждой стороной кирпича.

person oleclerc    schedule 27.10.2011