This simulation renders the phase plane of a 2D dynamical system entirely on the GPU using a Line-Integral-Convolution (LIC) style GLSL shader: domain-warped noise is smeared along the local vector-field direction, producing flowing streamlines instead of discrete arrows. Colour encodes local speed |(f, g)|, and a soft glow marks fixed points where the velocity vanishes. Five systems are built in — a tunable linear 2×2 matrix, the van der Pol oscillator, a damped pendulum, Lotka-Volterra predator-prey, and the double-well Duffing oscillator — each revealing a different kind of long-term behaviour, from spirals and saddles to a genuinely nonlinear limit cycle.
The velocity field (dx/dt, dy/dt) = (f(x,y), g(x,y)) evaluated at every pixel, visualised as animated streamlines whose colour ramps blue→cyan→yellow→red with increasing speed. Fixed points, where the field is zero, glow softly. For the linear system a live readout classifies the equilibrium — saddle, node, spiral or centre — directly from the trace and determinant of the matrix.
Choose a system from the list, then drag Parameter a and Parameter b to reshape its dynamics: for the linear case they move the equilibrium between stable/unstable spirals, nodes, a saddle and a centre; for van der Pol, parameter a is the nonlinear damping μ; for the pendulum it is damping and drive torque; for Lotka-Volterra it is prey growth and predator death rates; for Duffing it is damping. Flow speed controls how fast the streamlines animate, and Reset restores the selected system's defaults.
The van der Pol oscillator, invented in the 1920s to model vacuum-tube circuits, settles onto a limit cycle — a single closed loop that trajectories spiral onto from both inside and outside. No linear system, however you tune its matrix, can produce this behaviour: limit cycles are a genuinely nonlinear phenomenon, and van der Pol's equation became one of the founding examples in the study of self-sustained oscillations.
A phase portrait is a picture of the state space of a dynamical system, showing how every possible starting point evolves over time. In this simulation, each point in the plane has a velocity vector (dx/dt, dy/dt) determined by the chosen system's equations, and the flowing streamlines are a Line-Integral-Convolution rendering of that vector field — noise smeared along the local flow direction — so you can see the overall pattern of motion at a glance rather than following one trajectory at a time.
For the linear system with matrix [[a, b], [-b, a]], the trace is T = 2a and the determinant is D = a² + b². If D < 0 the origin is a saddle (unstable in one direction, stable in another); if D > 0 and T² < 4D it is a spiral, stable when T < 0 and unstable when T > 0; if D > 0 and T² > 4D it is a node; and if T = 0 with D > 0 it is a centre, surrounded by closed orbits. The readout panel computes this classification live as you move the sliders.
A standard damped linear oscillator always spirals into a single equilibrium point and stays there. The van der Pol equation ẋ = y, ẏ = μ(1−x²)y − x has damping that flips sign depending on amplitude: it energises small oscillations and damps large ones, so trajectories from both inside and outside converge onto the same closed orbit, called a limit cycle. This self-correcting oscillation amplitude is why van der Pol's model is used to describe heartbeats, vacuum-tube circuits and other self-sustained oscillators.
The Lotka-Volterra equations ẋ = a·x − x·y, ẏ = x·y − b·y model a predator-prey pair: prey (x) grow exponentially at rate a in the absence of predators, and predators (y) die off at rate b without prey to eat. The closed orbits encircling the coexistence point (b, a) mean populations cycle periodically rather than settling to a fixed value — a rise in prey feeds a rise in predators, which then depletes prey, which starves predators, and the cycle repeats, never converging to equilibrium.
The Duffing system ẋ = y, ẏ = −b·y + x − x³ describes motion in a double-well potential, physically like a ball that can settle in either of two dips separated by a hump. The cubic term −x³ creates two symmetric stable equilibria at x = ±1 (each a spiral when damping b > 0) and an unstable saddle at the origin separating their basins of attraction, so which spiral a trajectory ends up on depends sensitively on its starting position relative to the saddle.