为什么重力模型中的粒子会相互排斥?

问题描述

所以我试图建立一个简单的重力粒子相互作用模型(稍后我想让它变得更复杂,但现在不是)。

我正在处理 Processing,特别是 processing.py。我创建了 2 个文件一个是主要的设置和绘图功能。另一个是 Particle 类,我在其中定义了粒子属性和重力定律。对于重力,我使用牛顿 F = Gm1m2 / r^2 .

这是主文件

#MAIN --> simulation of a particles system influenced by gravity and temperatures
from particle import Particle

num_particles = 20
particle_array = []

show = False #To show the distance with particles that are interacting (LATER)

def setup():
    size(1000,600)
    for p in range(num_particles):
        p = Particle()
        particle_array.append(p)
    
def draw():
    background(255)
    
    for i in range(len(particle_array)):
        particle_array[i].display()
        #I'm creating another array without the particle considered in the loop. So i can confront the first one with
        #every other particle except itself.
        part_array = [elem for elem in particle_array if elem != particle_array[i]]
        #check interaction with every particles
        for k in range(len(part_array)):
            particle_array[i].check_interaction(part_array[k],show)
    
    #different loops to first determine the acceleration without changing positions
    #and later on updating the positions
    for elem in particle_array: 
        elem.update()
        
    #fill(173,164,164)
    #rect(10,10,20,20) #Show Interactions Box

这是课程: https://pastebin.com/nJJE45Rs

所以发生了什么?当我开始模拟时,坐标发生了一些奇怪的事情。

我收到“ValueError:无法将浮点 NaN 转换为整数”。我试图从它发生的事情中看出,似乎有些坐标随便变成了 NaN 并且 int() 函数崩溃了,因为它无法进行从 NaN 到 int 的转换。所以这很奇怪。 (已解决,见评论

而且看起来粒子的行为方式很奇怪,看起来不像是重力。他们似乎排斥而不是吸引。

对于这个模型的数学,我已经开始从力中获取加速度模块。然后,假设加速度矢量指向另一个粒子(正在计算相互作用的粒子),我必须确定与 x 轴的角度,我将使用该角度来计算 Ax 和 Ay,如下所示:

angle = acos((x2 - x1) / r) #Orientation of the acceleration vector
            print("Angle: " + str(angle) + "x1,y1,x2,y2: " + str(x1) +" "+ str(y1) +" "+ str(x2) +" "+ str(y2),"R: " + str(r))
            #print("New Angle: " + str(angle),"X1; Y1,X2,Y2: " + str(x1) +str(y1) + str(x2) + str(y2))
            ax = a * cos(angle)
            ay = a * sin(angle)
            self.a.add(ax,ay,0) #update acceleration vector

我已经使用了 acos 函数,因为在矩形三角形中:

A = Point (x1,y1)
B = Point (x2,y2)
AB * cos(angle) = (x2 - x1)

但我不知道,事情似乎失败了。

解决方法

我建议完全避免角度。我发现矢量更容易使用。如果以后想知道角度,可以使用 PVector.heading() 方法输出向量和 (0,1) 向量之间的角度。

如果我从头开始制作,我也会将位置转换为向量。由于这会影响您的其他方法,因此我将如何调整您的代码:

(免责声明:我不使用 Python 中的处理,所以我无法运行它来检查错误。如果遇到任何问题,请发表评论)

def check_interaction(self,p2,show_interactions):
    r_vec = PVector(p2.x - self.x,p2.y - self.y) #vector from self to other particle
    if r.mag() < 200:
        if show_interactions: #draw the line
            stroke(110)
            line(self.x,self.y,p2.x,p2.y)
        if 1 < r.magSq():
            grav_acc = G * p2.mass / r_vec.magSq() #acceleration due to the other particle
            r_vec.setMag(grav_acc) #Change magnitude of r_vec so it's now the acceleration vector (due to p2)
            self.a = self.a.add(r_vec) #update acceleration

如果你想转换

self.x = random(screen_width)
self.y = random(screen_height)

self.pos = PVector(random(screen_width),random(screen_height))

def __init__(self) 中,您可以像这样定义 r_vec

r_vec = p2.pos.sub(self.pos)