Python嵌套循环处理欧拉法炮弹轨迹多发射角绘图问题排查
代码问题清单
- 导入命名冲突:导入matplotlib时使用的别名是
plot,但后续绘图混用了plt和plot,命名不统一会触发报错 - 变量未定义:循环内计算的坐标变量是
x、y,但绘图时调用了不存在的x1、y1 - 逻辑冗余错误:
xs_euler、ys_euler本身就是solve_euler计算得到的0到300秒对应离散时间点的坐标序列,不需要额外嵌套循环遍历时间t,重复乘时间参数会导致坐标计算完全错误 - 数组维度匹配错误:
xs_euler是长度为1000的一维数组,内层循环每次用单个时间值和整个数组运算,只会不断覆盖x、y的值,循环结束后仅能得到最后一个时间点的结果,无法生成完整轨迹 - 物理逻辑错误:
solve_euler输出的坐标已经包含重力、空气阻力的计算结果,额外叠加重力项会导致轨迹完全偏离正确值 - 时间范围不匹配:自定义的
t数组范围是0到500秒,和solve_euler计算的0到300秒范围不匹配,属于冗余变量
修正逻辑
- 统一matplotlib别名为
plt,避免命名冲突 - 移除不必要的内层时间循环,直接用numpy向量化运算处理坐标数组,既提升效率也避免变量覆盖问题
- 先计算初始求解用的初速度大小,以此为基准对轨迹做角度缩放,得到不同发射角下的运动轨迹
- 移除错误的重复重力项计算,仅保留轨迹缩放逻辑
- 增加落地判断,只绘制高度大于0的有效轨迹段
完整修正代码
import math as m import matplotlib.pyplot as plt import numpy as np n_steps = 1000 theta = np.arange(m.pi/36, m.pi/2, m.pi/36) v = 200 g = 9.81 # 计算初始求解用的初速度基准值 initial_vx = 88.38834764831843 initial_vy = 88.38834764831843 initial_v = np.sqrt(initial_vx**2 + initial_vy**2) initial_conditions = [0, 0, initial_vx, initial_vy] values_euler = solve_euler(initial_conditions, 300, n_steps) xs_euler, ys_euler = values_euler[:,0], values_euler[:,1] # 绘制45度参考轨迹 plt.plot(xs_euler, ys_euler, color='blue', linestyle='--', label='45°参考轨迹') plt.xlim(0,1500) plt.ylim(0,800) # 遍历所有发射角生成对应轨迹 for angle in theta: # 按发射角和初速度缩放基准轨迹 scale_x = (v * np.cos(angle)) / initial_v scale_y = (v * np.sin(angle)) / initial_v x = xs_euler * scale_x y = ys_euler * scale_y # 过滤落地后的无效坐标 valid_idx = y >= 0 plt.plot(x[valid_idx], y[valid_idx], label=f'{np.rad2deg(angle):.0f}°') plt.legend() plt.xlabel('水平位移/m') plt.ylabel('竖直高度/m') plt.title('不同发射角下带空气阻力的炮弹轨迹') plt.show()
内容的提问来源于stack exchange,提问作者Sean Ambrose
相关产品推荐
相关产品推荐

