Столкновение двухмерных шаров с углами - PullRequest
3 голосов
/ 22 декабря 2009

Я пытаюсь написать двумерную симуляцию шара, который отскакивает от неподвижных вертикальных и горизонтальных стен. Имитация столкновений с гранями стен была довольно простой - просто отмените X-скорость для вертикальной стены или Y-скорость для горизонтальной стены. Проблема состоит в том, что шар может также столкнуться с углами стен, где горизонтальная стена встречается с вертикальной стеной. Я уже понял, как определить, когда происходит столкновение с углом. Мой вопрос заключается в том, как мяч должен реагировать на это столкновение, то есть как будут изменяться его скорости X и Y.

Вот список того, что я уже знаю или знаю, как найти:

  • Координаты X и Y центра мяча в кадре при обнаружении столкновения
  • X и Y составляющие скорости шара
  • Координаты X и Y угла
  • Угол между центром шара и углом
  • Угол, в котором движется мяч перед столкновением
  • Количество, на которое мяч пересекает угол при обнаружении столкновения

Я предполагаю, что лучше всего делать вид, что угол представляет собой бесконечно малый круг, поэтому я могу рассматривать столкновение между мячом и этим кругом, как если бы шар сталкивался со стеной, которая касается касательных к окружностям на точка столкновения. Мне кажется, что все, что мне нужно сделать, это повернуть систему координат, чтобы выровнять ее с воображаемой стенкой, обратить вспять X-компоненту скорости шара в этой системе и повернуть координаты обратно к исходной системе. Проблема в том, что я понятия не имею, как это запрограммировать.

Кстати, это идеальная симуляция. Я не принимаю во внимание ничего подобного трению или вращению мяча. Я использую Objective-C, но я бы просто хотел общий алгоритм или какой-нибудь совет.

Ответы [ 2 ]

4 голосов
/ 22 декабря 2009

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

float nx = ballX - cornerX;
float ny = ballY - cornerY;
const float length = sqrt(nx * nx + ny * ny);
nx /= length;
ny /= length;

для отражения вектора скорости вы делаете это:

const float projection = velocityX * nx + velocityY * ny;
velocityX = velocityX - 2 * projection * nx;
velocityY = velocityY - 2 * projection * ny;
2 голосов
/ 23 декабря 2009

Если это острый прямоугольный угол, он будет действовать как ретрорефектор и отскочит его назад по пути, по которому он пришел. (под острым я имею в виду без филе)

...