我用 python 创建了一个小的粒子可视化。
我正在计算零重力二维空间中粒子的运动。
每个粒子都会根据粒子质量和距离吸引所有其他粒子。
我在 pygame 中做了一个可视化,一切都按计划进行(通过计算),但是我需要极大地优化计算。如今,该系统可以在相当好的帧速率下计算大约 100-150 个粒子。我将所有计算放在一个单独的线程中,这给了我更多的计算,但远不是我想要的。
我看过 scipy 和 numpy 但由于我不是科学家或数学大师,我只是感到困惑。看起来我走在正确的轨道上,但我不知道如何做。
我需要计算所有粒子对循环的所有吸引力。
因为我需要找出是否有碰撞,所以我必须再次做同样的事情。
写出这样的代码让我心碎......
Numpy 能够使用数组计算数组,但是我还没有找到任何方法来计算数组中的所有项目以及同一/另一个数组中的所有项目。有吗?
如果是这样,我可以创建几个数组并计算得更快,并且必须有一个函数可以从两个数组中获取索引,其中它们的值匹配(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)
您可以首先尝试与复数:在这种形式中,相关的引力和动力学公式非常简单,并且也可以相当快(因为NumPy可以在内部进行计算,而不是单独处理x和y坐标)。例如,z 和 z' 处两个粒子之间的力很简单:
(z-z')/abs(z-z')**3
对于所有 z/z' 对,NumPy 可以非常快速地计算出这样的数量。例如,所有 z-z' 值的矩阵只需从一维数组中获得Z
坐标为Z-Z[:, numpy.newaxis]
(对角线项 [z=z'] 在计算时确实需要特别小心1/abs(z-z')**3
:它们应该设置为零)。
至于时间演变,你当然可以使用SciPy 的快速微分方程例程:它们比逐步欧拉积分精确得多。
无论如何,深入研究 NumPy 将非常有用,特别是如果您打算进行科学计算,因为 NumPy 非常快。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)