Note
Go to the end to download the full example code.
Circle Billiard (Integrable)#
A billiard is a point particle moving in a straight line at constant speed inside a closed boundary, until it strikes the boundary and undergoes specular reflection – the outgoing velocity \(\mathbf{v}'\) obtained from the incoming velocity \(\mathbf{v}\) and the local unit normal \(\mathbf{n}\) by
The circular billiard, whose boundary is \(x^2 + y^2 = r^2\), is the simplest integrable 2D billiard: the angle of incidence at every bounce is exactly conserved, so the boundary phase-space coordinate \(\sin\phi\) (the sine of the angle between the outgoing velocity and the local boundary tangent) never changes along a trajectory. This example plots a single trajectory and the resulting Poincare section.
import matplotlib.pyplot as plt
import numpy as np
from physicskit.chaos.systems.billiards import CircleBilliard
from physicskit.chaos.visualizers.dynamic_plots import animate_billiard_trajectory
from physicskit.chaos.visualizers.phase_space import plot_billiard_trajectory, plot_poincare_section
billiard = CircleBilliard(radius=1.0)
Launch off-center#
The circle’s default interior point (used elsewhere for e.g. sampling starting positions) is its exact center – and a ray launched from dead center hits the boundary head-on at every bounce, reflecting straight back through the center each time: a degenerate back-and-forth line, not the star-like pattern integrability is famous for. Any off-center point avoids this.
pos = (0.3, 0.0)
Animation#
Watch the ray bounce around the disk, tracing out the star-like pattern live alongside its Poincare section filling in point by point.
To save the animation to a file instead of (or in addition to) displaying it interactively, use e.g.:
anim.save("circle_billiard_animation.gif", writer="pillow", fps=25)
Trajectory#
A single ray, launched from an interior point, bounces around the disk forever tracing out a star-like pattern (unless its angle is a rational multiple of pi, in which case it eventually closes on itself).

Poincare section#
Because the circle is integrable, sin(phi) is an exact invariant of the
motion: each ray traces out its own horizontal line in the (s,
sin(phi)) section, at whatever sin(phi) its own impact parameter
fixes, regardless of how many bounces are simulated – together, many rays
from the same off-center point foliate the section into a family of such
lines (rays launched from dead center, by symmetry, would all share the
same sin(phi) = 0 and collapse onto a single line instead).

Total running time of the script: (0 minutes 5.451 seconds)