直接先放代码(在pyCharm中编写并运行,需要导入数学库随机库和图表库)
import math # 数学库
import random
import matplotlib.pyplot as plt # 图表库
# 绘图属性设置
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.title('斜抛轨迹') # 标题
plt.xlabel("水平距离/m") # x轴标签
plt.ylabel("垂直距离/m") # y轴标签
plt.xlim(0, 45) # x轴数值范围
plt.ylim(0, 25) # y轴数值范围
def ShowTrack(v0, angle, x_target, y_target): # 根据角度和初速绘制炮弹轨迹线
g = 9.788 # 广州重力加速度
v0x = v0 * math.cos(angle * math.pi / 180) # 初速水平分量
v0y = v0 * math.sin(angle * math.pi / 180) # 初速竖直分量
t = v0y / g # 炮弹达到最高点所用时间
T = 2 * t # 射时
# Sy = v0y * T - g * t ** 2 / 2
Sx = v0x * T
# 离散斜抛曲线
N = 1000
x = []
y = []
for i in range(N):
now_t = T * i / (N-1)
h = v0y * now_t - (g * now_t ** 2) / 2
s = v0x * now_t
x.append(s)
y.append(h)
# 画散点图
plt.scatter(x, y, s=0.5, alpha=0.5) # 绘制轨迹
plt.scatter(x_target, y_target, s=10, alpha=1) # 绘制靶子
plt.draw()
def CoordinateToAngle(x, y, v0, g): # 根据靶坐标算出炮管仰角
a = g * x**2 # 一元二次方程a、b、c系数
b = -2 * v0**2 * x
c = g * x**2 + 2 * y * v0**2
delta = b**2 - 4 * a * c # δ = b^2 - 4ac
if delta < 0:
print('方程delta为 %lf ,方程无解' % delta)
return -1, -1
else: # 如果δ不小于0,方程有一个或两个根
tana = (-b + math.sqrt(delta)) / (2 * a) # 一元二次求根公式
angle1 = math.atan(tana) * 180 / math.pi # 反三角函数求角
tana = (-b - math.sqrt(delta)) / (2 * a)
angle2 = math.atan(tana) * 180 / math.pi
print('angle1 %lf° angle2 %lf°' % (angle1, angle2))
return angle1, angle2
v0_set = 20
while 1:
x_set = random.uniform(0.1, 100) # 随机生成靶点坐标
y_set = random.uniform(0.1, 100)
print('x_set %lfm y_set %lfm' % (x_set, y_set))
angle1_get, angle2_get = CoordinateToAngle(x_set, y_set, v0_set, 9.788) # 根据靶点坐标算出炮管仰角
if angle1_get > 0 and angle2_get > 0: # 当角度值有效时才执行绘图
ShowTrack(v0_set, angle1_get, x_set, y_set)
ShowTrack(v0_set, angle2_get, x_set, y_set)
# plt.show()
plt.pause(1)
print('')
- 运行结果:
- 物理示意图:
- 炮弹轨迹为斜抛运动,斜抛运动方程:
- 转为一元二次方程:
(用 1+tan^2α = 1/cos^2α 可以将公式中的三角函数都转为tanα)
参考资料: