BeginPackage["Spirograph`"];

SpirographIn::usage = "Polecenie SpirographIn[r1,r2,d] rysuje 
spirograf powstajacy przez obrot okregu o promieniu r2
wewnatrz okregu o promieniu r1. Na mniejszym okregu w odleglosci
d od jego srodka znajduje sie rysik, ktory kresli spirograf";

SpirographOut::usage="Polecenie SpirographOut[r1,r2,d] rysuje 
spirograf powstajacy przez obrot okregu o promieniu r2 na 
zewnatrz okregu o promieniu r1. Na mniejszym okregu w odleglosci 
d od jego srodka znajduje sie rysik, ktory kresli spirograf";

SpirographIn::change = "Promien drugiego okregu (`1`) jest wiekszy 
od promienia pierwszego okregu (`2`). Zamieniam promienie";

SpirographIn::large = "Ostatni parametr (`1`) nie powinien byc 
wiekszy od mniejszego promienia (`2`).";

SpirographOut::large="Ostatni parametr (`1`) nie powinien byc 
wiekszy od drugiego promienia (`2`).";

Begin["Spirograph`Private`"];

Unprotect[SpirographIn,SpirographOut];

SpirographIn[R_,r_,d_]:=Block[{r1,r2,n},
    If[R>=r,r1=R;r2=r, 
       Message[SpirographIn::change,R,r];r2=R;r1=r];
    If[d>r2,Message[SpirographIn::large,d,r2]; 
              Return[HoldForm[SpirographIn[R,r,d]]]];
    n=LCM[r1,r2]/r2-1;
    ParametricPlot[{(r1-r2)*Sin[t]-d*Sin[n*t],
                    (r1-r2)*Cos[t]+d*Cos[n*t]},
              {t,0,2*Pi},AspectRatio->1,Axes->False,PlotRange->All]]

SpirographOut[R_,r_,d_]:=Block[{r1=R,r2=r,n},
    If[d>r2,Message[SpirographOut::large,d,r2];
              Return[HoldForm[SpirographOut[R,r,d]]]];
    n=LCM[r1,r2]/r2+1;
    ParametricPlot[{(r1+r2)*Sin[t]-d*Cos[n*t],
                    (r1+r2)*Cos[t]+d*Sin[n*t]}, 
              {t,0,2*Pi},AspectRatio->1,Axes->False,PlotRange->All]]


Protect[SpirographIn,SpirographOut];

End[]


EndPackage[]
