使用Python建模抛射运动

使用Python建模抛射运动

首先,让我们了解一些基本概念和方程,基于这些概念和方程可以对抛射运动进行建模。下面显示的图解释了抛射运动的一些基本术语。

使用Python建模抛射运动

在这里,”u”是投射物体的速度。𝛼是投射物体的投射角度。弹道是投射物体在飞行过程中所经过的路径。射程是投射物体所行进的最大水平距离。\mathrm{h_{max}}是投射物体所达到的最大高度。此外,投射物体到达射程所花费的时间称为飞行时间。

投射运动可以分为三类−

  • 水平投射。

  • 倾斜投射在水平地面上。

  • 倾斜投射但击中不同高度。

在本教程中,我们将涉及这三种情况。

案例1:水平投射

在第一种情况下,投射物体从一个高处仅具有水平速度(𝑢),在一定距离R后将击中地面,如下图所示。

使用Python建模抛射运动

根据运动方程,h、R和t(飞行时间)之间的关系可以写成:

h = 1/2 * g * t^2

R = ut

要在Python中模拟它,首先我们必须明确给定和所需的内容。为此,我们将从一个问题开始。

示例1

假设一个飞机在高度900米处以均匀的水平速度140米/秒释放一包食物。该包裹落地的水平距离是多少。

在这个问题中,给定h和u,而需要求解R。程序如下:

首先,使用input()函数从用户那里获取数据,并为重力加速度定义一个变量。由于键盘输入存储为字符串,因此将其强制转换为浮点数,将float放在input()前面。

# Input data
h=float(input("Enter the height of object\n"))
u=float(input("Enter initial velocity in m/s \n"))
# acceleration due to gravity
g=9.81

评估方程1中的“t”和方程2中的“R”。

# Time of flight
t=sqrt(2*h/g)
# Range of projectile
R=u*t

但是sqrt()函数在常规的Python包中没有定义,因此必须在程序的开头调用math模块。

from math import *

然后将飞行时间和距离的值打印出来作为你的答案。在这里,我们使用了f-string(格式化字符串)来简化打印过程。

# Output
print(f"Time of flight = {t} s")
print(f"Range = {R} m")

输出

最后,程序的输出结果将如下所示 –

Enter the height of object
900
Enter initial velocity in m/s
140
Time of flight = 13.545709229571926 s
Range = 1896.3992921400697 m

如果需要,可以使用round函数将输出四舍五入到小数点后几位,如下所示−

# Output
print(f"Time of flight = {round(t,3)} s")
print(f"Range = {round(R,3)} m")

如果想要绘制弹道轨迹,首先需要将射程(R)分成一组x数组,并获得不同高度上的弹丸位置(y),然后可以将这些数据绘制成轨迹。这将在第二种情况下进行解释。

案例2:斜向投射在水平地面上

在这种情况下,抛射物从平地发射,并达到与下图所示相同的高度。

使用Python建模抛射运动

在这种情况下,最大高度\mathrm{h_{max}}的范围(R)和总飞行时间(𝑇)可通过以下公式获得:

\mathrm{h_{max}=\frac{u^{2}\sin^{2}\left ( \alpha \right )}{2g}}

\mathrm{R=\frac{u^{2}\sin(2\alpha)}{g}}

\mathrm{T=\frac{2:u:\sin\left ( \alpha \right )}{g}}

重要的是如何评估轨迹的剖面\mathrm{y(x)}。假设在某个时间“t”时,抛体位于点a处,坐标为(𝑥,𝑦),如下图所示。

使用Python建模抛射运动

然后通过以下推导可以得到粒子位置”y”关于”x”的函数。

运动方程在”y”方向为-

\mathrm{y=u_{y}t+\frac{1}{2}a:t^{2}=u\sin(\alpha )t-\frac{1}{2}gt^{2}}

运动方程在”x”方向为-

\mathrm{x=u\cos\left ( \alpha \right )t}

\mathrm{y=x\tan(\alpha)-\frac{1}{2}\frac{gx^{2}}{u^{2}\cos^{2}\left ( \alpha \right )}}

