Python 2.7 Python 2.7龙格库塔轨道GUI

Python 2.7 Python 2.7龙格库塔轨道GUI,python-2.7,runge-kutta,orbital-mechanics,Python 2.7,Runge Kutta,Orbital Mechanics,我正在尝试使用Tkinter在Python中创建一个GUI,它使用Runge-Kutta方法绘制质量的轨道路径。我的GUI工作正常,但我的问题是,无论我向GUI输入什么值,它都只绘制一条直线。 我希望有人能告诉我GUI中的函数有什么问题,这样它就能正确地绘制轨道 def calcPath(self): M = float(self.entM.get()) m = float(self.entm.get()) G = 6.67e-11 c = 3e8

我正在尝试使用Tkinter在Python中创建一个GUI,它使用Runge-Kutta方法绘制质量的轨道路径。我的GUI工作正常,但我的问题是,无论我向GUI输入什么值,它都只绘制一条直线。 我希望有人能告诉我GUI中的函数有什么问题,这样它就能正确地绘制轨道

def calcPath(self):
    M = float(self.entM.get())
    m = float(self.entm.get())
    G = 6.67e-11
    c = 3e8



    velocity = np.array([float(self.entvx.get()),float(self.entvy.get()),float(self.entvz.get())])
    pos = np.array([float(self.entx.get()), float(self.enty.get()), float(self.entz.get())])

    Force = lambda pos: (G*m*M/(pos**2))

    #assigning variables empty lists to append x, y and z values to
    a = [] 
    b = []
    c = []
    t = 0.0
    tf = float(self.enttf.get())
    dt = float(self.entdt.get())

    while t < tf: # creating a while loop to trace the path for a set period of time
        #using the Runge-kutta formula from the problem sheet to assign variables at different steps and half steps 
        k1v=(dt*Force(pos))/m
        k2v=(dt*Force(pos+(k1v/2.0)))/m 
        k3v=(dt*Force(pos+(k2v/2.0)))/m 
        k4v=(dt*Force(pos+k3v))/m
        velocity=velocity+(k1v/6.0)+(k2v/3.0)+(k3v/3.0)+(k4v/6.0) #calaculating the weighted average of the k values
        pos=pos+velocity*dt #velocity is not a function of space or time so it will be identical at all 4 k values

        a.append(pos[0]) # appending the lists for each vaiable to produce a plot
        b.append(pos[1])
        c.append(pos[2])
        t = t+dt # setting the time steps

    #generating the path plot figure and formatting it    
    ax = Axes3D(self.fig) #creating a 3D figure 
    ax.set_title("Path of planetary mass") #produces title on the figure
    ax.plot3D(a,b,c, color='darkviolet', label='Runge-kutta path method') 
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    ax.set_zlabel('z')
    ax.legend(loc='lower left') #selecting the location of legend
    self.canvas.show()
def calcPath(自身):
M=float(self.entM.get())
m=float(self.entm.get())
G=6.67e-11
c=3e8
velocity=np.array([float(self.entvx.get())、float(self.entvy.get())、float(self.entvz.get()))
pos=np.array([float(self.entx.get())、float(self.enty.get())、float(self.entz.get()))
力=λ位置:(G*m*m/(位置**2))
#分配变量空列表以向其附加x、y和z值
a=[]
b=[]
c=[]
t=0.0
tf=float(self.enttf.get())
dt=float(self.entdt.get())
while t
你的物理错误。你对运动方程的处理是错误的

原力计算为

Force = lambda pos: -G*m*M/(norm2(pos)**3)*pos
运动方程是

m·位置“”(t)=力(位置(t))

在哪里

位置“”(t)=d²/dt²位置(t)

你必须把它转换成一阶系统

[ pos' , vel' ] = [ vel, Force(pos)/m ]
对于这个一阶系统,现在可以应用RK4方法

    k1p = dt *       vel
    k1v = dt * Force(pos        ) / m
    k2p = dt *      (vel+0.5*k1v) 
    k2v = dt * Force(pos+0.5*k1p) / m 
    k3p = dt *      (vel+0.5*k2v) 
    k3v = dt * Force(pos+0.5*k2p) / m 
    k4p = dt *      (vel+    k3v)
    k4v = dt * Force(pos+    k3p) / m
    pos = pos + (k1p+2*k2p+2*k3p+k4p)/6.0 
    vel = vel + (k1v+2*k2v+2*k3v+k4v)/6.0 
注意
k
矢量如何在位置和速度之间交错


或者,您可以使用

System = lambda pos, vel : vel, Force(pos)/m
然后进入时间循环

    k1p, k1v = System( pos           , vel           )
    k2p, k2v = System( pos+0.5*k1p*dt, vel+0.5*k1v*dt )
    k3p, k3v = System( pos+0.5*k2p*dt, vel+0.5*k2v*dt )
    k3p, k3v = System( pos+    k3p*dt, vel+    k3v*dt )
    pos = pos + (k1p+2*k2p+2*k3p+k4p)*dt/6.0 
    vel = vel + (k1v+2*k2v+2*k3v+k4v)*dt/6.0 


如果你只是想要数值解,也就是说,不必证明你可以实现RK4,那么就使用
scipy.integrate.ode
scipy.integrate.odeint

不确定,但是
pos[0]
(和其他人)是否可能对所有迭代使用相同的引用,导致
a
b
c
中的值相同?我已将力函数更改为在位置数组上使用np.square,但不幸的是,在运行时它仍然只绘制一条直线。您可以
打印(id(位置[0])吗
在每次迭代中,看看它是否产生相同的数字?您导入了哪些模块?它使用了无效的语法,即m*pos'=Force(pos),这不是python,而是微分方程的ASCII表示形式。
m·d²/dt²pos(t)=m·pos''(t)=F(pos t))
norm2
numpy.linalg.norm
。可以用
np.dot(pos,pos)替换
norm2(pos)**3
**1.5
。这避免了
numpy.linalg.norm
中的范数类型选择逻辑。我已经更正了k1p和k1v等公式,但是我不知道新的vel是如何输入到绘图中的。因为您没有绘制速度,所以不需要在绘图中分别绘制
vel
速度。它对位置的影响是在RK4步骤中的状态更新期间进行erted。