prologues:=2;

u=1cm;

% Nécessaire pour les "graduations"
input format;
init_numbers(btex $-$ etex, 
             btex$1$etex, 
             btex$ times 10$etex, 
             btex$"" sup -$etex, 
             btex$"" sup 2$etex);

% Nécessaire pour une largeur et une longueur 
% assez grande (par exemple a=37 et b=25)
input marith;

% Quelques macros arithmétiques
vardef pgcd(expr A,B) = 
    save a,b,r;
    numeric a,b,r;
    a := A; b := B;
    forever: 
        r := a mod b;
        a := b; b := r;
        exitunless r > 0;
    endfor;
    a
enddef;

vardef ppcm(expr A,B)=
  A * B / pgcd(A,B)
enddef;

vardef billardarithmetique(expr a,b)=
  pair O,A,B,C,M[];
  O=u*(0,0);
  A=u*(a,0);
  B=u*(a,b);
  C=u*(0,b);
  M[0]=O;
  % On définit les points en juxtaposant horizontalement 
  % le maillage
  for j=0 upto (ppcm(a,b)-1):
    k:=j div b;
    if k mod 2=0:
        M[j+1]-M[j]=u*(1,1);
    else:
        M[j+1]-M[j]=u*(1,-1);
    fi;
  endfor;

  % On les replace dans le rectangle de départ
  for j=0 upto ppcm(a,b):
    k:=j div a;
    if (k mod 2=0) :
        M[j]:=M[j] shifted(u*(-k*(a,0)));
    else:
        M[j]:=M[j] reflectedabout(u*(a,0),u*(a,b)) 
                   shifted(u*(k-1)*(a,0));
    fi;
  endfor;
  picture billard;
  billard=image(
    label.rt(btex $A$ etex,A);
    label.rt(btex $B$ etex,B);
    label.lft(btex $C$ etex,C);
    label.lft(btex $O$ etex,O);
    
    %La grille
    for k=0 upto a:
      draw ((0,0)--u*(0,b)) shifted(u*(k,0));
    endfor;
    for k=0 upto b:
      draw ((0,0)--u*(a,0)) shifted(u*(0,k));
    endfor;
    draw (0,0)--u*(a,0)--u*(a,b)--u*(0,b)--cycle 
    withpen pencircle scaled 2bp;
    
    %On trace le chemin
    for k=1 upto ppcm(a,b):
      drawarrow M[k-1]--M[k] withcolor (red+green);
    endfor;
    
    %Passons à la numérotation des noeuds du quadrillage
    label.bot(btex 0 etex,M0);
    %On déplace légèrement le point à nommer en fonction du point précédent
    for j=1 upto ppcm(a,b):
      label(format("%10f",j),
	M[j] shifted(M[j-1]-75/100[M[j],M[j-1]]));
    endfor;
    );
  billard
enddef;


beginfig(1);
  draw billardarithmetique(12,5);
endfig;

beginfig(2);
  draw billardarithmetique(5,12);
endfig;

beginfig(3);
  draw billardarithmetique(8,8);
endfig;

beginfig(4);
  draw billardarithmetique(15,10);
endfig;
end