方程6是我们可以轻松建模弹道并绘制弹道的基础。

示例2

要对其进行建模,我们将需要使用NumPy模块进行数组操作,而由于需要绘图,所以我们将使用pylab模块,它实际上就是matplot.pylab模块。

下面展示了详细的代码及其解释 –

首先调用并导入numpy和pylab模块。

# Importing modules
from numpy import *
from pylab import *

然后从用户那里询问你和\alpha。 (不要忘记使用radians()函数将角度转换为弧度)

α=float(input("Enter the angle in degrees\n"))
# converting angle in radians
α=radians(α)

# Initial velocity of projectile
u=float(input("Enter initial velocity in m/s \n"))

然后使用方程(3)和(4)计算出射程和抛射物的最大高度。

# Evaluating Range
R=u**2*sin(2*α)/g


# Evaluating max height
h=u**2*(sin(α))**2/(2*g)

现在使用linspace()函数创建了一个名为”x”的数组。linspace()函数接受3个参数,即起始点、结束值和要在起始点和结束点之间创建的点的数量。

# Creating an array of x with 20 points
x=linspace(0, R, 20)

然后求解等式6,将对不同的x评估y。

# Solving for y
y=x*tan(α)-(1/2)*(g*x**2)/(u**2*(cos(α))**2 )

然后使用plot()函数来绘制数据,并做一些装饰以使绘图有意义。如果需要的话,你可以通过savefig()函数来保存图像。

在这里,我们给出了图像编号为1,并为了增加图像的可见性,使用figure()函数将dpi设置为300。

# Data plotting
figure(1,dpi=300)
plot(x,y,'r-',linewidth=3)
xlabel('x')
ylabel('y')
ylim(0, h+0.05)
savefig('proj.jpg')
show()

对于𝑢=5米/秒和𝛼=30∘,上述程序的 输出 将如下所示 –

使用Python建模抛射运动

如果想以表格形式打印数据,则以下程序片段可以提供很大的帮助。

print(f"{'S. No.':^10}{'x':^10}{'y':^10}")
for i in range(len(x)):
   print(f"{i+1:^10}{round(x[i],3):^10}{round(y[i],3):^10}")

示例

完整的程序代码将如下所示 –

# Importing modules
from numpy import *
from pylab import *

α=float(input("Enter the angle in degrees\n"))
# converting angle in radians
α=radians(α)

# Initial velocity of projectile
u=float(input("Enter initial velocity in m/s \n"))

# Evaluating Range
R=u**2*sin(2*α)/g

# Evaluating max height
h=u**2*(sin(α))**2/(2*g)

# Creating array of x with 50 points
x=linspace(0, R, 20)

# Solving for y
y=x*tan(α)-(1/2)*(g*x**2)/(u**2*(cos(α))**2 )
# Data plotting

figure(1,dpi=300)
plot(x,y,'r-',linewidth=3)
xlabel('x')
ylabel('y')
ylim(0, h+0.05)
savefig('proj.jpg')
show()

print(f"{'S. No.':^10}{'x':^10}{'y':^10}")
for i in range(len(x)):
   print(f"{i+1:^10}{round(x[i],3):^10}{round(y[i],3):^10}")

我们还可以检查的一件事是把投射物以不同角度射出后会发生什么,然后将它们绘制出来。这将帮助你很多,让你了解如何将代码打包成一个函数。

在Python中,使用lambda来定义单行函数,例如:

f= lambda {arguments}: {output statement}

但是正如你所看到的,有很多行代码,所以这种方法行不通,我们将使用def来编写它,其主体如下所示 –

def (arguments):
   statements1
   statement 2
   .
   .
   .

在这里,我们将把要求用户输入之后的所有语句捆绑到一个名为Projectile_Plot的函数里。该函数接受两个参数,即u和\alpha,如下所示−

