From eb9fae311a34cf6d756a88cbaa8c18d05c0db7a7 Mon Sep 17 00:00:00 2001 From: Daniel Mevec Date: Tue, 14 Feb 2023 16:19:08 +0100 Subject: [PATCH] start refactoring in python --- harmonograph.py | 116 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 harmonograph.py diff --git a/harmonograph.py b/harmonograph.py new file mode 100644 index 0000000..7311069 --- /dev/null +++ b/harmonograph.py @@ -0,0 +1,116 @@ +""" + 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()