【发布时间】:2011-10-30 05:39:07
【问题描述】:
我已经在 python 中创建了一个小的粒子可视化。 我正在计算粒子在零重力的二维空间中的运动。 因为每个粒子根据粒子质量和距离吸引所有其他粒子。
我在 pygame 中进行了可视化,一切都按计划进行(使用计算),但是我需要优化计算。今天,该系统可以以正常的帧速率计算大约 100-150 个粒子。我把所有的计算放在一个单独的线程中,这给了我更多但不是我想要的。
我看过 scipy 和 numpy,但由于我不是科学家或数学大师,我只是感到困惑。看起来我在正确的轨道上,但我不知道如何做。
我需要计算所有粒子上的所有吸引力,我必须在一个循环中循环。 因为我需要找出是否有碰撞,所以我必须重新做同样的事情。
写这样的代码让我心碎....
Numpy 有能力用数组计算数组,但是我还没有找到任何东西来计算数组中的所有项目以及来自相同/另一个数组的所有项目。有吗? 如果是这样,我可以创建几个数组并计算得更快,并且必须有一个函数可以从它们的值匹配的 2 个数组中获取索引(Collitiondetect iow)
这是今天的吸引力/碰撞计算:
class Particle:
def __init__(self):
self.x = random.randint(10,790)
self.y = random.randint(10,590)
self.speedx = 0.0
self.speedy = 0.0
self.mass = 4
#Attraction
for p in Particles:
for p2 in Particles:
if p != p2:
xdiff = P.x - P2.x
ydiff = P.y - P2.y
dist = math.sqrt((xdiff**2)+(ydiff**2))
force = 0.125*(p.mass*p2.mass)/(dist**2)
acceleration = force / p.mass
xc = xdiff/dist
yc = ydiff/dist
P.speedx -= acceleration * xc
P.speedy -= acceleration * yc
for p in Particles:
p.x += p.speedx
p.y += p.speedy
#Collision
for P in Particles:
for P2 in Particles:
if p != P2:
Distance = math.sqrt( ((p.x-P2.x)**2) + ((p.y-P2.y)**2) )
if Distance < (p.radius+P2.radius):
p.speedx = ((p.mass*p.speedx)+(P2.mass*P2.speedx))/(p.mass+P2.mass)
p.speedy = ((p.mass*p.speedy)+(P2.mass*P2.speedy))/(p.mass+P2.mass)
p.x = ((p.mass*p.x)+(P2.mass*P2.x))/(p.mass+P2.mass)
p.y = ((p.mass*p.y)+(P2.mass*P2.y))/(p.mass+P2.mass)
p.mass += P2.mass
p.radius = math.sqrt(p.mass)
Particles.remove(P2)
【问题讨论】:
-
你考虑过Psyco或Writing C/C++ module吗?
-
本文回顾了优化引力模拟的常用方法,包括 Barnes-Hut。专业人士通常在 3D 中进行,但我相信 2D 案例都是类似的。 cs.hut.fi/~ctl/NBody.pdf
-
如果您对数学不满意(“我不是科学家或数学大师,我只是感到困惑”),那么我认为您需要寻找一个可以做到这一点的库。见stackoverflow.com/questions/6381137/python-physics-librarystackoverflow.com/questions/2298517/…
-
@nagisa 我会更深入地了解 Psyco,感谢您提供的链接。它可能最终会导致我编写一个 c/c++ 模块,但首先我想了解它是如何工作的。
-
@Russell Borogove 谢谢,现在我的睡前阅读已经整理了一段时间
标签: python optimization numpy physics