2D Упругая Шариковая Физика

Я делаю программу, которая включает физику упругих шаров. Я разработал всю математику для столкновения со стенами и стационарными объектами, но я не могу понять, что происходит, когда сталкиваются два движущихся шара. У меня есть масса и скорость (скорость x и y, если быть точным, но скорость каждого шара и их направление подойдут), и я хотел бы получить формулы для них. Помните - это идеально упругое столкновение - поэтому нет вращающихся шариков и т. Д.

1 ответ

Эта статья в Википедии предоставляет формулу для расчета скоростей после столкновения двух частиц:

Есть много причин использовать эту формулу:

  • вам просто нужны векторы скорости ваших шаров до столкновения, их масса и их положение,
  • вам не нужно определять углы отклонения,
  • операции просты (требуется только точка продукта),
  • векторы могут быть выражены в любой системе координат.

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


Определение проблемы

Для каждого шара мы определяем:

  • ми масса
  • vi вектор скорости до столкновения
  • v'i вектор скорости после столкновения
  • Ой точка центра
  • xi вектор положения Oi

Единичный вектор n нормален к поверхности шариков в точке контакта.

Единичный вектор t касается поверхностей шариков в точке контакта.


Физический закон для использования

Сохранение полного импульса выражается:

Сохранение полной кинетической энергии выражается:

Поскольку в тангенциальном направлении сила не приложена, тангенциальные составляющие скоростей остаются неизменными после столкновения:


доказательство

Тангенциальные составляющие скоростей неизменны. Таким образом, мы можем переписать законы сохранения с нормальными компонентами, и теперь у нас есть 1D проблема:

Сохранение кинетической энергии может быть факторизовано, а затем упрощено с сохранением импульса:

Мы объединяем это последнее выражение с сохранением импульса и получаем нормальную составляющую v'1:

Наконец, мы находим формулу статьи в Википедии для v'1:

Формула v'2 симметрична.

Поскольку я делаю римейк на blobby, тела не обязательно являются шарами - углы попадания не связаны с расстоянием между X1,X2. Поэтому я использовал следующие уравнения: https://williamecraver.wixsite.com/elastic-equations

Ниже приведен код, который вычисляет векторный угол из скоростей dx dy: Далее ниже приведены уравнения (которые требуют преобразованного векторного ввода). код находится в Python 3.8x. Кортежи являются входными и выходными для функций.

def angle_ofdxdy(dxdy):  # returns angle, z
  dx, dy = dxdy[0], dxdy[1]
  if abs(dy) < 0.01: #prevent div by zero
    dy = 0.01
  # https://math.stackexchange.com/questions/1327253/how-do-we-find-out-angle-from-x-y-coordinates
  z = (dx ** 2 + dy ** 2) ** 0.5
  angle = 2 * atan(dy / (dx + z))
  return (round(angle, 4), z)

ниже представлена ​​функция подготовки, которая использует вышеуказанное перед вызовом уравнений:

def calc_impulse_xy1xy2(xy1_xy2, ball_mass=1, wall_mass=10000000, gamma=0):
  xy1, xy2 = xy1_xy2
  a1, z = angle_ofdxdy(xy1)
  a2, z2 = angle_ofdxdy(xy2)
  # print(f'xy xy translator called for xy={xy1}, xy2{xy2}, angles {degrees(a1):.0f},  {degrees(a2):.0f}')
  return cv1v2(z, a1, z2, a2, ball_mass, wall_mass, gamma)

ниже приведены фактические уравнения:

def cv1v2(ball_velocity=5, ball_theta=0, wall_velocity=0, wall_theta=0, ball_mass=1, wall_mass=10000000, gamma=0):
  g = gamma  # 0 needs further explainig. ba
  t1,t2 = ball_theta, wall_theta
  v1,v2 = ball_velocity, wall_velocity  # a scalar.
  m1,m2 = ball_mass, wall_mass

  # print('pi/2 is',pi/2)
  vx = (v1 * cos(t1 - g) * (m1 - m2) + 2 * m2 * v2 * cos(t2 - g)) * cos(g) / (m1 + m2) + v1 * sin(t1 - g) * cos(g + pi / 2)
  vy = (v1 * cos(t1 - g) * (m1 - m2) + 2 * m2 * v2 * cos(t2 - g)) * sin(g) / (m1 + m2) + v1 * sin(t1 - g) * sin(g + pi / 2)
  v2x = (v2 * cos(t2 - g) * (m2 - m1) + 2 * m1 * v1 * cos(t1 - g)) * cos(g) / (m1 + m2) + v2 * sin(t2 - g) * cos(g + pi / 2)
  v2y = (v2 * cos(t2 - g) * (m2 - m1) + 2 * m1 * v1 * cos(t1 - g)) * sin(g) / (m1 + m2) + v2 * sin(t2 - g) * sin(g + pi / 2)
  xyxy = ((round(vx, 2), round(vy, 2)), (round(v2x, 2), round(v2y, 2)))
  print(f'Ball: {v1:.1f}({degrees(t1):.0f}\u2070)\t Player:{v2:.1f}({degrees(t2):.0f}\u2070),  impact angle:{degrees(g):.0f}\u2070 masses:{m1},{m2} \nresult:{xyxy}')
  return xyxy

Функция относится к мячу и стене. Это просто подсказка на тот случай, если вы хотите протестировать отскок от стены, используя те же уравнения (по умолчанию второму объекту назначен большой вес). Конечно, вы можете поместить идентичные массы в вызов функции. Проверено. За работой


Этот подход предполагает, что вы рассчитали гамму - угол контакта. Это очень просто, если у вас есть полная информация о точке столкновения и форме ваших объектов. Особенно, если хотя бы один мяч

Другие вопросы по тегам