我正在尝试编写一个代码,用于绘制从高度h下落的球的模拟,并使用运动方程y = y_0制作一个随时间变化的位置图 我的代码是这样的:
来自matplotlib.pylab import show,xlabel,ylabel,scatter,plot 来自numpy import empty
settings.xml1
然而,我的图表在图形的每个角落中绘制了三个点,当它看起来像一条曲线时,我的图形每次都会改变,因为没有任何变量正在改变
答案 0 :(得分:1)
好的,让我们解决语法错误。 for i in range of (1000-1)
实际上是for i in range(1000-1)
,但我认为这是您的错误,因为您可以运行代码。
现在,你的运动方程是错误的。
y[i+1] = time[i] + (vel[i+1] * dt)
# should be
y[i+1] = y[i] + (vel[i] * dt)
您退出模拟的条件也存在缺陷。
if y[i] > 0:
# you have to stop when the height becomes until negative
if y[i+1] < 0:
到目前为止,您的错误意味着您将在一次迭代后退出循环,实际上没有改变您的y
数组。最后的问题在这里开始了。 numpy.empty()
创建一个数组而不初始化值。这意味着原始值将是该点在内存中的任何值。如果在打破循环后打印y
,您可能会注意到大多数值为0,而有些值非常小,但不接近0,例如3.18377034e-308。由于它们是数组中的最高值,因此它们会将绘图缩放到其范围。但由于它们是任意值,因此每次运行代码时,它都会生成不同的数字。
您有两种方法可以解决此问题。要么使用numpy.zeros()
,要么只绘制第一个y[:i]
值,这是您在击中地面时打破的循环点。
由于我们对您的问题中的方程式有一个解析解,因此您可以取消循环并使用数组对所有内容进行矢量化。我们可以用t(二次方)求解位移方程,以找出我们何时会撞到地面。然后我们初始化时间数组并用它来计算位移(速度是可选的)。
import numpy as np
import matplotlib.pyplot as plt
def time_to_hit_ground(y0, v0, a):
discriminant = np.sqrt(v0**2 - 2*a*y0)
t1 = (-v0 - discriminant) / a
t2 = (-v0 + discriminant) / a
if t1 >=0:
return t1
return t2
def drop(y0, v0=0.0, dt=0.1, g=-9.8):
if y0 < 0:
print('Object is underground.')
return
# if you also allow the user to change `dt` and `g` from the arguments,
# you want to check they have the correct sign.
t_ground = time_to_hit_ground(y0, v0, g)
t = np.arange(0, t_ground+dt, dt)
v = v0 + g * t
y = y0 + v0 * t + g * t**2 / 2.
plt.plot(t, y, '.')
plt.axvline(t_ground, color='g')
plt.axhline(0, color='g')
plt.xlabel('Time (s)')
plt.ylabel('Height (m)')
plt.show()