| """Generate assets/fwd_diagram.png — schematic of the FWD test for the app.""" |
|
|
| import numpy as np |
| import matplotlib |
| matplotlib.use("Agg") |
| import matplotlib.pyplot as plt |
| from matplotlib.patches import Rectangle, FancyArrowPatch |
|
|
| plt.rcParams.update({"font.size": 11, "figure.dpi": 200}) |
|
|
| OFFSETS = [0, 200, 300, 450, 600, 900, 1200, 1500, 1800] |
|
|
| fig, ax = plt.subplots(figsize=(11, 4.4)) |
| ax.set_xlim(-260, 2050) |
| ax.set_ylim(-165, 105) |
| ax.axis("off") |
|
|
| |
| layers = [(0, -34, "#4a4a52", "AC — h$_{AC}$", "white"), |
| (-34, -76, "#c9a86a", "Base — h$_{Base}$", "#4d3d18"), |
| (-76, -124, "#e3d5b8", "Subbase — h$_{Subbase}$", "#6d5f3a"), |
| (-124, -165, "#a4b58c", "Subgrade (semi-infinite)", "#33402a")] |
| for top, bot, c, lab, tc in layers: |
| ax.add_patch(Rectangle((-260, bot), 2310, top - bot, fc=c, ec="none")) |
| ax.text(2020, (top + bot) / 2, lab, ha="right", va="center", |
| fontsize=10.5, color=tc, fontweight="bold") |
|
|
| |
| ax.add_patch(Rectangle((-55, 62), 110, 34, fc="#8b95a5", ec="#5d6673")) |
| ax.add_patch(FancyArrowPatch((0, 60), (0, 12), arrowstyle="-|>", |
| mutation_scale=18, lw=2, color="#333", |
| linestyle=(0, (4, 3)))) |
| ax.text(0, 100, "falling weight — 707 kPa", ha="center", fontsize=10.5) |
| ax.add_patch(Rectangle((-150, 0), 300, 9, fc="#3d4451", ec="none")) |
| ax.text(-170, 14, "plate r = 150 mm", ha="right", fontsize=9.5) |
|
|
| |
| basin_y = [-30 * np.exp(-x / 550) for x in OFFSETS] |
| ax.plot(OFFSETS, basin_y, "--", color="#ff6b6b", lw=1.8, zorder=5) |
| ax.text(700, -12, "deflection basin", color="#e04848", fontsize=9.5) |
| for x in OFFSETS: |
| ax.plot(x, 14, "v", ms=8, color="#10a37f" if x == 0 else "#5436da", |
| zorder=6) |
| ax.text(x, 26, f"D{x}", ha="center", fontsize=8.6) |
| ax.text(1050, 55, "9 geophones record the deflection basin (μm)", |
| ha="center", fontsize=10, color="#444") |
|
|
| |
| ax.plot(0, -32, "o", ms=10, mfc="none", mec="#ff8f8f", mew=2, zorder=6) |
| ax.text(50, -28, r"$\varepsilon_t$ — AC tensile strain (fatigue)", |
| fontsize=10.5, color="#ffb3b3", fontweight="bold") |
| ax.plot(0, -126, "o", ms=10, mfc="none", mec="#2e6bc4", mew=2, zorder=6) |
| ax.text(50, -140, r"$\varepsilon_c$ — subgrade compressive strain (rutting)", |
| fontsize=10.5, color="#1d4e94", fontweight="bold") |
|
|
| fig.tight_layout() |
| fig.savefig("assets/fwd_diagram.png", bbox_inches="tight", |
| facecolor="white") |
| print("wrote assets/fwd_diagram.png") |
|
|