我正在尝试绘制在重力,浮力和阻力作用下的质点的抛物线运动。基本上,我想显示浮力和阻力对飞行距离,飞行时间和速度变化对绘图的影响。
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!--script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script-->
在此之后,我无法弄清楚如何在这种力下绘制弹丸运动。换句话说,我正在尝试比较三种情况下质量的弹丸运动
答案 0 :(得分:2)
您必须根据给定时间的力总和来计算每个位置。为此,最好从随时计算净力开始,然后使用它来计算加速度,速度和位置。对于以下计算,假定浮力和重力是恒定的(实际上并不正确,但在这种情况下其可变性的影响可忽略不计),还假定初始位置为(0,0)
可以简单地更改为任何初始位置。
F_x = tau_x
F_y = tau_y + bouyancy + gravity
其中tau_x
和tau_y
分别是在x
和y
方向上的拖曳力。然后由
v_x
和v_y
v_x = v_x + (F_x / (2 * m)) * dt
v_y = v_y + (F_y / (2 * m)) * dt
因此,x
在任何时间y
的{{1}}和r_x
位置r_y
都是
t
在两种情况下,对于某些r_x = r_x + v_x * dt
r_y = r_y + v_y * dt
,必须从0
到t
进行评估,如果dt
是求和的步数,则其中dt * n = t
。 / p>
n
整个计算实际上可以分两行完成
r_x = r_x + V_i * np.cos(theta) * dt + (F_x / (2 * m)) * dt**2
r_y = r_y + V_i * np.sin(theta) * dt + (F_y / (2 * m)) * dt**2
除了r_x = r_x + V_i * np.cos(theta) * dt + (tau_x / (2 * m)) * dt**2
r_y = r_y + V_i * np.sin(theta) * dt + ((tau_y + bouyancy + gravity) / (2 * m)) * dt**2
和v_x
需要在每个时间步进行更新。要对此进行循环并计算一段时间内的v_y
和x
位置,您可以简单地遵循以下示例(已编辑)。
以下代码包含一些纠正措施,以防止出现y负位置,因为y
的给定值适用于表面或火星,我认为这是适当的-当您命中零g
并尝试继续时您可能会像我们物理学家所说的那样快速进行计划外的拆卸。
为响应已编辑的问题,对以下示例进行了修改,以绘制请求的所有三种情况-重力,重力加阻力以及重力加阻力和浮力。情节设置代码也已添加
y
请注意,这会保留并返回变量import numpy as np
import matplotlib.pyplot as plt
def projectile(V_initial, theta, bouyancy=True, drag=True):
g = 9.81
m = 1
C = 0.47
r = 0.5
S = np.pi*pow(r, 2)
ro_mars = 0.0175
time = np.linspace(0, 100, 10000)
tof = 0.0
dt = time[1] - time[0]
bouy = ro_mars*g*(4/3*np.pi*pow(r, 3))
gravity = -g * m
V_ix = V_initial * np.cos(theta)
V_iy = V_initial * np.sin(theta)
v_x = V_ix
v_y = V_iy
r_x = 0.0
r_y = 0.0
r_xs = list()
r_ys = list()
r_xs.append(r_x)
r_ys.append(r_y)
# This gets a bit 'hand-wavy' but as dt -> 0 it approaches the analytical solution.
# Just make sure you use sufficiently small dt (dt is change in time between steps)
for t in time:
F_x = 0.0
F_y = 0.0
if (bouyancy == True):
F_y = F_y + bouy
if (drag == True):
F_y = F_y - 0.5*C*S*ro_mars*pow(v_y, 2)
F_x = F_x - 0.5*C*S*ro_mars*pow(v_x, 2) * np.sign(v_y)
F_y = F_y + gravity
r_x = r_x + v_x * dt + (F_x / (2 * m)) * dt**2
r_y = r_y + v_y * dt + (F_y / (2 * m)) * dt**2
v_x = v_x + (F_x / m) * dt
v_y = v_y + (F_y / m) * dt
if (r_y >= 0.0):
r_xs.append(r_x)
r_ys.append(r_y)
else:
tof = t
r_xs.append(r_x)
r_ys.append(r_y)
break
return r_xs, r_ys, tof
v = 30
theta = np.pi/4
fig = plt.figure(figsize=(8,4), dpi=300)
r_xs, r_ys, tof = projectile(v, theta, True, True)
plt.plot(r_xs, r_ys, 'g:', label="Gravity, Buoyancy, and Drag")
r_xs, r_ys, tof = projectile(v, theta, False, True)
plt.plot(r_xs, r_ys, 'b:', label="Gravity and Drag")
r_xs, r_ys, tof = projectile(v, theta, False, False)
plt.plot(r_xs, r_ys, 'k:', label="Gravity")
plt.title("Trajectory", fontsize=14)
plt.xlabel("Displacement in x-direction (m)")
plt.ylabel("Displacement in y-direction (m)")
plt.ylim(bottom=0.0)
plt.legend()
plt.show()
中的运行时间。
答案 1 :(得分:0)
使用向量符号和<div class="title-button"></div>
If(document.querySelector(".title-button").className == "hidden"){
//Your statement goes here
}
。
odeint
请注意,我已纠正了拖动力以使用实际(而非初始)速度,不知道这是您的错误还是故意的。
也请查看import numpy as np
from scipy.integrate import odeint
import scipy.constants as SPC
import matplotlib.pyplot as plt
V_initial = 30 # m/s
theta = np.pi/6 # 30
g = 3.711
m = 1 # I assume this is your mass
C = 0.47
r = 0.5
ro_mars = 0.0175
t_flight = 2*(V_initial*np.sin(theta)/g)
t = np.linspace(0, t_flight, 200)
pos0 = [0, 0]
v0 = [np.cos(theta) * V_initial, np.sin(theta) * V_initial]
def f(vector, t, C, r, ro_mars, apply_bouyancy=True, apply_resistance=True):
x, y, x_prime, y_prime = vector
# volume and surface
V = np.pi * 4/3 * r**3
S = np.pi*pow(r, 2)
# net weight bouyancy
if apply_bouyancy:
Fb = (ro_mars * V - m) * g *np.array([0,1])
else:
Fb = -m * g * np.array([0,1])
# velocity vector
v = np.array([x_prime, y_prime])
# drag force - corrected to be updated based on current velocity
# Ft = -0.5*C*S*ro_mars*pow(V_initial, 2)
if apply_resistance:
Ft = -0.5*C*S*ro_mars* v *np.linalg.norm(v)
else:
Ft = np.array([0, 0])
# resulting acceleration
x_prime2, y_prime2 = (Fb + Ft) / m
return x_prime, y_prime, x_prime2, y_prime2
sol = odeint(f, pos0 + v0 , t, args=(C, r, ro_mars))
plt.plot(sol[:,0], sol[:, 1], 'g', label='tray')
plt.legend(loc='best')
plt.xlabel('x')
plt.ylabel('y')
plt.grid()
plt.show()
的文档,以更好地了解如何将二阶ODE(如问题中的一个)转换为一阶向量ODE。
要消除空气阻力或弹性,请将odeint
和apply_bouyancy
设置为apply_resistance
或True
并将其添加到False