(***************************************************************************)
(*                                                                         *)
(*  File:             latexpic.m                                           *)
(*                                                                         *)
(*  Author:           Oliver Knill,  March 26, 1998                        *)
(*                                                                         *)
(*  Description:      exports LateX planar Bezier curves from Mathematica  *)
(*                    exports graphs of mathematical functions             *)
(*                    using shorter Bezier code unlike gnuplot             *)
(*                    exports pictures made out of points (i.e. orbits of  *)
(*                    discrete dynamical systems).                         *)
(*                                                                         *)
(*  Use:              just run this file in Mathematica. In Unix:          *)
(*                    math<latexpict.m                                     *)
(*                    produces LaTeX file test.tex with examples           *)
(*                    A graph for a function,    a phase space capture     *)
(*                    of a chaotic map, and a planar Lissajou figure.      *)
(*                                                                         *)
(*  Requires:         Requires LaTeX and Mathematica (www.mathematica.com) *)
(*                                                                         *)
(*  When to use:      Use for small illustrations in a LaTeX article when  *)
(*                    it is convenient to have everything in one file      *)
(*                    without additional PS figures (i.e. Preprint archive)*)
(*                                                                         *)
(*  Remark:           LateX can complain about being out of memory for     *)
(*                    complex figures. Reducing UnitLength or              *)
(*                    PictureWidth or number of Bezier curves can help.    *)
(*                    The number of points in the Bezier curves must be    *)
(*                    chosen from case to case. For example, if a curve    *)
(*                    has too large curvature, the LaTeX figure can get    *)
(*                    screwed up. This usually needs some tuning.          *)
(*                                                                         *)
(*  Suggestion:       Adapt the procedures in this file to build up your   *)
(*                    own figures. You might want to add your own macros   *)
(*                    and a little library of things which you need to put *)
(*                    together for your figure. The best for me was to keep*)
(*                    a seperate file for each figure  together with the   *)
(*                    LaTeX file for later adaptions or as template.       *)
(*                                                                         *)
(*  For future:       Mathematica will maybe sooner or later have built-in *)
(*                    feature to export planar Bezier curves in Latex.     *)
(*                    So, we didn't bother to make this a real Mathematica *)
(*                    package and just used it pragmatically while writing *) 
(*                    research papers. Maybe this template is useful for   *)
(*                    others in one or the other situation.                *)
(*                                                                         *)
(***************************************************************************)


FileName="test";                   (*  test.tex will be the exported file  *)
PictureWidth=1000;                 (*  Number of points in LaTeX picture   *)
UnitLength="0.02mm"                (*  Width of one point                  *)


TeXFileName=Module[{v,w},
  v=ToCharacterCode[FileName];
  w=ToCharacterCode[".tex"];
  FromCharacterCode[Join[v,w]]
];

LaTeXFile:=Module[{u,v,w},
  u=ToCharacterCode["latex "];
  v=ToCharacterCode[FileName];
  w=ToCharacterCode[".tex"];
  Run[FromCharacterCode[Join[u,v,w]]];
];

ShowDviFile:=Module[{u,v,w},
  u=ToCharacterCode["xdvi "];
  v=ToCharacterCode[FileName];
  w=ToCharacterCode[".dvi &"];
  Run[FromCharacterCode[Join[u,v,w]]]
];

WS[s__]:=WriteString[TeXFileName,s];

BeginTeXFile:= Module[{},
  If[Length[FileInformation[TeXFileName]]>0,DeleteFile[TeXFileName]];
  WS["\NeedsTeXFormat{LaTeX2e} \n"];
  WS["\documentclass[]{article} \n"];
  WS["\begin{document} \n "];
  WS["\\newcommand{\cc}[2]{\put(#1,#2){\circle*{13}}} \n"]; 
]; 

EndTeXFile:=WS["\end{document}"];

fitt[r_] :=Round[PictureWidth*r];

CurveToBezier[{x_,y_},{t1_,t2_}]:=Module[{mu, xmid, ymid,
   xt1=x[t1], xt2=x[t2], yt1=y[t1], yt2=y[t2],
   xdott1=D[x[t],t] /. t->t1, xdott2=D[x[t],t] /. t->t2,
   ydott1=D[y[t],t] /. t->t1, ydott2=D[y[t],t] /. t->t2},
   mu=(xt1* ydott1-xdott1*yt1-xt2 ydott1+xdott1*yt2)/
      (xdott2*ydott1-xdott1 ydott2);
   xmid=xt2+mu*xdott2; ymid=yt2+mu*ydott2;
   WS[" \qbezier(", fitt[xt1] , ",", fitt[yt1] , ")(",
                    fitt[xmid], ",", fitt[ymid], ")(",
                    fitt[xt2] , ",", fitt[yt2] , ") \n" ] 
];

BezierPicture[{x_,y_},{t1_,t2_},n_]:= Module[{},
  Do[CurveToBezier[{x,y},
  {t1+k*(t2-t1)/n,t1+(k+1)*(t2-t1)/n}],{k,0,n-1}]
];


StartPicture:=Module[{},
   WS[" "];
   WS[" \setlength{\unitlength}{"];WS[UnitLength]; WS["} \n"];
   WS[" \begin{picture}(1000,1000)      \n"]; 
];

EndPicture:= WS[" \end{picture}         \n"];


WriteText[{x1_,y1_},text_]:=WS[" \put(",fitt[x1],",",
   fitt[y1],"){",text,"} \n"];

NewLine:=WriteString[TeXFileName,"\n"]; 

PointPicture[{x1_,y1_}]:=WS["\cc{",fitt[x1],"}{",fitt[y1],"}"];

HorizontalLine[{x1_,y1_},l_]:=WS[" \put(",fitt[x1],",",fitt[y1],
   "){\vector(1,0){",fitt[l],"}} \n"
];

VerticalLine[{x1_,y1_},l_]:=WS[" \put(",fitt[x1],",",fitt[y1],
   "){\vector(0,1){",fitt[l],"}} \n"
];

VerticalVector[{x1_,y1_},l_]:=Module[{},
  WS[" \put("];          WS[fitt[x1]]; WS[","]; WS[fitt[y1]];
  WS["){\vector(0,1){"]; WS[fitt[l]];  WS["}}"]
];

HorizontalVector[{x1_,y1_},l_]:=Module[{},
  WS[" \put("];          WS[fitt[x1]]; WS[","]; WS[fitt[y1]];
  WS["){\vector(1,0){"]; WS[fitt[l]];  WS["}}"]
];

StraightLine[{x1_,y1_},{x2_,y2_}]:=Module[{},
  WS[" \qbezier( "];   WS[fitt[x1]]; WS[","]; WS[fitt[y1]];
  WS[")"]; WS[" ( "];  WS[fitt[(x1+x2)/2]];   WS[","];
  WS[fitt[(y1+y2)/2]]; WS[")"]; WS[" ( "];    WS[fitt[x2]];
  WS[","]; WS[fitt[y2]]; WS[") \n"];
];

SquareFrame[{x1_,y1_},l_]:=Module[{},
   WS[ "\put(",fitt[x1],",",fitt[y1],"){\\framebox(",
      fitt[l],",",fitt[l],"){}} \n"]
];


(***************************************************************************)
(*      EXAMPLES                                                           *)
(***************************************************************************)

LissajouExample:=Module[{},
  BeginTeXFile;
    StartPicture;
      g[x_]:=1*Sin[2Pi 5*x];
      h[x_]:=1*Cos[2Pi 7*x];
      BezierPicture[{g,h},{0,1.0},51];
    EndPicture;
  EndTeXFile;
  LaTeXFile;
  ShowDviFile;
];

GraphExample:=Module[{},
  BeginTeXFile;
    StartPicture;
      g[x_]:=x;
      h[x_]:=Cos[2Pi 2*x];
      BezierPicture[{g,h},{0,3.0},101];
    EndPicture;
    HorizontalVector[{-1,-1},2.5];   
    VerticalVector[{-1,-1},2.5];   
    WriteText[{-1.2, 2.0},y];      
    WriteText[{ 2.2,-1.2},x];      
  EndTeXFile;
  LaTeXFile;
  ShowDviFile;
];

StandardMapExample:=Module[{}, 
  BeginTeXFile;
    StartPicture;
      g=2.1; P=N[Pi]; g1=g/(2Pi);      
      StandardMap[{x_,y_}]:=N[Mod[{2x-y+g1*Sin[2 P x],x},1]];
      StandardOrbit[{x1_,y1_},n_]:=Module[{x0=x1,y0=y1}, 
        Do[
          PointPicture[{x0,y0}]; 
          If[Mod[j,6]==0, NewLine];   
          {x0,y0}=StandardMap[{x0,y0}],{j,n} 
        ]        
      ]; 
      SquareFrame[{-0.0001,-0.0001},1.0002];
      StandardOrbit[{0.26,0.26},500]; 
      StandardOrbit[{0.29,0.29},200];
      StandardOrbit[{0.40,0.33},200];
      StandardOrbit[{0.44,0.40},200];
      StandardOrbit[{0.45,0.38},200]; 
      StandardOrbit[{0.48,0.49},100]; 
      StandardOrbit[{0.47,0.47},100]; 
      StandardOrbit[{0.10,0.35},2000];
    EndPicture;
  EndTeXFile;
  LaTeXFile;
  ShowDviFile;              
]

GraphExample                                  
LissajouExample                           
StandardMapExample                               

