# Chaotic billiard with TikZ

I'm looking for a TikZ library that could help me to represent different shapes of chaotic billiards.

Any idea?

• do you want tikz to calculate the trajectories as well or do you have other means to prouduce a series of points? Commented Dec 12, 2013 at 22:11
• ideally, Tikz should do all the work Commented Dec 12, 2013 at 22:12
• Is there any way to parametrize the solution? It should be possible to come up with an analytically described path for the circle but how do you calculate it for other shapes? Commented Dec 12, 2013 at 22:17
• that is the main problem, for chaotic shapes the paths are very messy, I could probably find my points using matlab and do the conversion. I was wondering if a magic tool in Tikz could have an iterative way to represent this figure Commented Dec 12, 2013 at 22:21
• If you do not have the coordinate (the hits) beforehand, TikZ and its intersections library is not the tool for this task. It lacks the precision: For a circle of radius of 2 and a starting point of (45:2) and the direction -90, the result after 20 hit shows that the hits are not as expected all at (n*90+45:2) (for all integer ns). The result for 200 hits is even worse. Note that the inner empty region is shifting downwards. Commented Dec 13, 2013 at 19:51

This is another nice one for Asymptote, which can calculate intersections and directions of paths easily:

Here's the code for the stadium billiard:

\documentclass{standalone}
\usepackage{asymptote}

\begin{document}

\begin{asy}[width=10cm,height=10cm]
import graph;

size(200);

// circle billiard
// path bill = Circle((0,0),90.0);
// real phi = 2*pi*0.23456;

path bill = (-50,-50)--(50,-50)--arc((50,0), 50, -90, 90)
--(50,50)--(-50,50)--arc((-50,0), 50, 90, 270)--cycle;
real phi = 2*pi*0.123456;

draw(bill);

pair s = (20,20), db, dt = exp(I*phi), e = s+200*dt;
path traj = s--e;
real [] c;

for(int i=0; i<50; ++i) {

c = intersect(bill, traj);
e = point(traj, c[1]);
db = dir(bill, c[0]);

draw(s--e,red);
dot(e,blue);

dt = -dt + 2*dot(dt,db)*db;

s = e;
e = s + 200*dt;

traj = (s+dt)--e;
}
\end{asy}
\end{document}


To get the circle, uncomment the lines

// path bill = Circle((0,0),90.0);
// real phi = 2*pi*0.23456;


and comment out the billiard path

path bill = (-50,-50)--(50,-50)--arc((50,0), 50, -90, 90)
--(50,50)--(-50,50)--arc((-50,0), 50, 90, 270)--cycle;
real phi = 2*pi*0.123456;


EDIT: This question is so much fun, I had to do the Sinai billiard as well:

The code has only a few more lines:

\documentclass{standalone}
\usepackage{asymptote}

\begin{document}

\begin{asy}[width=10cm,height=10cm]
import graph;

size(200);

// Sinai billiard
path bill = (-90,-90)--(90,-90)--(90,90)--(-90,90)--cycle;
path inner = reverse(Circle((0,0),30.0));
real phi = 2*pi*0.05;

filldraw(bill^^inner,lightgray,black);

pair s = (30,30), db, dt = exp(I*phi), e = s+200*dt;
path traj = s--e;
real [] co;
real [][] ci;

for(int i=0; i<80; ++i) {

co = intersect(traj, bill);
ci = intersections(traj, inner);

if(ci.length > 0) {
e = point(traj, ci[0][0]);
db = dir(inner, ci[0][1]);
} else {
e = point(traj, co[0]);
db = dir(bill, co[1]);
}

draw(s--e,red);
dot(e,blue);

dt = -dt + 2*dot(dt,db)*db;

s = e;
e = s + 200*dt;

traj = (s+dt)--e;
}
\end{asy}

\end{document}

• That seems also very simple to use, thanks a lot ! Commented Dec 13, 2013 at 13:10
• @Thomas Yes, basically you can use any closed path that you can build with Bezier curves...
– Alex
Commented Dec 13, 2013 at 13:13
• You sir, made my day :) Commented Dec 13, 2013 at 13:14
• The Sinai billiard makes me a mistake during the Asymptote compilation : "rading array of length 2 with out-of-bounds index 4" Commented Dec 13, 2013 at 15:07
• The problem appears when the ray intersects the circle. Commented Dec 13, 2013 at 15:16

For comparison, here is a translation of Alex's code to Metapost.

\starttext
\startMPpage[offset=2mm]

u := 1mm;
phi := 0.12345;

path billiard, ball, trajectory;
pair dt, hit, location, awayPoint, tangent;

billiard = (-50u,-50u)--( 50u,-50u) {right} .. {left}  (50u, 50u)
-- (-50u, 50u)--(-50u, 50u) {left}  .. {right} cycle;

ball := fullcircle scaled 3mm;

draw billiard;

location := (20u, 20u);
dt := dir(phi);

for i = 0 upto 50 :
awayPoint := location + 200u*dt ;
trajectory := (location+dt) -- awayPoint;

save timeBilliard, timeBall;
(timeBilliard, timeBall) = billiard intersectiontimes trajectory;

hit := point timeBilliard of billiard;
draw location -- hit withcolor red;
fill ball shifted hit withcolor blue;

tangent := direction timeBilliard of billiard;
% The result of direction has arbitrary magnitude. Normalize it;
tangent := tangent/abs(tangent);

dt := -dt + 2*(dt dotprod tangent)*tangent;
location  := hit;

endfor

\stopMPpage
\stoptext


which gives:

Increasing the amount of reflections to 500 gives:

and increasing it to 2000 gives:

which shows space filling.

If however one starts with a circle, then 2000 collisions gives:

A fun option is to add randomization to the reflection: After normalizing the tangent add

  % Randomize the tangent
tangent := tangent randomized 0.3;
% Renormalize the result
tangent := tangent/abs(tangent);


which gives:

With this randomization, if you start with a circle, you get space filling (after 2000 collisions):

• Cool. But still no tikz solution ;-)
– Alex
Commented Dec 13, 2013 at 16:15
• Nevermind, that's also a cool and simple solution :) Commented Dec 13, 2013 at 19:08
• Your edit with 2000 reflexions illustrates perfectly the chaotic properties of different shapes of billiard ! Commented Dec 14, 2013 at 10:55