2016-01-08 220 views
1

我想写一个代码,将绘制一个球从高度h下降的模拟,并使用运动方程y = y_0 我的代码是这样的:随着时间的推移随着时间的推移球的位置下降的情节

从matplotlib.pylab进口展,xlabel,ylabel,散布,情节 从numpy的进口空

def drop(): 

    """ 
    This function calculates and creates arrays for the velocity at eac time interval as well as the position and plots it. Assuming no drag. 
    """ 
    #Define the constants in the problem 
    h_0 = 10 
    g = -9.8 #gravitational constant N 
    dt = 0.1 #timestep 

    #Now need to create arrays to hold the positins, time, and velocities 
    vel = empty(1000,float) 
    time = empty(1000,float) 
    y = empty(1000,float) 

    time[0] = 0 
    vel[0] = 0 
    y[0] = h_0 

    #code for the kinematic equations for the calculation of time, velocity and position 
    for i in range of (1000-1): 
     time[i+1] = time[i] + dt 
     vel[i+1] = vel[i] + (g * dt) 
     y[i+1] = time[i] + (vel[i+1] * dt) 

     if y[i] > 0: 
     #ensures that the graph will not keep going when the ball hits the ground 
      break 


    plot(time,y, '.') 
    xlabel("Time(s)") 
    ylabel("Position") 
    show() 

但是我的图形绘制三个点之一的图时的每个角落它应该看起来像一条曲线,我的图形每次都会改变,因为不是ne的变量正在变化

回答

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]值,这是您打破地面的循环中的点。


由于我们对您的问题方程的解析解,你可以不设循环和vectorise使用数组的一切。我们可以求解关于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() 
相关问题