""" https://en.wikipedia.org/wiki/Ellipse#General_parametric_form """ import numpy as np import matplotlib.pyplot as plt class Pendel(): def __init__(self, a: float, b: float, omega: float, phi: float, delta: float, tau: float, sub: int = 0): self.a = a self.b = b self.omega = omega self.phi = phi self.delta = delta self.tau = tau self._sub = sub def point(self, t: float): x = (self.a * np.cos(t*self.omega + self.delta)*np.cos(t*self.phi) - self.b*np.sin(t*self.omega + self.delta)*np.sin(t*self.phi)) y = (self.a * np.cos(t*self.omega + self.delta)*np.sin(t*self.phi) + self.b*np.sin(t*self.omega + self.delta)*np.cos(t*self.phi)) return np.exp(-t*self.tau)*np.array([x, y]) def __repr__(self): SUB = str.maketrans("0123456789", "₀₁₂₃₄₅₆₇₈₉") sub = f"{self._sub}".translate(SUB) return f"A{sub}={self.a}, B{sub}={self.b}, ω{sub}={self.omega}, Φ{sub}={self.phi}, δ{sub}={self.delta}, τ{sub}={self.tau}" def update(self, **kwargs): for key, val in kwargs.items(): if hasattr(self, key): setattr(self, key, val) else: raise ValueError(f'{self.__name__} object has no attribute {key}') class DoppelPendel(): def __init__(self, kwargs1, kwargs2): self.stift = Pendel(**kwargs1, sub=1) self.tisch = Pendel(**kwargs2, sub=2) def point(self, t): return self.stift.point(t)+self.tisch.point(t) def update_stift(self, **kwargs): self.stift.update(**kwargs) def update_tisch(self, **kwargs): self.tisch.update(**kwargs) def __repr__(self): return str(self.stift) + "\n" + str(self.tisch) class Harmonograph(DoppelPendel): def __init__(self, kwargs1, kwargs2, t_init, n=10000): super().__init__(kwargs1, kwargs2) self.n = n self.t = t_init self.fig, self.ax = plt.subplots() self.ax.set_xlim(-2, 2) self.ax.set_ylim(-2, 2) self.ax.set_aspect('equal') self.ax.axis('off') self.init_harmonograph() # self.label = self.ax.text(0, -2, str(self), # horizontalalignment='center', # verticalalignment='bottom',) def init_harmonograph(self): t = np.linspace(0, self.t, self.n) self.ax.plot(*self.point(t), 'k', lw=0.5) if __name__ == "__main__": # kw1 = dict( # a=1, # b=1, # omega=np.pi/60, # phi=np.pi/180, # delta=np.pi/2, # tau=0 # ) # kw2 = dict( # a=0.2, # b=1, # omega=0.1204277183860873, # phi=np.pi/90, # delta=0, # tau=0 # ) kw1 = dict( a=1, b=0.3, omega=0.05, phi=2.5e-4, delta=0, tau=5e-7 ) kw2 = dict( a=0.5, b=0, omega=1/10, phi=5e-5, delta=0, tau=5e-5 ) p1 = Harmonograph(kw1, kw2, 7000) plt.show()