Рассчитать угол движения шарика после столкновения с угловой или наклонной стенкой, которая является двухмерным отрезком

1

Если у вас есть "шарик" внутри двумерного многоугольника, состоящий, например, из четырех сегментов линии, которые действуют как ограничивающие стены, как вы вычисляете угол шара после столкновения с нерегулярно наклонной стенкой?

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

Я читал о точечных продуктах и ​​нормалях, но я не могу понять, как их реализовать в Java/Android. Я полностью в тупике и чувствую, что теперь я искал все 10 страниц в Google в 10 раз. Я сгорел, пытаясь понять это, я надеюсь, что кто-то может помочь.

  • 0
    Извините за мой сумасшедший титул. Я, наверное, тоже использую неправильную терминологию. Я искал отражение, углы, склоны, столкновения, нормали и т. Д., Чтобы понять это.
  • 0
    Возможно, вам стоит задать этот вопрос на физике.stackexchange.com ?
Показать ещё 2 комментария
Теги:
game-physics

2 ответа

8

Извините заранее: я не знаю правильных типов Android. Я предполагаю, что у вас есть векторный тип со свойствами "x" и "y".

Если стена была горизонтальной, а текущая скорость была "вектором", то это было бы так же просто, как:

vector.y = -vector.y;

И вы оставите x-компонент один. Поэтому вам нужно сделать что-то аналогичное, но более общее.

Вы делаете это, подставляя идею нормальной линии (вектор, перпендикулярный прямой) для жесткого кодирования оси y (которая перпендикулярна горизонтали).

Так как нормаль ортогональна прямой, ее можно найти, повернув линию на 90 градусов. В 2d вектор (a, b) можно поворачивать на 90 градусов, преобразуя его в (-b, a). Следовательно, если у вас есть строка от (x1, y1) до (x2, y2), вы можете получить нормальный с помощью:

vectorAlongLine.x = x2 - x1;
vectorAlongLine.y = y2 - y1;

normal.x = -vectorAlongLine.y;
normal.y = vectorAlongLine.x;

Вы действительно не заботитесь о том, как долго была оригинальная строка (и это повлияет на вычисления позже, когда вы этого не захотите), поэтому вы хотите сделать нормальную длину длиной 1 независимо от ее текущей длины. Вы можете сделать это, разделив его на текущую длину. Так, например,

lengthOfNormal = Math.sqrt(normal.x*normal.x + normal.y*normal.y);
normal.x /= lengthOfNormal;
normal.y /= lengthOfNormal;

Используя теорему Пифагора, получим длину.

С горизонтальной линией, переворачивание по оси y было таким же, как (i) разработка того, какова протяженность вектора вдоль оси y; и (ii) вычитать эту сумму дважды - один раз, чтобы получить скорость в 0 в этом направлении, чтобы сделать ее отрицательной версией оригинала. То есть, это то же самое, что:

distanceAlongNormal = vector.y;
vector.y -= 2.0 * distanceAlongNormal;

Точечный продукт используется в общем случае для работы, насколько вектор распространяется вдоль нормали. Таким образом, он делает то же самое, что и vector.y делает для горизонтальной линии. Здесь вам, возможно, придется немного поверить вере. Это свойство точечного продукта, и вы можете убедить себя, проверив прямоугольный треугольник. Но пока, если бы у вас была горизонтальная линия, вы бы закончили с нормальным (0, 1). Так как точка-произведение будет:

vector.x * normal.x + vector.y * normal.y

Вы бы вычислили:

distanceAlongNormal = vector.x * 0.0 + vector.y * 1.0;

Это, очевидно, то же самое, что просто взять y-компонент.

Выработав расстояние по нормали, вы действительно захотите вычесть это количество раз в два раза. Единственный дополнительный шаг здесь - это умножение на нормаль, чтобы получить 2d-величину для вычитания. Это потому, что вы хотите вычесть в порядке нормы. Таким образом, полный код, основанный на норме, вычисленный ранее, следующий:

distanceAlongNormal = vector.x * normal.x + vector.y * normal.y;
vector.x -= 2.0 * distanceAlongNormal * normal.x;
vector.y -= 2.0 * distanceAlongNormal * normal.y;

Если вы не сделали нормальной длины 1, вам нужно разделить ее по длине, так как точечный продукт будет масштабировать значение DistanceAlongNormal на эту величину.

  • 0
    Я думаю, что мы работаем над двумя очень разными уровнями, потому что я понятия не имею, как бы я реализовал все это. В настоящее время у меня есть мяч, путешествующий в dx / dy. Это ударяет стену. Как я узнаю, каким должен быть его новый dx / dy, если стена не горизонтальная или вертикальная? Извини, я просто не понимаю.
  • 0
    Я использовал vector.x и vector.y вместо dx и dy, но в остальном я думаю, что просто повторюсь.
Показать ещё 3 комментария
0

Это может пригодиться вам http://www.tonypa.pri.ee/vectors/tut07.html

Ещё вопросы

Сообщество Overcoder
Наверх
Меню