Interactive billiard

(see the examples/billiard.jl file to generate every animation)

interactive_billiard(bd::Billiard [, x, y, φ] [, ω=nothing]; kwargs...)
interactive_billiard(bd::Billiard, ps::Vector{<:AbstractParticle}; kwargs...)

Launch an interactive application that evolves particles in a dynamical billiard bd, using DynamicalBilliards.jl. Requires DynamicalBilliards.

You can either specify exactly the particles that will be used ps or provide some initial conditions x,y,φ,ω, which by default are random in the billiard. The particles are evolved in real time instead of being pre-calculated, so the application can be left to run for infinite time.

See also interactive_billiard_bmap and billiard_video.


Push "play" to start evolving particles in the billiard, and "reset" to restore them to their (latest) initial condition. The "particles" hides or shows the particles. The "speed" slider controls the animation speed (in fact, it controls how often are the plots updated).

Clicking and dragging inside the billiard plot shows a line. When the line is selected, new particles are created that have the direction of this line, as well as its starting position, using the function particlebeam from DynamicalBilliards.

Further keywords

  • N = 100 : if exact particles are not given, N are created. Otherwise it is length(ps).
  • dx = 0.01 : width of the particle beam.
  • dt = 0.001 : time resolution of the animation.
  • tail = 1000 : length of the tail of the particles (multiplies dt).
  • colors = JULIADYNAMICS_CMAP : If a symbol (colormap name) each particle gets a color from the map. If Vector of length N, each particle gets a color form the vector. If Vector with length < N, linear interpolation across contained colors is done.
  • tailwidth = 1 : Linewidth of the particle tail.
  • fade = true : Whether to add fadeout to the particle tail.
  • sleept = nothing : If the slowest speed of the animation is already too fast, give a small number to sleept.
  • plot_particles = true : If false, the particles are not plotted (as balls and arrows). This makes the application faster (you cannot show them again with the button).
  • particle_size = 1.0 A multiplier for the size of the particles.

For example, running

using DynamicalBilliards, InteractiveDynamics, GLMakie
bd, = billiard_logo(T = Float32)
interactive_billiard(bd, 1f0, tail = 1000)


Billiard video

billiard_video(file, bd::Billiard [, x, y, φ] [, ω=nothing]; kwargs...)
billiard_video(file, bd::Billiard, ps::Vector{<:AbstractParticle}; kwargs...)

Perform the same animation like in interactive_billiard, but there is no interaction; the result is saved directly as a video in file (no buttons are shown).


  • N, dt, tail, dx, colors, plot_particles, fade, tailwidth, backgroundcolor: same as in interactive_billiard, but plot_particles is false by default here.
  • speed = 5: Animation "speed" (how many dt steps are taken before a frame is recorded)
  • frames = 1000: amount of frames to record.
  • framerate = 60: exported framerate.
  • res = nothing: resolution of the frames. If nothing, a resolution matching the the billiard aspect ratio is estimated. Otherwise pass a 2-tuple.

Notice that the animation performs an extra step for every speed steps and the first frame saved is always at time 0. Therefore the following holds:

total_time = (frames-1)*(speed+1)*dt
time_covered_per_frame = (speed+1)*dt

Here is a video in the style of 3Blue1Brown

Video with timeseries

billiard_video_timeseries(file, bd::Billiard, ps, f; kwargs...)

Perform the same animation like in billiard_video, but in addition show the timeseries of a chosen observable above the billiard. The observable is given using the function f, which takes as an input a particle and outputs the observable. E.g. f(p) = p.pos[2] or f(p) = atan(p.vel[2], p.vel[1]). The video is saved directly into file.


  • N, dt, tail, dx, colors, plot_particles, fade, tailwidth, backgroundcolor: same as in interactive_billiard.
  • speed, frames, framerate, res: As in billiard_video.
  • total_span = 10.0: Total span of the x-axis of the timeseries plot in real time units.
  • ylim = (0, 1): Limits of the y-axis of the timeseries plot.
  • ylabel = "f": Label of the y-axis of the timeseries plot.

For example running

using InteractiveDynamics, DynamicalBilliards, GLMakie

psize = 2.0

bd = billiard_stadium(1.0f0, 1.0f0) # must be type Float32

frames = 1800
dt = 0.0001
speed = 200
f(p) = p.pos[2] # the function that obtains the data from the particle
total_span = 10.0

ps = particlebeam(1.0, 0.8, 0, 2, 0.0001, nothing, Float32)
ylim = (0, 1)
ylabel = "y"

    videodir("timeseries.mp4"), bd, ps, f;
    displayfigure = true, total_span,
    frames, backgroundcolor = :black,
    plot_particles = true, tailwidth = 4, particle_size = psize, res = MAXRES,
    dt, speed, tail = 20000, # this makes ultra fine temporal resolution
    framerate = 60, ylabel


Interactive with boundary map

interactive_billiard_bmap(bd::Billiard, ω=nothing; kwargs...)

Launch an interactive application whose left part is interactive_billiard and whose write part is an interactive boundary map of the billiard (see "Phase spaces" in DynamicalBilliards.jl).

A particle evolved in the real billiard is also shown on the boundary map. All interaction of the billiard works as before, but there is also interaction in the boundary map: clicking on it will generate a particle whose boundary map is the clicked point.

The mean collision time "m.c.t." of the particle is shown as well.


  • newcolor = randomcolor A function which takes as input (pos, vel, ξ, sφ) and outputs a color (for the scatter points in the boundary map).
  • ms = 12 markersize (in pixels).
  • dt, tail, sleept, fade : propagated to interactive_billiard.

Static plot with boundary map

billiard_bmap_plot(bd::Billiard, ps::Vector{<:AbstractParticle}; kwargs...)

Return a static figure which has particles plotted on both the real billiard as well the boundary map, each with its own color (keyword colors), and the same color is used for the corresponding scatter points in the boundary map.

All keyword arguments are the same as interactive_billiard_bmap, besides the interaction part of course. The additional keyword steps counts how many times to progress the particles (in multiples of dt).