codexradially-sprung-disk-normal-modes.py
radially-sprung-disk-normal-modes.py
"""Original normal-mode schematic; write the PNG to the current directory."""
from pathlib import Path
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from matplotlib.patches import Circle, FancyArrowPatch
import numpy as np
def main():
fig, axes = plt.subplots(1, 3, figsize=(10.2, 3.6), facecolor='white')
directions = np.pi / 2 + np.arange(3) * 2 * np.pi / 3
names = ['Horizontal translation', 'Vertical translation', 'Rotation about the centre']
shifts = [np.array([0.20, 0.0]), np.array([0.0, 0.20]), np.array([0.0, 0.0])]
for index, (ax, name, shift) in enumerate(zip(axes, names, shifts)):
angle = 0.26 if index == 2 else 0
ax.add_patch(Circle((0, 0), 0.53, fill=False, ec='0.5', ls='--', lw=1.3))
ax.add_patch(Circle(shift, 0.53, fc='#dcecf9', ec='#265b87', lw=1.8, alpha=0.85))
for phi in directions:
anchor = 1.28 * np.array([np.cos(phi), np.sin(phi)])
contact = shift + 0.53 * np.array([np.cos(phi + angle), np.sin(phi + angle)])
delta = anchor - contact
tangent = np.array([-delta[1], delta[0]]) / np.linalg.norm(delta)
t = np.linspace(0, 1, 160)
wiggle = 0.042 * np.sin(12 * np.pi * t) * np.sin(np.pi * t)
spring = contact[:, None] + delta[:, None] * t + tangent[:, None] * wiggle
ax.plot(*spring, color='0.3', lw=1.3)
ax.plot(*anchor, 'ks', ms=5)
ax.plot(*contact, 'o', color='#265b87', ms=4)
if index < 2:
vector = np.array([0.7, 0]) if index == 0 else np.array([0, 0.7])
ax.add_patch(FancyArrowPatch(-vector / 2, vector / 2,
arrowstyle='<->', mutation_scale=15,
color='#bd4f26', lw=2.2))
else:
ax.add_patch(FancyArrowPatch((0.27, 0.03), (-0.22, 0.15),
connectionstyle='arc3,rad=0.7',
arrowstyle='<->', mutation_scale=14,
color='#bd4f26', lw=2.2))
ax.plot([0, 0.4 * np.cos(angle)], [0, 0.4 * np.sin(angle)], color='#265b87', lw=2)
ax.set_title(name, fontsize=11)
ax.text(0, -1.30, 'Same frequency' if index < 2 else 'Separate frequency',
ha='center', fontsize=10)
ax.set_aspect('equal')
ax.set(xlim=(-1.42, 1.42), ylim=(-1.45, 1.55))
ax.axis('off')
fig.subplots_adjust(left=0.025, right=0.975, bottom=0.03, top=0.88, wspace=0.12)
fig.savefig(Path.cwd() / (Path(__file__).stem + '.png'), dpi=120,
facecolor='white', transparent=False)
plt.close(fig)
if __name__ == '__main__':
main()