"""Original shallow-glide polar: python glider-sink-polar-optima.py writes cwd PNG. Tested with Python 3.14, NumPy 2.3.5 and Matplotlib 3.10.7. """ import numpy as np import matplotlib.pyplot as plt W, S, rho, c0, k = 3000.0, 10.0, 1.2, 0.020, 0.045 A = rho * S * c0 / 2 B = 2 * k * W**2 / (rho * S) def sink(v): return (A * v**3 + B / v) / W v_bg = (B / A)**0.25 v_ms = (B / (3 * A))**0.25 assert 0 < v_ms < v_bg assert np.isclose(v_bg / v_ms, 3**0.25) assert np.isclose(3*A*v_ms**2 - B/v_ms**2, 0, atol=1e-10) assert np.isclose(A*v_bg**2 - B/v_bg**2, 0, atol=1e-10) v = np.linspace(17, 41, 700) fig, ax = plt.subplots(figsize=(7.2, 4.5), dpi=100, facecolor='white') ax.set_facecolor('white') ax.plot(v, sink(v), color='#235789', lw=2.4, label='Invented sink polar') ray = np.linspace(0, 41, 250) ax.plot(ray, sink(v_bg) / v_bg * ray, '--', color='#b45222', lw=1.6, label='Tangent from origin: best glide') ax.axhline(sink(v_ms), color='#4c7c36', linestyle=':', lw=1.5) for vv, color in [(v_ms, '#4c7c36'), (v_bg, '#b45222')]: ax.scatter([vv], [sink(vv)], color=color, s=45, zorder=4) ax.annotate(f'Minimum sink\n{v_ms:.2f} m/s, {sink(v_ms):.3f} m/s', (v_ms, sink(v_ms)), (5, 3.2), arrowprops={'arrowstyle':'->', 'color':'#4c7c36'}, fontsize=9) ax.annotate(f'Best glide\n{v_bg:.2f} m/s, {sink(v_bg):.3f} m/s', (v_bg, sink(v_bg)), (28.5, 0.55), arrowprops={'arrowstyle':'->', 'color':'#b45222'}, fontsize=9) ax.set(xlim=(0, 43), ylim=(0, 4.5), xlabel='True airspeed V (m/s)', ylabel='Downward rate w (m/s)', title='Longest time aloft and greatest range use different speeds') ax.grid(alpha=0.2) ax.legend(loc='upper right', fontsize=8, frameon=False) fig.text(0.5, 0.025, 'Original shallow-glide model; fixed loading and density; no wind or stall model.', ha='center', fontsize=8) fig.tight_layout(rect=(0, .05, 1, 1)) fig.savefig('glider-sink-polar-optima.png', facecolor='white') print({'V_BG':v_bg, 'V_min_sink':v_ms, 'w_BG':sink(v_bg), 'w_min':sink(v_ms)})