# 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? – papabravo Dec 12 '13 at 22:11
ideally, Tikz should do all the work – Thomas Dec 12 '13 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? – papabravo Dec 12 '13 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 – Thomas Dec 12 '13 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. – Qrrbrbirlbel Dec 13 '13 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 ! – Thomas Dec 13 '13 at 13:10
@Thomas Yes, basically you can use any closed path that you can build with Bezier curves... – Alex Dec 13 '13 at 13:13
You sir, made my day :) – Thomas Dec 13 '13 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" – Thomas Dec 13 '13 at 15:07
The problem appears when the ray intersects the circle. – Thomas Dec 13 '13 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 Dec 13 '13 at 16:15
Nevermind, that's also a cool and simple solution :) – Thomas Dec 13 '13 at 19:08
Your edit with 2000 reflexions illustrates perfectly the chaotic properties of different shapes of billiard ! – Thomas Dec 14 '13 at 10:55