【问题标题】:2D Elastic Ball Collision Physics2D 弹性球碰撞物理
【发布时间】:2016-05-14 15:51:29
【问题描述】:

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

【问题讨论】:

标签: 2d physics collision


【解决方案1】:

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

使用这个公式的原因有很多:

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

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


问题的定义

对于我们定义的每个球:

  • 弥撒
  • vi 碰撞前的速度矢量
  • v'i 碰撞后的速度向量
  • Oi 中心点
  • xi Oi 位置的向量

单位向量n在接触点垂直于球的表面。

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


要使用的物理定律

总动量守恒表示为:

总动能守恒表示为:

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


证明

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

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

我们将最后一个表达式与动量守恒结合起来,得到 v'1 的法线分量:

最后,我们找到了 v'1 的维基百科文章的公式:

v'2的公式是对称的。

【讨论】:

【解决方案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

函数是指球和墙。这只是一个提示,以防您想使用相同的方程式测试墙壁弹跳(第二个对象分配了默认的重权重)。您当然可以在函数调用中放置相同的质量。 经过测试。工作


这种方法假设您计算了 Gamma - 接触角。如果您拥有对象的碰撞点和形状的完整信息,这很容易失败。特别是如果至少有一个是球

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-18
    • 2018-01-28
    • 1970-01-01
    • 2010-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多