Harmonograph#
Harmonograph geometry — sums of damped sinusoids in 2-D and 3-D.
Per axis: x(t) = Σ_i A_i · sin(ω_i · t + φ_i) · exp(-d_i · t).
A classic two-pendulum harmonograph (lateral) traces a single 2-D path. A rotary harmonograph adds a slow rotation around the origin. The 3-D variant extends the same idea to three axes.
References
- harmonograph_lateral(input: HarmonicInput, duration: float = 30.0, sr: int = 200, x_components: Sequence[int] | None = None, y_components: Sequence[int] | None = None) GeometryData[source]#
A two-pendulum lateral harmonograph trace.
- Parameters:
input (HarmonicInput) – Provides peak frequencies, amplitudes, phases, and (optionally) damping per component.
duration (float, default=30.0) – Duration of the trace in seconds.
sr (int, default=200) – Sample rate in samples per second. Downstream renderers may resample.
x_components, y_components (sequence of int, optional) – Indices of components assigned to each axis. If both are
None, components alternate (even indices → x, odd → y).
- Returns:
GeometryData –
geom_type='curve_2d'with shape(int(sr * duration), 2).
- harmonograph_rotary(input: HarmonicInput, duration: float = 30.0, sr: int = 200, rotation_freq: float = 0.1) GeometryData[source]#
Lateral harmonograph with an additional slow rotation about the origin.
The lateral trace is rotated by an angle
θ(t) = 2π · rotation_freq · t, producing the rosette-like rotary patterns of a circular harmonograph.- Parameters:
input (HarmonicInput)
duration (float, default=30.0)
sr (int, default=200)
rotation_freq (float, default=0.1) – Angular drift in Hz applied to the entire trace.
- Returns:
GeometryData –
geom_type='curve_2d'.
- harmonograph_3d(input: HarmonicInput, duration: float = 30.0, sr: int = 200, axis_assignment: str = 'cyclic') GeometryData[source]#
3-D harmonograph trace.
- Parameters:
input (HarmonicInput)
duration (float, default=30.0)
sr (int, default=200)
axis_assignment ({‘cyclic’, ‘split’}, default=’cyclic’) –
'cyclic': component i is assigned to axisi % 3.'split': components are split contiguously into three near-equal blocks for x, y, z.
- Returns:
GeometryData –
geom_type='curve_3d'.
- harmonograph_from_peaks(peaks: Sequence[float], amps: Sequence[float] | None = None, phases: Sequence[float] | None = None, damping: Sequence[float] | None = None, duration: float = 30.0, sr: int = 200) GeometryData[source]#
Convenience: build a lateral harmonograph directly from peak Hz values.
Internally constructs a
HarmonicInputand delegates toharmonograph_lateral(). IfdampingisNone, a uniform default ofDEFAULT_DAMPINGis used.
- derive_damping_from_linewidth(linewidths: Sequence[float], default: float = 0.01) ndarray[source]#
Convert spectral linewidths (FWHM, Hz) to damping coefficients (1/s).
For a Lorentzian peak with full width at half maximum
Δf, the underlying decay rate isπ · Δf(since the Lorentzian is the FT of a decaying exponentiale^(-π Δf t)).Non-positive or non-finite linewidths fall back to
default.