【问题标题】:Using python to simulate 2D elastic collisions使用python模拟2D弹性碰撞
【发布时间】:2020-05-17 17:12:25
【问题描述】:

我用 Python 3 编写了一个脚本来模拟二维的弹性碰撞。 我不知道我做错了什么,因为当我运行它时,这些球似乎相互粘连,有时会出现故障以成为一个球。另外,当一个球碰到屏幕的任何边缘时,它会弹开,但是当另一个球粘在上面时,它会导致其中一个球离开屏幕。

Eqautions that I used

代码片段:

class Particle(Sprite):
    def __init__(self, image):
        super(Particle, self).__init__(image)
        self.Vxi, self.Vyi = random.randint(-3, 3), random.randint(-3, 3)
        self.mass = random.randint(1, 100) / 1000

        self.schedule_interval(self.update, 1/60)

    def update(self, dt):
        self.xpos, self.ypos = self.position

        if self.xpos <= self.width/2 or self.xpos >= scr_width - self.width/2:
            self.Vxi *= -1
        if self.ypos <= self.width/2 or self.ypos >= scr_height - self.height/2:
            self.Vyi *= -1

        for particle in director.scene.children[0][1].particles:
            particle_xpos, particle_ypos = particle.position

            if abs(self.xpos - particle_xpos) <= self.width/2 + particle.width/2:
                if abs(self.ypos - particle_ypos) <= self.height/2 + particle.height/2:
                    xmomentum = (particle.mass * particle.Vxi) + (self.mass * self.Vxi)
                    ymomentum = (particle.mass * particle.Vyi) + (self.mass * self.Vyi)
                    Vxf = (xmomentum - particle.mass * (self.Vxi - particle.Vxi)) / (particle.mass + self.mass)
                    Vyf = (ymomentum - particle.mass * (self.Vyi - particle.Vyi)) / (particle.mass + self.mass)
                    self.Vxi = Vxf
                    self.Vyi = Vyf

        self.xpos += self.Vxi
        self.ypos += self.Vyi
        self.position = self.xpos, self.ypos

【问题讨论】:

  • 你在哪里定义scr_widthscr_height
  • 目前尚不清楚这是物理相关问题还是编码问题。如果是物理问题,这可能不是获得答案的地方,因为这个论坛专注于编码问题。
  • 是编码相关的问题,scr_width和scr_height分别定义为640和480。

标签: python cocos2d-iphone physics


【解决方案1】:

我想你忘了在碰撞时更新另一个粒子的速度。

之前

self.Vxi = Vxf
self.Vyi = Vyf

应该还有

particle.Vxi = Vxf + (self.Vxi - particle.Vxi)
particle.Vyi = Vyf + (self.Vyi - particle.Vyi)

风格明智,我认为变量可以更好地命名。粒子对象不应具有名为VxiVxf 的属性。就物理粒子而言,它只有一个速度。初始/最终速度的概念与数值模拟相关,粒子类的属性不应该对其进行建模。在您当前的代码中,self 的“最终”速度会更新为其初始速度,这可能会造成混淆。

初始速度(VxiVyi)应取自update开头的self.Vxself.Vy。最后,VfxVfy 应更新为 self.Vxself.Vy

此外,最好在局部变量中指出它是哪个粒子,例如V1_x_initialV2_x_initial 等。

【讨论】:

  • 从逻辑上讲,我认为当粒子 A 和粒子 B 碰撞时,它们都会运行更新函数来计算它们的最终速度,那么为什么粒子 A 也计算粒子 B 的速度呢?
  • 因为在这种情况下,当其他粒子转动时,该粒子的速度已经是它的碰撞后更新速度
  • 我知道 Sprite 如何管理此问题,但您可能需要检查并跳过每次更新中已处理的对。我没有在您的代码中看到另一个粒子的位置也没有更新 - 您也需要这样做。
  • 这是一个非常好的观点,因为一个粒子被更新,然后另一个粒子被更新,所以初始速度可能不一样。在这种情况下,我可以使用多处理来让每个粒子同时更新吗?
  • 哦,你绝对的传奇xcmkz!我已经添加了这两行代码,现在所有的故障都消失了!谢谢!
猜你喜欢
  • 1970-01-01
  • 2016-05-14
  • 2013-03-07
  • 1970-01-01
  • 1970-01-01
  • 2021-09-26
  • 2014-02-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多