codexpast-exam-of-the-mathematics-course-of-the-university-of-oxford2021prelimsmathematics-iv-resit-cone-forces.py
past-exam-of-the-mathematics-course-of-the-university-of-oxford/2021/prelims/mathematics-iv-resit-cone-forces.py
"""Original Q5 force diagram; writes its PNG into the current directory.
Python 3.14.4; NumPy 2.3.5; Matplotlib 3.10.7 (root pyproject.toml).
"""
from pathlib import Path
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import numpy as np
def arrow(ax, start, displacement, label, offset=(0, 0)):
end = np.asarray(start) + displacement
ax.annotate("", xy=end, xytext=start,
arrowprops={"arrowstyle": "-|>", "color": "#b04430", "lw": 2})
ax.text(*(end + offset), label, fontsize=12, ha="center", va="center")
def main():
fig, ax = plt.subplots(figsize=(7.4, 5.0), facecolor="white")
ax.plot([-2.7, 0, 2.7], [-2.7, 0, -2.7], color="#999999", lw=3)
ax.plot([0, 1.8], [0, -1.8], color="#17658a", lw=2)
ax.plot([0, 0], [0, -3.35], color="#17658a", lw=2)
ax.scatter([1.8, 0], [-1.8, -3.35], s=95, color="#222222", zorder=4)
ax.scatter([0], [0], s=24, color="#222222", zorder=4)
ax.text(-0.22, 0.17, "$O$", fontsize=12)
ax.text(1.5, -1.67, "$m_1$", fontsize=12, ha="right")
ax.text(-0.22, -3.32, "$m_2$", fontsize=12, ha="right")
arrow(ax, (1.8, -1.8), (0, -0.8), "$m_1g$", (0.35, 0))
arrow(ax, (1.8, -1.8), (-0.62, 0.62), r"$\mathbf{T}_1$", (-0.2, 0.08))
arrow(ax, (1.8, -1.8), (0.62, 0.62), r"$\mathbf{N}$", (0.15, 0.15))
arrow(ax, (0, -3.35), (0, 0.8), r"$\mathbf{T}_2$", (0.32, 0))
arrow(ax, (0, -3.35), (0, -0.7), "$m_2g$", (0.35, 0))
ax.text(-2.65, -2.35, "Cone: $z=-r$", fontsize=11)
ax.text(0.7, -0.5, r"$|\mathbf{r}_1|=\sqrt{2}r_1$", fontsize=10, rotation=-45)
ax.text(-0.2, -1.55, "$-z_2$", fontsize=11, rotation=90, ha="right")
arrow(ax, (-2.4, -3.9), (0.65, 0), r"$\mathbf{e}_r$", (0.2, 0))
arrow(ax, (-2.4, -3.9), (0, 0.65), r"$\mathbf{e}_z$", (0, 0.2))
ax.set_title("Cone and hanging particle: all applied forces")
ax.set(xlim=(-3.1, 3.1), ylim=(-4.35, 0.55))
ax.set_aspect("equal")
ax.axis("off")
fig.tight_layout()
fig.savefig(Path(__file__).stem + ".png", dpi=130, facecolor="white")
plt.close(fig)
if __name__ == "__main__":
main()