2d реакция столкновения между кругами - PullRequest
7 голосов
/ 23 июня 2011

Я пытаюсь вычислить новые скорости для 2 сталкивающихся шаров, но на самом деле не могу этого сделать, пока не решу другую проблему.

Поскольку в цифровом мире реального столкновения почти никогда не происходит, у нас всегда будет ситуация, когда «сталкивающиеся» шары перекрываются.

Представьте, что есть 100 шаров, движущихся случайным образом, поэтому, если я правильно понимаю, процедура должна быть следующей:

  • Переместите шары (x += vx; y+= vy;)
  • Получите, чтобы шары не перекрывались (или идеально сталкивались)
  • Переместить шары «назад во времени» к этому моменту
  • Выполнение расчетов столкновений

Если вышеприведенное верно, то как я могу переместить шары «назад во времени» в точку первого столкновения? Известные данные:

  • Все координаты шаров (b[i].x, b[i].y)
  • Ball X и Y скоростей (b[i].vx, b[i].vy)
  • Расстояние между перекрывающимися шариками (dist)

Должен ли я просто рассчитать, сколько процентов dist составляет идеальное расстояние до столкновения, а затем просто переместиться назад x и y координат на то же количество процентов vx и vy?

Ответы [ 4 ]

3 голосов
/ 23 июня 2011

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

Допустим, у вас есть ball1 и ball2. Эти шары имеют позиции p1 и p2 соответственно и скорости v1 и v2. Пусть относительная скорость ball1 относительно ball2 будет v1-v2=v.

Мы хотим знать, когда ||p1-p2|| меньше ||r1||+||r2||, где r1 - вектор с длиной радиуса первого шара в направлении ко второму шару, а r2 - наоборот. наоборот.

С точки зрения ball2, ball1 движется со скоростью v1+v2. В момент времени t, ball2 находится в положении p2+(v1+v2)*t.

Шарики сталкиваются, когда:

(p1-(p2+vt)) = (r1+r2)
-(p2+vt) = (r1+r2)-p1
-p2-vt = (r1+r2)-p1
-vt = (r1+r2)-p1+p2
vt = (p1-p2)-(r1+r2)

Теперь, начиная с ||a|| = ||b||+||c||, когда a = b+c, мы знаем, что

||v||t = ||p1-p2|| - ||r1+r2||
t = (||p1-p2|| - ||r1+r2||)/||v||

Например: p1 = (7,5) и p2=(4,1), ||r1||=1 и ||r1||=2 и v1=(1,2) и v2=(-2,-2), затем v=(3,4). Столкновение происходит в:

t = (||(3,4)|| - 3)/||(3,4)||
t = (5-3)/(5) = 2/5 = 0.4

Теперь, когда у вас есть время столкновения, легко определить, где находятся шары: -)

изменить, чтобы поместить vectormath в псевдокод:

p = p1-p2
v = v1-v2
t = (sqrt(p.x*p.x + p.y*p.y) - (r1+r2)) / sqrt(v.x*v.x + v.y*v.y)
3 голосов
/ 23 июня 2011

То, имеет ли смысл ваша стратегия движения-тогда-столкновения, зависит от того, что вы пытаетесь смоделировать, и от компромисса между точностью и скоростью. Если вы, скажем, пишете симулятор снукера или Super Monkey Ball, то, скорее всего, движение-то-столкновение недостаточно хорошо по трем причинам.

Во-первых, шары будут иметь неправильные скорости после столкновения. Различия будут незначительными, но они будут казаться неправильными игрокам:

enter image description here see text

Слева - скорости в конце временного шага, когда шарам разрешается пересекаться до обнаружения столкновения. Справа: скорости сразу после столкновения в правильное время и место.

Во-вторых, объекты, движущиеся достаточно быстро, могут проходить друг через друга, не сталкиваясь. Или даже если вы обнаружите столкновение, вы можете извлечь объекты неправильным образом, вызывая какое-то незаконное движение. (См. Tasvideos.org для коллекции ошибок столкновений в играх Super Mario Bros, которые вызваны этой стратегией «двигай, а затем выбрасывай».)

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

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

1 голос
/ 23 июня 2011

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

Таким образом, положение центра второго круга (x, y), где y является постоянным, а x уменьшается. Столкновение происходит, когда x 2 + y 2 = (r 1 + r 2 ) 2 , вызов что х крит . Но в моделировании мы прошли мимо этого, до некоторого x крит . Поэтому нам нужно перемотать достаточно времени, чтобы вернуть его к x крит , который мы можем легко вычислить, поскольку знаем x, x крит и v .

0 голосов
/ 23 июня 2011

РЕДАКТИРОВАТЬ: не важно, мой алгоритм нахождения точки столкновения неверен. Я подумаю об этом немного больше.

EDIT2: Хорошо, извините за это. Попробуйте это:

  1. Узнайте, когда они столкнулись. Давайте назовем это T секунд назад. Это будет T так, чтобы расстояние между двумя шариками было равно сумме их радиусов. Уравнение имеет вид ((x1 - v_x1 * T) - (x2 - v_x2 * T)) ^ 2 = r1 + r2
  2. Переместить шары назад время T
  3. Продолжайте свое столкновение

Извините, я не знаю, как форматировать математические уравнения на SO. : S

После возвращения ко времени столкновения вы можете довольно легко рассчитать их новые скорости, используя элементарную физику. Смотри http://en.wikipedia.org/wiki/Elastic_collision#Two-_and_three-dimensional

...