python - 在两个二维物体之间的弹性碰撞中,物体之间的总速度(速度的大小)是否守恒?

标签 python geometry pygame game-physics

问题

在一个封闭的系统中,移动的二维圆形物体(它们具有质量和速度属性)以完美的弹性彼此碰撞,是所有物体的总 velocity 速度(速度的大小)在系统内守恒?

背景

我正在基于 this Stack Overflow question 中概述的碰撞解决方法在 Python 中实现一个简单的二维物理引擎。 .我的期望是总速度(与每个物体相关的速度矢量的长度之和)在两个物体碰撞时应该保持恒定,我根据这个期望为我的分辨率方法设计了一个单元测试。但是我发现我的测试失败了。所以我想首先确定我的假设是否正确。

如果它是正确的,我邀请你检查我的代码并解释为什么测试失败:

冲突解决

class Physics:

    @staticmethod
    def reflect_colliding_circles(
        (c1_x, c1_y, c1_vx, c1_vy, c1_r, c1_m, c1_e),
        (c2_x, c2_y, c2_vx, c2_vy, c2_r, c2_m, c2_e)):
        # inverse masses, mtd, restitution
        im1 = 1.0 / c1_m
        im2 = 1.0 / c2_m
        mtd = Physics.calculate_mtd((c1_x, c1_y, c1_r), (c2_x, c2_y, c2_r))
        normal_mtd = mtd.normalized()
        restitution = c1_e * c2_e

        # impact speed
        v = vec2d(c1_vx, c1_vy) - vec2d(c2_vx, c2_vy)
        vn = v.dot(normal_mtd)

        # circle moving away from each other already -- return
        # original velocities
        if vn > 0.0:
            return vec2d(c1_vx, c1_vy), vec2d(c2_vx, c2_vy)

        # collision impulse
        i = (-1.0 * (1.0 + restitution) * vn) / (im1 + im2)
        impulse = normal_mtd * i

        # change in momentun
        new_c1_v = vec2d(c1_vx, c1_vy) + (impulse * im1)
        new_c2_v = vec2d(c2_vx, c2_vy) - (impulse * im2)

        return new_c1_v, new_c2_v

    @staticmethod
    def calculate_mtd((c1_x, c1_y, c1_r), (c2_x, c2_y, c2_r)):
        """source: https://stackoverflow.com/q/345838/1093087"""
        delta = vec2d(c1_x, c1_y) - vec2d(c2_x, c2_y)
        d = delta.length
        mtd = delta * (c1_r + c2_r - d) / d
        return mtd

单元测试

def test_conservation_of_velocity_in_elastic_collisions(self):
    for n in range(10):
        r = 2
        m = 10
        e = 1.0

        c1_pos = vec2d(0, 0)
        c1_v = vec2d(random.randint(-100,100), random.randint(-100,100))

        c2_delta = vec2d(random.randint(-100,100), random.randint(-100,100))
        c2_delta.length = random.randint(50, 99) * r / 100.0
        c2_pos = c1_pos + c2_delta
        c2_v = vec2d(random.randint(-100,100), random.randint(-100,100))

        c1_np, c2_np = Physics.translate_colliding_circles(
            (c1_pos.x, c1_pos.y, r, m),
            (c2_pos.x, c2_pos.y, r, m))

        c1_nv, c2_nv = Physics.reflect_colliding_circles(
            (c1_np.x, c1_np.y, c1_v.x, c1_v.y, r, m, e),
            (c2_np.x, c2_np.y, c2_v.x, c2_v.y, r, m, e))

        old_v = c1_v.length + c2_v.length
        new_v = c1_nv.length + c2_nv.length

        self.assertTrue(Physics.circles_overlap(
            (c1_pos.x, c1_pos.y, r), (c2_pos.x, c2_pos.y, r)))
        self.assertTrue(old_v - new_v < old_v * .01)

我正在使用这个 pygame 向量类:http://www.pygame.org/wiki/2DVectorClass

最佳答案

无论碰撞的弹性如何,总动量 都是守恒的。总速度显然不是。严格来说,速度是一个矢量,很容易看出它会随着矢量的变化而变化:例如,一个球从不可移动的垂直壁上弹性弹回,其速度变为恰恰相反。

关于python - 在两个二维物体之间的弹性碰撞中,物体之间的总速度(速度的大小)是否守恒?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13639017/

相关文章:

java - 查找点是否在三角形内(2D)

python - ' bool 对象不可调用'pygame

python - 如何将表面的右上角传递给矩形?

python - 尝试获取字段值时,django-rest-framework 获取属性错误

python - 如何在 QLabel 中设置文本并显示 '<>' 个字符?

python - 如何在Python表格中拥有多行单元格?

java - Graphics2D 渲染太慢?

python - 如何使用 Python 获取 oauth2 access_token

java - 矩形与从中心点绘制的直线之间的截距

python - 播放歌曲后如何让pygame退出