# Projectile Function
def Projectile_Plot(u,α):

   # for pronging legend
   αd=α

   # converting angle in radians
   α=radians(α)

   # Evaluating Range
   R=u**2*sin(2*α)/g

   # Evaluating max height
   h=u**2*(sin(α))**2/(2*g)

   # Creating array of x with 20 points
   x=linspace(0, R, 20)

   # Solving for y
   y=x*tan(α)-(1/2)*(g*x**2)/(u**2*(cos(α))**2 )

   # Data plotting
   figure(1,dpi=300)
   plot(x,y,'-',linewidth=2,label=f'α = {αd}')
   xlabel('x')
   ylabel('y')
   ylim(0, h+0.05)
   legend()
   savefig('proj2.jpg')

最后,对于速度为5 m/s的抛体运动,可以使用以下代码绘制(在这里您应该理解,由于角度将会变化,因此需要使用for循环)−

# Input data
# Initial velocity of projectile
u=float(input("Enter initial velocity in m/s \n"))
for i in range(0,100,10):
Projectile_Plot(u,i)
show()

输出

程序的输出如下:

使用Python建模抛射运动

案例3:倾斜投射但以不同高度击中

在本节中,我将向您展示如何建模投射物,当投射物的起飞点和着陆点不在同一海拔高度时,如下图所示。
使用Python建模抛射运动

在这种情况下,可以看到投影点(A)比着陆点(B)高出𝑦_{0}单位。

分析方法如下:

在垂直方向应用运动方程:

\mathrm{s=u_{y}t+\frac{1}{2}a_{y}t^{2}}

但是\mathrm{u_{y}=u\sin(\alpha)}a_{y}=-g(即重力加速度)。因此等式7变为:

\mathrm{y=u\sin(\alpha)t-\frac{1}{2}gt^{2}}

到达点B所需的时间如下评估:

当抛射物到达B时,y将被−𝑦_{0}替代,因为它在X轴下方。因此,方程8转变为-

\mathrm{-y_{0}=u\sin(\alpha)t-\frac{1}{2}gt^{2}}

为了更好地理解,可以简化为-

\mathrm{gt^{2}-2u\sin(\alpha)t-2y_{0}=0}

现在必须解决这个二次方程(即方程10)以获得t。

最后,水平范围可以评估为-

\mathrm{R=u\cos(\alpha)t}

在这种情况下,由于我们需要解决二次方程(即方程10),所以为了简化任务,我们将使用NumPy(Numerical Python)。在编写这个抛物线运动之前,让我向你展示如何使用NumPy找到二次方程的根。

NumPy中的方程根

假设我们想要找到方程的根

ax^{2}+bx+c=0

那么第一步是调用NumPy,如下所示 –

from numpy import *

然后将上述多项式的系数按如下方式存储在一个数组中(注意:从多项式的最高幂到最低幂开始)−

coeff=array([a,b,c])

然后调用函数 roots() 来解决根的问题,如下所示−

r1,r2=roots(coeff)

由于这是一个二次方程,我们已经知道会有两个根,所以我们将它们存储在变量”r1″和”r2″中。但是如果多项式的次数增加,那么根变量的数量也必须相应增加。下面的示例将清楚地解释上面所示的过程。

求解多项式x2 - 5x + 6 = 0的根

# Importing NumPy
from numpy import *

# The polynomial is x^2 -5x+6=0
# The coefficients of the above equation are:
a=1
b=-5
c=6

# Creating array of coefficients
coeff=array([a,b,c])

# Calling function to find the roots
r1,r2=roots(coeff)

# Printing result
print(f"r1 = {round(r1,3)} and r2 = {round(r2,3)}")

执行后,它将产生以下 输出

r1 = 3.0 and r2 = 2.0

寻找多项式x的根 3 - 2x 2 - 5x + 6 = 0

# Importing NumPy
from numpy import *

# The polynomial is x^3-2x^2-5x+6=0

# The coefficients of the above equation are:

a=1
b=-2
c=-5
d=6

# Creating array of coefficients
coeff=array([a,b,c,d])

