"""Show local Earth rotation geometry and a northward-velocity example. Run from the desired output directory. Tested with Python 3.14, Matplotlib 3.10.7 and NumPy 2.3.5; dependencies are in pyproject.toml. """ from pathlib import Path import matplotlib.pyplot as plt from matplotlib.patches import Arc, Circle import numpy as np def arrow(ax, start, end, color, label=None, text=None): ax.annotate("", xy=end, xytext=start, arrowprops={"arrowstyle": "-|>", "color": color, "lw": 2, "mutation_scale": 15}) if label: ax.text(*text, label, fontsize=11, color=color) def main(): omega, speed, phi = 7.292115e-5, 20.0, np.pi / 4 acceleration = 2 * omega * speed * np.sin(phi) fig, (left, right) = plt.subplots(1, 2, figsize=(10, 5.7), facecolor="white") fig.subplots_adjust(left=0.035, right=0.98, top=0.79, bottom=0.25, wspace=0.15) for ax in (left, right): ax.set_aspect("equal") ax.set_facecolor("white") ax.axis("off") left.set_xlim(-1.25, 1.65) left.set_ylim(-1.1, 1.5) left.add_patch(Circle((0, 0), 0.88, facecolor="#eef6fa", edgecolor="#507080", lw=1.4)) left.plot([-1.1, 1.1], [0, 0], color="#999999", lw=1) left.text(-1.14, -0.16, "equatorial plane", fontsize=10) arrow(left, (0, -1.0), (0, 1.37), "#555555", r"$\boldsymbol{\Omega}$", (0.08, 1.22)) p = 0.88 * np.array([np.cos(phi), np.sin(phi)]) left.plot([0, p[0]], [0, p[1]], color="#888888", ls="--") left.add_patch(Arc((0, 0), 0.70, 0.70, theta1=0, theta2=45, color="#555555")) left.text(0.37, 0.13, r"$\varphi=45^\circ$", fontsize=11) left.plot(*p, "o", color="#222222", ms=5) arrow(left, p, p + 0.52 * np.array([np.cos(phi), np.sin(phi)]), "#009e73", "up", (1.04, 1.02)) arrow(left, p, p + 0.56 * np.array([-np.sin(phi), np.cos(phi)]), "#0072b2", "north", (0.11, 1.10)) left.text(0, -1.05, "Meridian section (spherical Earth)", ha="center", fontsize=10) left.set_title("Latitude sets the vertical rotation component", fontsize=12, pad=16) right.set_xlim(-0.65, 1.65) right.set_ylim(-0.3, 1.7) arrow(right, (0, 0), (1.4, 0), "#777777", "east", (1.22, -0.17)) arrow(right, (0, 0), (0, 1.35), "#777777", "north", (-0.18, 1.46)) arrow(right, (0, 0), (0, 1.06), "#0072b2") right.text(0.08, 1.0, r"$\mathbf{v}=20\,\mathbf{e}_N\ {\rm m\,s^{-1}}$", fontsize=11, color="#0072b2") arrow(right, (0, 0.59), (1.12, 0.59), "#d55e00") right.text(0.20, 0.74, r"$\mathbf{a}_{\rm cor}=f u\,\mathbf{e}_E$", fontsize=12, color="#d55e00") right.text(0.35, 0.37, "eastward acceleration", fontsize=10, color="#d55e00") right.text(-0.49, 0.57, r"$\odot$", fontsize=24, color="#009e73", ha="center") right.text(-0.60, 0.24, "up\n(out of page)", fontsize=9, color="#009e73") right.text(0.55, -0.29, "Arrows show directions; lengths are schematic.", ha="center", fontsize=9) right.set_title("Local horizontal view at 45° north", fontsize=12, pad=16) fig.suptitle("Why a northward velocity has an eastward Coriolis acceleration", fontsize=15, y=0.98) fig.text(0.5, 0.875, r"$\boldsymbol{\Omega}=\Omega\cos\varphi\,\mathbf{e}_N+\Omega\sin\varphi\,\mathbf{e}_U,\qquad f=2\Omega\sin\varphi$", fontsize=13, ha="center") fig.text(0.5, 0.15, rf"$\Omega=7.292115\times10^{{-5}}\ {{\rm s^{{-1}}}},\qquad a_E={acceleration:.7f}\ {{\rm m\,s^{{-2}}}}$", fontsize=13, ha="center") fig.text(0.5, 0.085, r"At 10 s: $\Delta x_E\simeq\frac{1}{2} a_E t^2=0.1031$ m (local, short-time estimate).", fontsize=11, ha="center") fig.text(0.5, 0.025, "Initial northward motion, no other horizontal force; this is not a prediction of a wind trajectory.", fontsize=10, ha="center") fig.savefig(Path.cwd() / (Path(__file__).stem + ".png"), dpi=110, facecolor="white") plt.close(fig) if __name__ == "__main__": main()