Lissajous Curve Generator
Animate and explore Lissajous figures with interactive frequency and phase controls.
Formula
About this tool
A Lissajous curve is a mathematical shape produced by combining two perpendicular oscillations with different frequencies. Named after French physicist Jules Antoine Lissajous, these elegant parametric curves have captivated mathematicians and engineers for over 160 years. The beauty of Lissajous figures lies in their simplicity—just two sine waves create intricate, symmetrical patterns that range from simple ellipses to complex knot-like shapes.
Using this generator, you can experiment interactively with frequency ratios and phase differences to see how they shape the final curve. Adjust frequencies A and B independently, control the phase offset δ with precision, modify the curve's amplitude, and customize the visualization with colors and trail length. By playing the animation, you'll observe how the phase continuously evolves, morphing the figure through all its possible forms—a tangible way to understand harmonic relationships and resonance phenomena.
Lissajous curves are far more than decorative: they appear on oscilloscope displays in electrical engineering labs, illustrate coupled-pendulum motion in physics classrooms, visualize frequency relationships in audio engineering, and inform antenna design. Whether you're a student exploring parametric curves, an engineer debugging signal relationships, or simply someone fascinated by mathematical beauty, this tool makes the abstract concrete.
Frequently Asked Questions
Code Implementation
import math
def lissajous_points(freq_a: float, freq_b: float, delta: float,
amplitude: float = 1.0, num_points: int = 1000) -> list[tuple[float, float]]:
"""Generate Lissajous curve points.
x(t) = A * sin(a*t + delta)
y(t) = A * sin(b*t)
"""
points = []
for i in range(num_points):
t = 2 * math.pi * i / num_points
x = amplitude * math.sin(freq_a * t + delta)
y = amplitude * math.sin(freq_b * t)
points.append((x, y))
return points
# Common interesting ratios
ratios = [
(1, 1, math.pi / 4, "Ellipse (a:b=1:1)"),
(1, 2, math.pi / 4, "Figure-8 (a:b=1:2)"),
(2, 3, math.pi / 4, "Bow-tie (a:b=2:3)"),
(3, 4, math.pi / 4, "Complex knot (a:b=3:4)"),
(5, 4, 0, "Star pattern (a:b=5:4)"),
]
for a, b, delta, label in ratios:
pts = lissajous_points(a, b, delta)
x_vals = [p[0] for p in pts]
y_vals = [p[1] for p in pts]
print(f"{label}: x range [{min(x_vals):.3f}, {max(x_vals):.3f}]")
# Number of lobes = |a - b| or related to ratio
# Closed curve when a/b is rational
def is_closed(a: float, b: float) -> bool:
from math import gcd
if isinstance(a, int) and isinstance(b, int):
g = gcd(a, b)
return True # rational ratio
return False
print(f"\na=3, b=4 closed curve: {is_closed(3, 4)}")Comments & Feedback
Comments are powered by Giscus. Sign in with GitHub to leave a comment.