"""Original planar support examples: reaction fractions and a lifted foot.""" from pathlib import Path import matplotlib.pyplot as plt from matplotlib.patches import Polygon import numpy as np def reactions(point): x, y = point return np.array([1 - x - y, x, y]) def main(): feet = np.array([[0, 0], [1, 0], [0, 1]]) inside, outside, walking = np.array([0.3, 0.2]), np.array([0.7, 0.5]), np.array([0.6, 0.6]) fractions = reactions(inside) assert np.allclose(fractions, [0.5, 0.3, 0.2]) assert np.allclose(fractions @ feet, inside) assert np.isclose(np.sum(fractions), 1) assert np.allclose(fractions * 98.1, [49.05, 29.43, 19.62]) assert np.isclose(reactions(outside)[0], -0.2) assert np.isclose(reactions(walking)[0], -0.2) assert np.isclose(min(inside[0], inside[1], (1 - sum(inside)) / np.sqrt(2)), 0.2) fig, (triangle, lifting) = plt.subplots(1, 2, figsize=(10, 4.4), dpi=100, layout="constrained") fig.set_facecolor("white") for ax in (triangle, lifting): ax.add_patch(Polygon(feet, closed=True, facecolor="#dceaf1", edgecolor="#286f99", linewidth=1.8, zorder=2)) ax.scatter(feet[:, 0], feet[:, 1], color="#286f99", s=42, zorder=5) ax.set(xlim=(-0.12, 1.22), ylim=(-0.12, 1.25), aspect="equal", xlabel="x (m)", ylabel="y (m)") ax.set_xticks([0, 0.5, 1]) ax.set_yticks([0, 0.5, 1]) ax.grid(alpha=0.15) triangle.set_title("Three supports: reactions must be nonnegative") for (x, y), label, offset in zip(feet, ["1", "2", "3"], [(7, 4), (7, 4), (7, 4)]): triangle.annotate(label, (x, y), xytext=offset, textcoords="offset points", color="#286f99") triangle.scatter(*inside, color="#52762a", s=45, zorder=6) triangle.annotate("c = (0.30, 0.20)\nN = (49.05, 29.43, 19.62) N", inside, xytext=(0.04, 0.70), fontsize=9, arrowprops={"arrowstyle": "->", "color": "#52762a"}) triangle.scatter(*outside, color="#9f4b27", marker="x", s=55, linewidth=2, zorder=6) triangle.annotate("Outside: (0.70, 0.50)\nwould require N₁ = āˆ’19.62 N", outside, xytext=(0.38, 1.05), fontsize=9, arrowprops={"arrowstyle": "->", "color": "#9f4b27"}) lifting.add_patch(Polygon([[0, 0], [1, 0], [1, 1], [0, 1]], closed=True, facecolor="#eeeeee", edgecolor="#888888", linestyle="--", zorder=1)) lifting.scatter(1, 1, marker="x", color="#9f4b27", s=65, linewidth=2, zorder=6) lifting.annotate("Lifted foot", (1, 1), xytext=(0.65, 1.17), fontsize=9, arrowprops={"arrowstyle": "->", "color": "#9f4b27"}) lifting.scatter(*walking, color="#9f4b27", s=45, zorder=6) lifting.annotate("c = (0.60, 0.60)\nInside square; outside triangle", walking, xytext=(0.05, 0.91), fontsize=9, arrowprops={"arrowstyle": "->", "color": "#9f4b27"}) lifting.text(0.05, 0.20, "Remaining support region", fontsize=9, color="#286f99") lifting.set_title("Lifting a foot changes the support polygon") fig.savefig(Path(__file__).with_suffix(".png").name, facecolor="white") plt.close(fig) if __name__ == "__main__": main()