模拟一个简单的物理相关场景

发布于 2024-11-02 01:43:27 字数 530 浏览 7 评论 0原文

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

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

其中 n 是当前的时间步长, pi_n 表示 i 在时间步 n 的位置,|| 表示幅度计算,(pj_n - pi_n) 表示向量减法。

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

time-step particle position(x,y)

有人可以给我一些建议吗?

I am a total beginner in both simulations so this question might be silly. If so, please feel free to edit it. I am trying to simulate the following scenario in Python. I randomly place a few small particles in a 2D field with fixed dimentions. Each particle has a radius of effect r. If the first particle has the second one within its radius of effect, then a force has to be applied on both the particles (the effect that the first one has on the second and vice versa) and my force function is defined as:

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

where n is the time step currently, pi_n represents the position of i at time step n and || represents magnitude calculation and (pj_n - pi_n) represents vector subtraction.

I was wondering if there are any libraries that simplify this stuff for me. All I need is basically the following:

time-step particle position(x,y)

Does anyone have some suggestions for me please?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

白衬杉格子梦 2024-11-09 01:43:27

谷歌搜索python库向量2d返回http://www .super effective.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

这是欧拉积分,其属性非常糟糕,但对于游戏。

Googling for python library vector 2d returned http://www.supereffective.org/pages/Vector-2d-Vector-Library as the top hit, which seems like a competent library (containing projection-and-perpendicularization, normalization, rotation, scaling, etc.)

As long as the number of particles isn't too large, this should work just fine in combination with an integration scheme. e.g. you keep track of each particle's (pos, vel) and perhaps also accel vectors, and use:

F = m a

-> F = m dv/dt

-> dv/dt = F/m

and thus

dv ~= dt*F/m

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

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

This is Euler integration which has pretty bad properties, but is okay for a game.

謌踐踏愛綪 2024-11-09 01:43:27

我真的很喜欢 pymunk 物理库,它是花栗鼠的包装器物理图书馆。

首先,需要初始化库:

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)

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

I really like the pymunk physics library, a wrapper for the chipmunk physics library.

First of all, the library needs to be initialized:

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

To achieve something the likes you have requested you have to create a Body and a Circle shape for each particle you wish to create.

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)

The particles will not collide with each other, beacause the sensor flag is set to True. The radius is now somewhat of an area of influence.

Now, we create a callback function for particles which have an overlapping area of influence:

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)

The callback is set in the space:

space.set_default_collision_handler(near_callback, near_callback, None, None, None)

Of course, the space has to be "stepped" for each time-frame:

space.step(dt)

I hope this was somewhat understandable and helpful.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文