# Calling function to find the roots
r1,r2,r3=roots(coeff)

# Printing result
print(f"r1 = {round(r1,3)}, r2 = {round(r2,3)} and r3 = {round(r3,3)}")

在执行时,你将得到以下的输出。

r1 = -2.0, r2 = 3.0 and r3 = 1.0

现在我们可以解决斜抛问题。

示例3

一个子弹以速度和角度分别为100 m/s和45^{0}的速度被发射到离地面100 m的地方。需要评估以下内容:

  • 飞行时间

  • 飞行距离

  • 抛物线的最大高度

解答

引入包 –

from numpy import *
from pylab import *

提供输入数据 –

# Velocity at the start
u=100
# Angle of projectile at start
α=radians(45)
# Elevation of starting point above the ground
y0=100
# Acceleration due to gravity
g=9.81

计算飞行时间 –

# Time of flight
a=g
b=-2*u*sin(α)
c=-2*y0

# coefficient array
coeff=array([a,b,c])

# finding roots
t1,t2=roots(coeff)
print(f"t1= {t1} and t2= {t2}")

这将返回两个根,即两个时间值。将接受非负值。

抛射物的最大高度将由以下公式得到 –

\mathrm{h_{max}=\frac{u^{2}\sin^{2}(\alpha)}{2g}+y_{0}}

# From the throwing point
h1=u**2*(sin(α))**2/(2*g)

# total
h_max=h1+y0
print(f"h_max= {round(h_max,3)} m")

范围将根据公式11进行评估,如下所示:−

R=u*cos(α)*max(t1,t2)
# max(t1,t2) will return the positive value

print(f"R= {round(R,3)} m")

因此,完整程序和程序输出将如下所示 −

# Importing packages
from numpy import *
from pylab import *

# Input data
# Velocity at the start
u=100

# Angle of projectile at start
α=radians(45)

# Elevation of starting point above the ground
y0=100

# Acceleration due to gravity
g=9.81

# Time of flight
a=g
b=-2*u*sin(α)
c=-2*y0

# coefficient array
coeff=array([a,b,c])

# finding roots
t1,t2=roots(coeff)
print(f"t1= {t1} and t2= {t2}")

# Maximum Height
# From the throwing point
h1=u**2*(sin(α))**2/(2*g)

# total
h_max=h1+y0
print(f"h_max= {round(h_max,3)} m")

# Range
R=u*cos(α)*max(t1,t2)
#max(t1,t2) will return the positive value

print(f"R= {round(R,3)} m")

当您运行程序代码时,它将产生以下输出。

t1= 15.713484026367722 and t2= -1.2974436352046743
h_max= 354.842 m
R= 1111.111 m

绘制抛体运动

现在的任务是绘制这个抛体运动。方程将与我之前使用的相同,即:

\mathrm{y=x\tan(\alpha)-\frac{1}{2}\frac{gx^{2}}{u^{2}\cos^{2}(\alpha)}}

绘图过程如下:

  • 首先导入pylab库。

  • 绘制斜面,考虑点(0,0)和(R,-y_{0})

  • 然后创建从0到R的x数组。

  • 求解方程6,得到对应x的y数组。

  • 最后使用plot()函数绘制(𝑥,𝑦)。

完整的Python代码和绘图如下:

from pylab import *
# Figure name
figure(1, dpi=300)

# Plotting inclined surface
plot([0,R],[0,-y0],linewidth=5)

# plotting y=0 line
plot([0,R],[0,0],'k',linewidth=1)

# Array of x
x=linspace(0,R,50)

# Evaluating y based on x
y=x*tan(α)-(1/2)*(g*x**2)/(u**2*(cos(α))**2 )

# Plotting projectile
plot(x,y,'r-',linewidth=2)
xlabel('x')
ylabel('y')
savefig("Inc_Proj.jpg")
show()

它将生成以下图表 −
使用Python建模抛射运动

这里需要注意的是,只有在评估了弹射物的射程之后才能绘制出来。因此,你将首先评估射程,然后使用绘制代码。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程