Lissajous#
Lissajous-curve geometry.
Standard 2-D form: x(t) = A_x · sin(a · t + δ), y(t) = A_y · sin(b · t).
For coprime integer frequency ratios (a, b) and arbitrary phase δ, the
curve closes after t ∈ [0, 2π]. A pairwise-coprime triple (a, b, c)
applied to the three Cartesian axes yields a Lissajous knot.
References
- lissajous_2d(ratio: Fraction | int | float | Tuple[int, int], phase: float = 1.5707963267948966, amps: Tuple[float, float] = (1.0, 1.0), n_points: int = 1000, n_periods: int = 1) GeometryData[source]#
A single 2-D Lissajous curve.
Samples
x(t) = A_x · sin(a · t + phase)andy(t) = A_y · sin(b · t)overt ∈ [0, 2π · n_periods], where(a, b)is a coprime representation ofratio.- Parameters:
ratio (Fraction, int, float, or (int, int)) – Frequency ratio
a / bof the x-component to the y-component.phase (float, default=π/2) – Phase shift
δin radians applied to the x-component.amps (tuple of float, default=(1.0, 1.0)) – Amplitudes
(A_x, A_y).n_points (int, default=1000) – Number of samples along the curve.
n_periods (int, default=1) – Number of fundamental periods to sample. For coprime
(a, b)the curve closes after one period.
- Returns:
GeometryData –
geom_type='curve_2d'with shape(n_points, 2). Metadata includes the coprime(a, b)pair, closure flag, and phase.
- lissajous_3d(ratios: Sequence[Fraction | int | float | Tuple[int, int]], phases: Sequence[float] = (0.0, 0.0, 0.0), amps: Sequence[float] = (1.0, 1.0, 1.0), n_points: int = 2000) GeometryData[source]#
A 3-D Lissajous curve.
Samples
x_i(t) = A_i · sin(f_i · t + φ_i)fori ∈ {0, 1, 2}, wheref_iis a coprime integer derived fromratios[i].When all three
f_iare pairwise coprime the resulting curve is a Lissajous knot; this is flagged inmetadata['knot'].- Parameters:
ratios (sequence of length 3) – Frequencies for x, y, z.
phases (sequence of length 3, default=(0, 0, 0)) – Phase per axis in radians.
amps (sequence of length 3, default=(1, 1, 1)) – Amplitude per axis.
n_points (int, default=2000)
- Returns:
GeometryData –
geom_type='curve_3d'with shape(n_points, 3).
- lissajous_pairwise_grid(input: HarmonicInput, n_points: int = 500, phase: float = 1.5707963267948966) List[List[GeometryData]][source]#
Build a 2-D grid of pairwise Lissajous curves from a HarmonicInput.
For an input with N components, returns an N×N nested list where entry
[i][j]is the 2-D Lissajous of component i (x-axis) against component j (y-axis). The diagonal contains 1:1 unison curves.- Parameters:
input (HarmonicInput)
n_points (int, default=500)
phase (float, default=π/2)
- Returns:
list of list of GeometryData –
N × Nmatrix ofcurve_2dgeometries.
- lissajous_compound(input: HarmonicInput, n_points: int = 2000, n_periods: int = 1) GeometryData[source]#
Sum-of-sinusoids Lissajous from a HarmonicInput.
Treats the input components as a chord. The x-coordinate is the sum of all components phase-shifted by
π/2; the y-coordinate is the sum without the phase shift. This collapses an N-component HarmonicInput into a single 2-D Lissajous-like curve.- Parameters:
input (HarmonicInput)
n_points (int, default=2000)
n_periods (int, default=1)
- Returns:
GeometryData –
geom_type='curve_2d'.
- lissajous_phase_drift(ratio: Fraction | int | float | Tuple[int, int], drift_rate: float, duration: float, sr: int = 1000, amps: Tuple[float, float] = (1.0, 1.0)) GeometryData[source]#
Lissajous with a linearly-drifting phase.
The phase
δ(t) = drift_rate · tevolves linearly with time, producing the classic “spinning” Lissajous animation when rendered.- Parameters:
ratio (Fraction, int, float, or (int, int))
drift_rate (float) – Phase drift in radians per second.
duration (float) – Total duration in seconds.
sr (int, default=1000) – Sample rate (samples per second).
amps (tuple of float, default=(1.0, 1.0))
- Returns:
GeometryData –
geom_type='curve_2d'with shape(int(sr * duration), 2).
- lissajous_topology(geom: GeometryData) dict[source]#
Inspect a Lissajous-style
curve_2dand return topological summary.- Parameters:
geom (GeometryData) – Must have
geom_type='curve_2d'.- Returns:
dict – Keys:
'lobes_x','lobes_y'— integer lobe counts (read from metadata when available; otherwise estimated by counting zero crossings on each axis).'closed'— whether the first and last points coincide within a small tolerance.'self_intersections'— count of polyline self-intersections (brute-force,O(N²)).'period_ratio'—Fractionrepresenting thea / bratio when known, elseNone.