我正在尝试构建一个函数,该函数将计算给定时间步长的物体的牛顿引力定律(G * M / r ^ 2),同时能够改变该点的位置和速度。
作为一个例子,我将尝试展示我所做的设置初始速度和点的起始位置(但是我会在某些时候需要能够实时显示该点并移动它循环正在运行。)
我写了两个试图证明我遇到麻烦的例子。
如果仔细观察图表,您可能会注意到这两行不重叠(即使所有起始参数都相同)。
打印输出:
概念1 (计算间隔= 1秒):
v:9.82 pos:9.82
v:19.64 pos:29.46
v:29.46 pos:58.93
v:39.28 pos:98.22
概念2 (计算间隔= 1秒):
v:0.0 pos:0.0
v:9.82 pos:4.91
v:19.64 pos:19.64
v:29.46 pos:44.20
根据此online calculator,它表示Concept1不正确,而Concept2非常接近实际。
以下代码绘制了两个示例。我添加了两个变量,可以设置initial_velocity
和initial_position
(请参阅下面的其他两个情节图片了解详情)。
import numpy as np
import matplotlib.pyplot as plt
G = 6.67408 * 10 ** -11 # Newton meters^2/kg^2
Me = 5.9736 * 10 ** 24 # mass of earth in kg
Re = 6.371 * 10 ** 6 # radius of earth in meters
def get_g(mass, distance, seconds):
_g = G * mass / distance ** 2
_d = (_g * (seconds ** 2)) / 2
_v = _g * seconds
return _v, _d, _g
def Concept1(seconds=1, timestep=0.1):
plt_x = np.linspace(0, seconds, (seconds/timestep))
plt_y = np.zeros_like(plt_x)
"""
Simple concept demonstrating values that are very close to actual.
Time = 0.1 vel = 0.9822280588290989 pos = 0.049111402941454954 _g = 9.822280588290988
Time = 0.2 vel = 1.9644561176581978 pos = 0.19644561176581982 _g = 9.822280588290988
Time = 0.3 vel = 2.946684176487297 pos = 0.44200262647309463 _g = 9.822280588290988
Time = 0.4 vel = 3.9289122353163957 pos = 0.7857824470632793 _g = 9.822280588290988
"""
for _i in range(len(plt_y)):
t = (_i+1)
_v, _d, _g = get_g(Me, Re, t*timestep)
plt_y[_i] = _d
#print("Time = ", t*timestep, " vel = ", _v, " pos = ", _d, " _g = ", _g)
return plt_x,plt_y
def Concept2(seconds=1, timestep=0.1, initial_velocity=0, initial_position=0):
plt_x = np.linspace(0, seconds, seconds/timestep)
plt_y = np.zeros_like(plt_x, dtype=np.float32)
"""
Dynamic concept showing variable velocity and starting position (output is not accurate)
Time = 0.1 vel = 0.9822280588290989 pos = 0.0982228058829099 _g = 9.822280588290988
Time = 0.1 vel = 1.9644561176581978 pos = 0.2946684176487297 _g = 9.822280588290988
Time = 0.1 vel = 2.9466841764872966 pos = 0.5893368352974594 _g = 9.822280588290988
Time = 0.1 vel = 3.9289122353163957 pos = 0.982228058829099 _g = 9.822280588290988
"""
vel = initial_velocity * timestep
pos = initial_position
for _i in range(len(plt_y)):
t = timestep
_v, _d, _g = get_g(Me, Re, t)
vel += _g * timestep
pos += vel * timestep
plt_y[_i] = pos
#print("Time = ", t, " vel = ", vel, " pos = ", pos, " _g = ", _g)
return plt_x, plt_y
def Concept3(seconds=1, timestep=0.1, initial_velocity=0, initial_position=0):
plt_x = np.linspace(0, seconds, seconds/timestep)
plt_y = np.zeros_like(plt_x, dtype=np.float32)
"""
Dynamic concept showing variable velocity and starting position (output is accurate)
Time = 0.1 vel = 0.982228058829099 pos = 0.049111402941454954 _g = 9.822280588290988
Time = 0.1 vel = 1.964456117658198 pos = 0.19644561176581982 _g = 9.822280588290988
Time = 0.1 vel = 2.9466841764872975 pos = 0.44200262647309463 _g = 9.822280588290988
Time = 0.1 vel = 3.928912235316396 pos = 0.7857824470632793 _g = 9.822280588290988
"""
vel = initial_velocity * timestep
pos = initial_position
gforce = 0
for _i in range(len(plt_y)):
t = timestep
_v, _d, _g = get_g(Me, Re, t)
vel += (gforce + _g)*timestep**2/2
pos += vel
gforce = _g
plt_y[_i] = pos
#print("Time = ", t, " vel = ", (vel + _d)/timestep, " pos = ", pos, " _g = ", gforce)
return plt_x, plt_y
seconds=1
timestep=0.1
initial_velocity = 0
initial_position = 0
x1, y1 = Concept1(seconds=seconds, timestep=timestep)
x2, y2 = Concept2(seconds=seconds, timestep=timestep, initial_velocity=initial_velocity, initial_position=initial_position)
x3, y3 = Concept3(seconds=seconds, timestep=timestep, initial_velocity=initial_velocity, initial_position=initial_position)
plt.xlabel("Time (Seconds)")
plt.ylabel("Distance")
plt.plot(x1, y1,'g', label='Concept 1 (gauge)')
plt.plot(x2, y2,'b', label='Concept 2')
plt.plot(x3, y3,'r', label='Concept 3')
plt.legend(loc='upper left')
plt.show()
我对物理学比较陌生(这是一种学习经历)。我一直想知道我的方法是否可能不正确。如果是这样,我真的想了解更多如何实现这一目标。我们很乐意留意所有建议。谢谢你!
显示initial_position = 100000 的情节
[UPDATE]
在代码中添加了Concept3。
我“认为”它通过在每个循环迭代中将当前gforce值存储在变量中来实现我所需要的。
然后我将它添加到当前的gforce值并将其除以2。 之后我更新当前的速度。