Python 2.7 Runge Kutta Orbit GUI [英] Python 2.7 Runge Kutta Orbit GUI
问题描述
我正在尝试使用Tkinter在Python中创建GUI,以使用Runge-Kutta方法绘制质量轨道的轨迹.我的GUI工作正常,但是我的问题是,无论我向GUI输入什么值,它都只能绘制一条直线. 我希望有人能向我展示GUI中我的功能出了什么问题,以便它实际上能正确绘制出轨迹.
I'm trying to create a GUI in Python using Tkinter that plots the orbital path of a mass using the Runge-Kutta method. My GUI works fine but my issue is that it only plots a straight line no matter what values I input to the GUI. I was hoping someone could show me what is wrong with my function within the GUI so that it will actually plot the orbit properly.
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()
推荐答案
您的物理学是错误的.而且您对运动方程的处理是错误的.
Your physics is wrong. And your treatment of the motion equation is wrong.
力计算为
Force = lambda pos: -G*m*M/(norm2(pos)**3)*pos
运动方程为
m·pos''(t)=力(pos(t))
m·pos''(t) = Force(pos(t))
其中
pos''(t)=d²/dt²pos(t)
pos''(t) = d²/dt² pos(t)
您必须将其转换为一阶系统
which you have to transform into a first order system
[ pos' , vel' ] = [ vel, Force(pos)/m ]
现在,您可以将RK4方法应用于该一阶系统.
To this first order system you can now apply the RK4 method.
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
向量如何在位置和速度之间交织.
Note how the k
vectors interleave between position and velocity.
或者您可以使用来自动执行正确的RK4实施
Or you can make the correct RK4 implementation automatic using
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
.
这篇关于Python 2.7 Runge Kutta Orbit GUI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!