用numpy-matplotlib-python模拟弹丸运动

2024-04-25 00:03:12 发布

您现在位置:Python中文网/ 问答频道 /正文

我试着从不同的角度绘制一个射弹穿越时间的图表。角度范围从25到60,每个初始角度在图上应有自己的线。“弹丸在空中的总时间”的公式是t的公式。我不确定这个总时间是如何起作用的,因为我应该用不同的初始角度在不同的时间绘制弹丸。我想我需要x,x1,x2,x3,x4,x5和y等价物来绘制所有六个不同角度的图形。但我不知道该怎么处理这段时间。

import numpy as np 
import matplotlib.pylab as plot 

#initialize variables 
#velocity, gravity
v = 30 
g = -9.8 
#increment theta 25 to 60 then find  t, x, y
#define x and y as arrays 
theta = np.arange(25,65,5)   

t = ((2 * v) * np.sin(theta)) / g #the total time projectile remains in the #air
t1 = np.array(t) #why are some negative 



x = ((v * t1) * np.cos(theta))
y = ((v * t1) * np.sin(theta)) - ((0.5 * g) * (t ** 2))

plot.plot(x,y)
plot.show()

Tags: theimportplotasnp图表时间绘制
2条回答

首先g是阳性的!修正后,让我们看一些方程式:

你已经知道了,但是让我们花点时间讨论一下。你需要知道什么才能得到粒子的轨迹?

初始速度和角度,对吗?问题是:在给定初始速度为v=somethingtheta=something的情况下,在一段时间后找到粒子的位置。初始值很重要!那是我们开始实验的时候。所以时间是连续的参数!你不需要飞行时间。

还有一件事:角度不能写成60, 45, etc,python需要其他东西才能工作,所以需要用数字形式来编写它们,(0,90)=(0,pi/2)。

让我们看看代码:

import numpy as np
import matplotlib.pylab as plot
import math as m
#initialize variables
#velocity, gravity
v = 30
g = 9.8
#increment theta 25 to 60 then find  t, x, y
#define x and y as arrays

theta = np.arange(m.pi/6, m.pi/3, m.pi/36)

t = np.linspace(0, 5, num=100) # Set time as 'continous' parameter.

for i in theta: # Calculate trajectory for every angle
    x1 = []
    y1 = []
    for k in t:
        x = ((v*k)*np.cos(i)) # get positions at every point in time
        y = ((v*k)*np.sin(i))-((0.5*g)*(k**2))
        x1.append(x)
        y1.append(y)
    p = [i for i, j in enumerate(y1) if j < 0] # Don't fall through the floor                          
    for i in sorted(p, reverse = True):
        del x1[i]
        del y1[i]

    plot.plot(x1, y1) # Plot for every angle

plot.show() # And show on one graphic

enter image description here

你犯了很多错误。

首先,错误较少,但是matplotlib.pylab应该被用来同时访问matplotlib.pyplotnumpy(对于类似于matlab的体验),我认为更建议在脚本中使用matplotlib.pyplot as plt(另请参见this Q&A)。

其次,角度是以度为单位的,但是默认情况下数学函数需要弧度。在将角度传递给三角函数之前,必须将角度转换为弧度。

第三,当前代码将t1设置为每个角度都有一个时间点。这不是您需要的:您需要计算每个角度(在t中所做的)的最大时间t,然后为每个角度创建一个从0t的时间向量,以便绘制!

最后,您需要在y这两个方面使用相同的绘制时间向量,因为这是力学问题的解决方案:

y(t) = v_{0y}*t - g/2*t^2

这假设g是正的,这在代码中又是错误的。除非你把y轴设置为向下,但是“投射物”这个词让我认为情况并非如此。

所以我要做的是:

import numpy as np 
import matplotlib.pyplot as plt 

#initialize variables 
#velocity, gravity
v = 30 
g = 9.81  #improved g to standard precision, set it to positive
#increment theta 25 to 60 then find  t, x, y
#define x and y as arrays 
theta = np.arange(25,65,5)[None,:]/180.0*np.pi #convert to radians, watch out for modulo division

plt.figure()

tmax = ((2 * v) * np.sin(theta)) / g
timemat = tmax*np.linspace(0,1,100)[:,None] #create time vectors for each angle

x = ((v * timemat) * np.cos(theta))
y = ((v * timemat) * np.sin(theta)) - ((0.5 * g) * (timemat ** 2))

plt.plot(x,y) #plot each dataset: columns of x and columns of y
plt.ylim([0,35])
plot.show()

我利用了这样一个事实,即plt.plot将绘制两个矩阵输入对彼此的列,因此不需要循环角度。我还使用[None,:][:,None]分别将1d numpyarrays转换为2d行向量和列向量。通过将行向量和列向量相乘,数组广播确保生成的矩阵按我们希望的方式运行(即timemat的每一列在100步内从0变为对应的tmax

结果:

plot

相关问题 更多 >