python - 粒子与盒子内壁的碰撞

标签 python matplotlib physics particles

我想模拟盒子内的粒子运动。当粒子撞击盒子中 4 个墙壁之一时,我希望它们反弹回来。弹性碰撞【碰撞后速度变化图】[1]

编辑

添加了更多代码。更改了 (x,y,z) 限制的测试。我知道当粒子撞击墙壁时,平行于墙壁的速度将保持不变,但垂直于墙壁的速度将变为 -v_perpendillary_vel_before

完整代码

fig0 = plt.figure()
fig1 = plt.figure()

n = 1000 # time steps

M = 1000. #[kg]
N = 1000 #10**5 
a = 0

最佳答案

我无法重现运行,因为您还没有发布完整的代码;我是通过目视检查来做到这一点的。

除此之外,您还没有定义变量k、T、m,因此我不知道速度的大小。上限是否足够高以使粒子完全跳过碰撞?如果 v*dt > tol*2,则完全可以错过碰撞。当我编写这样的代码时,我确保 tol 受到最大变化的限制。

除此之外,您的位置更新是正确的。

当您使用单个粒子运行此程序时会发生什么?你能让它从三堵墙上弹开吗?当你手工编码两个粒子沿单一维度相互直冲时会发生什么?我想您在加载 10000 个粒子之前测试了这些基本功能。

我不确定您的代码中的L是什么;我唯一合理的想法是它是盒子尺寸的上限,我在你的绘图上将其读为 1.2^10-6。

我发现的最大问题是您的唯一碰撞检查是针对盒子的 x+ 侧。你还没有检查任何东西的其他维度或下限(0?),并且没有一个粒子与另一个粒子的比较。因此,您将得到的唯一变化是让大约一半的粒子撞击右侧墙壁 (x+) 并反转方向。除此之外,一切都将永远漂移,x 值不断减小。

<小时/>

处理弹跳

首先,使速度和位置表达式彼此同步:每个表达式都应该是一个三元组(元组或列表),以便您可以将它们一起索引。目前,您将它们作为粒子列表的第二个索引(好主意),但在其他地方有三个单独的变量(坏主意)。相反,使 newVel 成为一个列表,这样您就可以简单地循环遍历粒子并更新:

for dim in range(3):
    if r[i, dim] < tol or        # hit the lower wall
       r[i, dim] > b - tol:      # hit the upper wall
        v[i, dim] = -v[i, dim]

另外,请适当更新职位;不需要涉及本地临时变量:

for dim in range(3):
    r[i, dim] += v[i, dim] * dt
<小时/>

编写一些服务函数

编写一些通用函数通常会有所帮助,只是为了让它们在您编写主代码时不妨碍您。目前,您正在处理很多细节,而您应该一次只担心一种技术。例如,由于您要处理粒子碰撞,因此您需要进行距离计算。不要将其保留在事件代码的中间;只需编写一个函数即可完成此操作。例如:

def dist(a, b):      # a, b are positions: triples of coordinates
    return math.sqrt(sum([(a[dim] - b[dim])**2 for dim in range(3)]))

我不会评论如何实现粒子碰撞,因为您还没有表现出任何解决问题的努力,而且您还没有到攻击该扩展的地步。首先,让这部分工作:一个粒子弹跳,然后两个粒子弹跳,然后可能是 4 个粒子,以表明您可以对任意数量的粒子执行此操作。

一旦你有了这个,你就可以担心粒子碰撞了。 你达到这一点时,好好尝试一下;如果您遇到困难,请发布新问题。

关于python - 粒子与盒子内壁的碰撞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40186702/

相关文章:

python - 逐行构建 pyarrow 表的最快方法

python - 绘制鼠标移动 Python

python - 增加决策树中节点的大小

java - 如何修复碰撞响应中的圆圈重叠?

python - Windows 上的 Virtualenv 和 Komodo IDE 6

python - reStructuredText:如何在表格中使用续行?

python - Matplotlib 用标记而不是箭头进行注释

android - 计算正在运行的车辆的 x 加速度(东)和 y 加速度(北)

c# - 在C#中实现牛顿万有引力定律

python - 为什么在 Python 2.x 中使用 msvcrt 时会出现 IOError?