模拟简单的物理相关场景

时间:2011-04-19 17:04:45

标签: python physics

我在两次模拟中都是初学者,所以这个问题可能很愚蠢。如果是这样,请随时编辑它。我试图在Python中模拟以下场景。我随机将一些小颗粒放置在具有固定尺寸的2D场中。每个粒子的效果半径为r。如果第一个粒子在其效果半径内有第二个粒子,则必须在两个粒子上施加一个力(第一个粒子对第二个粒子的影响,反之亦然),我的力函数定义为:

f(i,j)_n = (r - |pi_n - pj_n|)((pj_n - pi_n)/|pi_n - pj_n|)

其中n是当前的时间步长,pi_n表示i在时间步n的位置,||表示幅度计算和{{1}表示向量减法。

我想知道是否有任何库可以为我简化这些内容。我所需要的只是以下内容:

(pj_n - pi_n)

有人对我有什么建议吗?

2 个答案:

答案 0 :(得分:2)

Google搜索python library vector 2d返回http://www.supereffective.org/pages/Vector-2d-Vector-Library作为最高点,这似乎是一个称职的库(包含投影和垂直化,标准化,旋转,缩放等)

只要粒子的数量不是太大,这应该与集成方案结合使用。例如你跟踪每个粒子的(pos,vel),也许还有加速矢量,并使用:

F = m a

- > F = m dv/dt

- > dv/dt = F/m

因此

dv ~= dt*F/m

- > v' - v ~= dt*F/m

- > ball.vel += timeStep*sum(ball.force(n) for n in ball.neighbors())/ball.mass

这是Euler整合,它具有相当糟糕的属性,但对游戏来说还可以。

答案 1 :(得分:1)

我非常喜欢pymunk物理库,它是chipmunk物理库的包装器。

首先,需要初始化库:

import pymunk
pymunk.init_pymunk()
space = pymunk.Space()
space.gravity = (0.0, -100.0)

要获得您所要求的内容,您必须为要创建的每个粒子创建BodyCircle形状。

mass = 1
radius = 14
inertia = pymunk.moment_for_circle(mass, 0, radius, (0,0))
body = pymunk.Body(mass, inertia)
x, y = random.randint(0, 200), random.randint(0, 200)
body.position = x, 550
shape = pymunk.Circle(body, radius, (0,0))
shape.sensor = True
space.add(body, shape)

由于sensor标志设置为True,因此粒子不会相互碰撞。半径现在有点影响。

现在,我们为具有重叠影响区域的粒子创建回调函数:

def near_callback(space, arbiter, *args, **kwargs):
    body_i = arbiter.shapes[0].body
    body_j = arbiter.shapes[1].body

    # calculate the forces force_i and force_j with your formula
    ...

    body_i.apply_force(force_i)
    body_j.apply_force(force_j)

回调是在space

中设置的
space.set_default_collision_handler(near_callback, near_callback, None, None, None)

当然,space必须为每个时间框架“步进”:

space.step(dt)

我希望这在某种程度上是可以理解和有用的。