codexglide-angle-wind.py
glide-angle-wind.py
"""Air-relative glide angle versus constant-wind ground range.
Original constant-velocity model. Run in the intended media directory; NumPy and
Matplotlib are supplied by pyproject.toml. No aircraft performance data are used.
"""
from pathlib import Path
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import numpy as np
def glide_components(airspeed=25.0, lift_drag=20.0):
angle = np.arctan(1.0/lift_drag)
return airspeed*np.cos(angle), airspeed*np.sin(angle)
def main():
horizontal_air, sink = glide_components()
height = 1000.0
duration = height/sink
time = np.linspace(0.0, duration, 301)
cases = [(-10.0, '#b84e32', '10 m/s headwind'),
(0.0, '#185f99', 'Still air'),
(10.0, '#2d8050', '10 m/s tailwind')]
fig, ax = plt.subplots(figsize=(7.2, 4.5), dpi=100, facecolor='white')
ax.set_facecolor('white')
for wind, color, label in cases:
range_km = (horizontal_air+wind)*duration/1000
ax.plot((horizontal_air+wind)*time/1000, height-sink*time,
color=color, lw=2.4, label=f'{label}: {range_km:.2f} km')
ax.scatter([range_km], [0], color=color, s=28, zorder=4)
ax.set(xlim=(0, 30), ylim=(-30, 1070),
xlabel='Horizontal distance over ground (km)', ylabel='Height remaining (m)')
ax.set_title('One air-relative glide angle, three ground ranges', fontsize=13)
ax.text(.98,.96,'All cases: airspeed 25 m/s; L/D = 20\nSink rate 1.2484 m/s; initial height 1000 m',
transform=ax.transAxes, ha='right', va='top', fontsize=9)
ax.legend(loc='upper right', bbox_to_anchor=(.99,.80), fontsize=9, framealpha=1)
ax.grid(alpha=.18)
ax.axhline(0, color='#666666', lw=.8)
fig.text(.5,.017,'Original steady-glide model; unequal axis scales; no measured flight data.',
ha='center',fontsize=8.5,color='#555555')
fig.tight_layout(rect=(0,.035,1,1))
fig.savefig(Path('glide-angle-wind.png'), dpi=100, facecolor='white', transparent=False)
plt.close(fig)
if __name__ == '__main__':
main()