我在两次模拟中都是初学者,所以这个问题可能很愚蠢。如果是这样,请随时编辑它。我试图在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)
有人对我有什么建议吗?
答案 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)
要获得您所要求的内容,您必须为要创建的每个粒子创建Body
和Circle
形状。
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)
我希望这在某种程度上是可以理解和有用的。