2D弹性球碰撞物理

时间:2016-02-04 20:36:16

标签: 2d physics collision

我正在制作一个涉及弹性球物理的程序。我已经计算出所有与墙壁和静止物体发生碰撞的数学计算,但我无法弄清楚当两个移动的球碰撞时会发生什么。我有质量和速度(x和y速度准确,但每个球的速度和它们的方向都会这样做)并且想要那些公式。记住 - 这是一个完全弹性的碰撞 - 所以没有旋转球等。

2 个答案:

答案 0 :(得分:12)

这个wikipedia article提供了计算两个粒子碰撞后的速度的公式:

使用此公式的原因有很多:

  • 你只需要在碰撞前你的球的速度矢量,它们的质量和位置,
  • 你不需要定义偏离角度,
  • 操作简单(只需要点产品),
  • 矢量可以在任何坐标系中表示。

维基百科文章中没有证据,所以我在下面提供。

问题的定义

enter image description here

对于我们定义的每个球:

  • mi the mass
  • vi 碰撞前的速度矢量
  • v <#39; i 碰撞后的速度矢量
  • Oi中心点
  • xi Oi位置的载体

单位矢量 n 与接触点处球的表面垂直。

单位矢量 t 与接触点处球的表面相切。

使用物理法

总动量守恒表示为:

总动能守恒表示为:

由于在切线方向上没有施加力,碰撞后速度的切向分量不变:

<强>证明

速度的切向分量不变。所以我们可以用正常的组件重写守恒定律,现在我们有一个问题:

动能守恒可以分解,然后通过动量守恒简化:

我们将最后一个表达式与动量守恒结合起来,得到 v&#39; 1 的正常分量:

最后,我们找到 v&#39; 1 的维基百科文章的公式:

v&#39; 2 的公式是对称的。

答案 1 :(得分:1)

由于我正在对blobby进行翻拍,因此主体不一定是球形-命中角与X1,X2之间的距离无关。所以我从中使用方程式: https://williamecraver.wixsite.com/elastic-equations enter image description here

下面的

是根据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

该功能是指球和墙。这只是一个提示,以防您要使用相同的方程式(默认的重物分配给第二个物体)测试墙的反弹。您当然可以在函数调用中添加相同的质量。 经过测试。工作中


此方法假设您已计算出Gamma(接触角)。如果您具有碰撞点和对象形状的完整信息,这很容易出错。尤其是如果至少一个是球