% fctgraph.sty
% from http://www.jokr.de/stefan/
% File created by Stefan Krause -- version 1.6.
% Creates plots for functions or point data with error bars.
% You may access
%  \begin{fctgraph}{}{}{}{}
%   \xaxis[]
%   \yaxis[]
%   \xgrid[]
%   \ygrid[]
%   \xscales
%   \yscales
%   \graphcurve[]{}
%   \graphfunction[]{}{}{}{}
%   \setpointstyle{}
%   \point[]{}{}
%   \pointerror[]{}{}{}{}
%  \end{fctgraph}
%  \setfctgraph{}{}
%   where #1 = arrowlength, arrowskip, arrowwidth, pointsize, scaleslength, xaxistextsep, xzoom, yaxistextsep, yzoom
%  fggray
%  \fgaxiscolor
%  \fgaxistextcolor
%  \fggridcolor
%  \fggraphcolor
% from this document.
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{fctgraph}[2009/01/29]
\RequirePackage{calc,color,curves,fp,ifthen}
\FPset\fgarrowlength{0.35}
\FPset\fgarrowskip{0.7}
\FPset\fgarrowwidth{0.1}
\FPset\fgpointsize{0.1}
\FPset\fgscaleslength{0.06}
\FPset\fgxaxistextsep{0.1}
\FPset\fgxzoom{1}
\FPset\fgyaxistextsep{0.15}
\FPset\fgyzoom{1}
\newcounter{fgcounter}
\newcounter{fgstyle}
\setcounter{fgstyle}{1}
\newcommand{\setfctgraph}[2]{\FPset{fg#1}{#2}}
\definecolor{fggray}{rgb}{0.85,0.85,0.85}
\newcommand{\fgaxiscolor}{black}
\newcommand{\fgaxistextcolor}{black}
\newcommand{\fggridcolor}{fggray}
\newcommand{\fggraphcolor}{blue}
\newlength{\fglength}
\newenvironment{fctgraph}[4]{%
 \FPset\fgxmin{#1}%
 \FPmul\fgxmin\fgxmin\fgxzoom%
 \FPsub\fgxmin\fgxmin\fgarrowskip%
 \FPset\fgymin{#2}%
 \FPmul\fgymin\fgymin\fgyzoom%
 \FPsub\fgymin\fgymin\fgarrowskip%
 \FPset\fgxmax{#3}%
 \FPmul\fgxmax\fgxmax\fgxzoom%
 \FPadd\fgxmax\fgxmax\fgarrowskip%
 \FPset\fgymax{#4}%
 \FPmul\fgymax\fgymax\fgyzoom%
 \FPadd\fgymax\fgymax\fgarrowskip%
 \FPsub\fgtempa\fgxmax\fgxmin%
 \FPsub\fgtempb\fgymax\fgymin%
 \begin{picture}(\FPprint\fgtempa,\FPprint\fgtempb)(\FPprint\fgxmin,\FPprint\fgymin)%
 \newcommand{\xaxis}[1][]{%
  \color{\fgaxiscolor}%
  \curve(\FPprint\fgxmin,0, \FPprint\fgxmax,0)%
  \FPsub\fgtempa\fgxmax\fgarrowlength%
  \curve(\FPprint\fgxmax,0, \FPprint\fgtempa,-\FPprint\fgarrowwidth)%
  \curve(\FPprint\fgxmax,0, \FPprint\fgtempa,\FPprint\fgarrowwidth)%
  \ifthenelse{\equal{##1}{}}{}{%
   \color{\fgaxistextcolor}%
   \FPsub\fgtempa\fgxmax\fgxmin%
   \setlength{\fglength}{\FPprint\fgtempa\unitlength}%
   \put(\FPprint\fgxmin,0){\parbox[b]{\fglength}{%
    \settoheight{\fglength}{##1}%
    \addtolength{\fglength}{\FPprint\fgarrowwidth\unitlength}%
    \addtolength{\fglength}{\FPprint\fgxaxistextsep\unitlength}%
    \hspace*{\fill}\raisebox{-\fglength}{##1}}%
   }%
  }%
 }%
 \newcommand{\yaxis}[1][]{%
  \color{\fgaxiscolor}%
  \curve(0,\FPprint\fgymin, 0,\FPprint\fgymax)%
  \FPsub\fgtempb\fgymax\fgarrowlength%
  \curve(0,\FPprint\fgymax, -\FPprint\fgarrowwidth,\FPprint\fgtempb)%
  \curve(0,\FPprint\fgymax, \FPprint\fgarrowwidth,\FPprint\fgtempb)%
  \ifthenelse{\equal{##1}{}}{}{%
   \color{\fgaxistextcolor}%
   \FPset\fgtempa\fgarrowwidth%
   \FPadd\fgtempa\fgtempa\fgyaxistextsep%
   \settoheight{\fglength}{##1}%
   \put(\FPprint\fgtempa,\FPprint\fgymax){\parbox[t]{\widthof{##1}}{\raisebox{-\fglength}{##1}}}%
  }%
 }%
 \newcommand{\xgrid}[1][1]{%
  \FPadd\fgxmin\fgxmin\fgarrowskip%
  \FPsub\fgxmax\fgxmax\fgarrowskip%
  \color{\fggridcolor}%
  \FPmul\fgtempc\fgxzoom{##1}%
  \FPdiv\fgtempa\fgxmin\fgtempc%
  \FPtrunc\fgtempa\fgtempa{0}%
  \FPmul\fgtempa\fgtempa\fgtempc%
  \FPiflt\fgtempa\fgxmin\FPadd\fgtempa\fgtempa\fgtempc\fi%
  \FPdiv\fgtempb\fgxmax\fgtempc%
  \FPtrunc\fgtempb\fgtempb{0}%
  \FPmul\fgtempb\fgtempb\fgtempc%
  \FPifgt\fgtempb\fgxmax\FPsub\fgtempb\fgtempb\fgtempc\fi%
  \FPifgt\fgtempa\fgtempb\else%
   \FPsub\fgtempb\fgtempb\fgtempa%
   \FPdiv\fgtempb\fgtempb\fgtempc%
   \FPadd\fgtempb\fgtempb{1}%
   \FPround\fgtempb\fgtempb{0}%
   \multiput(\FPprint\fgtempa,0)(\FPprint\fgtempc,0){\FPprint\fgtempb}{\curve(0,\FPprint\fgymin,0,\FPprint\fgymax)}%
  \fi%
  \FPsub\fgxmin\fgxmin\fgarrowskip%
  \FPadd\fgxmax\fgxmax\fgarrowskip%
 }%
 \newcommand{\ygrid}[1][1]{%
  \FPadd\fgymin\fgymin\fgarrowskip%
  \FPsub\fgymax\fgymax\fgarrowskip%
  \color{\fggridcolor}%
  \FPmul\fgtempc\fgyzoom{##1}%
  \FPdiv\fgtempa\fgymin\fgtempc%
  \FPtrunc\fgtempa\fgtempa{0}%
  \FPmul\fgtempa\fgtempa\fgtempc%
  \FPiflt\fgtempa\fgymin\FPadd\fgtempa\fgtempa\fgtempc\fi%
  \FPdiv\fgtempb\fgymax\fgtempc%
  \FPtrunc\fgtempb\fgtempb{0}%
  \FPmul\fgtempb\fgtempb\fgtempc%
  \FPifgt\fgtempb\fgymax\FPsub\fgtempb\fgtempb\fgtempc\fi%
  \FPifgt\fgtempa\fgtempb\else%
   \FPsub\fgtempb\fgtempb\fgtempa%
   \FPdiv\fgtempb\fgtempb\fgtempc%
   \FPadd\fgtempb\fgtempb{1}%
   \FPround\fgtempb\fgtempb{0}%
   \multiput(0,\FPprint\fgtempa)(0,\FPprint\fgtempc){\FPprint\fgtempb}{\curve(\FPprint\fgxmin,0,\FPprint\fgxmax,0)}%
  \fi%
  \FPsub\fgymin\fgymin\fgarrowskip%
  \FPadd\fgymax\fgymax\fgarrowskip%
 }%
 \newcommand{\xscales}{%
  \FPadd\fgxmin\fgxmin\fgarrowskip%
  \FPsub\fgxmax\fgxmax\fgarrowskip%
  \color{\fgaxiscolor}%
  \FPdiv\fgtempa\fgxmin\fgxzoom%
  \FPtrunc\fgtempa\fgtempa{0}%
  \FPmul\fgtempa\fgtempa\fgxzoom%
  \FPiflt\fgtempa\fgxmin\FPadd\fgtempa\fgtempa\fgxzoom\fi%
  \FPdiv\fgtempb\fgxmax\fgxzoom%
  \FPtrunc\fgtempb\fgtempb{0}%
  \FPmul\fgtempb\fgtempb\fgxzoom%
  \FPifgt\fgtempb\fgxmax\FPsub\fgtempb\fgtempb\fgxzoom\fi%
  \FPifgt\fgtempa\fgtempb\else%
   \FPsub\fgtempb\fgtempb\fgtempa%
   \FPdiv\fgtempb\fgtempb\fgxzoom%
   \FPadd\fgtempb\fgtempb{1}%
   \FPround\fgtempb\fgtempb{0}%
   \multiput(\FPprint\fgtempa,0)(\FPprint\fgxzoom,0){\FPprint\fgtempb}%
    {\curve(0,-\FPprint\fgscaleslength,0,\FPprint\fgscaleslength)}%
  \fi%
  \FPsub\fgxmin\fgxmin\fgarrowskip%
  \FPadd\fgxmax\fgxmax\fgarrowskip%
 }%
 \newcommand{\yscales}{%
  \FPadd\fgymin\fgymin\fgarrowskip%
  \FPsub\fgymax\fgymax\fgarrowskip%
  \color{\fgaxiscolor}%
  \FPdiv\fgtempa\fgymin\fgyzoom%
  \FPtrunc\fgtempa\fgtempa{0}%
  \FPmul\fgtempa\fgtempa\fgyzoom%
  \FPiflt\fgtempa\fgymin\FPadd\fgtempa\fgtempa\fgyzoom\fi%
  \FPdiv\fgtempb\fgymax\fgyzoom%
  \FPtrunc\fgtempb\fgtempb{0}%
  \FPmul\fgtempb\fgtempb\fgyzoom%
  \FPifgt\fgtempb\fgymax\FPsub\fgtempb\fgtempb\fgyzoom\fi%
  \FPifgt\fgtempa\fgtempb\else%
   \FPsub\fgtempb\fgtempb\fgtempa%
   \FPdiv\fgtempb\fgtempb\fgyzoom%
   \FPadd\fgtempb\fgtempb{1}%
   \FPround\fgtempb\fgtempb{0}%
   \multiput(0,\FPprint\fgtempa)(0,\FPprint\fgyzoom){\FPprint\fgtempb}%
    {\curve(-\FPprint\fgscaleslength,0,\FPprint\fgscaleslength,0)}%
  \fi%
  \FPsub\fgymin\fgymin\fgarrowskip%
  \FPadd\fgymax\fgymax\fgarrowskip%
 }%
 \newcommand{\graphcurve}[2][\fggraphcolor]{\color{##1}\curve(##2)}%
 \newcommand{\graphfunction}[5][\fggraphcolor]{%
  \color{##1}%
  \FPsub\fgtempa{##5}{##3}%
  \FPdiv\fgtempa\fgtempa{##4}%
  \FPadd\fgtempa\fgtempa{0.5}%
  \FPtrunc\fgtempa\fgtempa{0}%
  \setcounter{fgcounter}{\FPprint\fgtempa}%
  \FPset\fgtempa{##3}%
  \edef\fgx{\FPprint\fgtempa}%
  \edef\fgfctstr{##2}%
  \FPupn\fgtempb{\fgfctstr}%
  \FPmul\fgtempa\fgtempa\fgxzoom%
  \FPmul\fgtempb\fgtempb\fgyzoom%
  \edef\fgcoords{\FPprint\fgtempa,\FPprint\fgtempb}%
  \FPdiv\fgtempa\fgtempa\fgxzoom%
  \FPadd\fgtempa\fgtempa{##4}%
  \whiledo{\value{fgcounter}>0}{%
   \edef\fgx{\FPprint\fgtempa}%
   \edef\fgfctstr{##2}%
   \FPupn\fgtempb{\fgfctstr}%
   \FPmul\fgtempa\fgtempa\fgxzoom%
   \FPmul\fgtempb\fgtempb\fgyzoom%
   \edef\fgcoords{\fgcoords,\FPprint\fgtempa,\FPprint\fgtempb}%
   \FPdiv\fgtempa\fgtempa\fgxzoom%
   \FPadd\fgtempa\fgtempa{##4}%
   \addtocounter{fgcounter}{-1}%
  }%
  \curve(\fgcoords)%
 }%
 \newcommand{\setpointstyle}[1]{%
  \ifthenelse{\equal{##1}{}}{\setcounter{fgstyle}{0}}{}%
  \ifthenelse{\equal{##1}{+}}{\setcounter{fgstyle}{1}}{}%
  \ifthenelse{\equal{##1}{o}}{\setcounter{fgstyle}{2}}{}%
 }%
 \newcommand{\point}[3][\fggraphcolor]{%
  \color{##1}%
  \ifthenelse{\value{fgstyle}=1}{%  %% +
   \FPmul\fgtempa\fgxzoom{##2}%
   \FPmul\fgtempb\fgyzoom{##3}%
   \FPadd\fgtempc\fgtempa\fgpointsize%
   \FPsub\fgtempa\fgtempa\fgpointsize%
   \curve(\FPprint\fgtempa,\FPprint\fgtempb,\FPprint\fgtempc,\FPprint\fgtempb)%
   \FPmul\fgtempa\fgxzoom{##2}%
   \FPadd\fgtempc\fgtempb\fgpointsize%
   \FPsub\fgtempb\fgtempb\fgpointsize%
   \curve(\FPprint\fgtempa,\FPprint\fgtempb,\FPprint\fgtempa,\FPprint\fgtempc)%
  }{}%
  \ifthenelse{\value{fgstyle}=2}{%  %% o
   \FPmul\fgtempa\fgxzoom{##2}%
   \FPmul\fgtempb\fgyzoom{##3}%
   \put(\FPprint\fgtempa,\FPprint\fgtempb){\arc(\FPprint\fgpointsize,0){360}}%
  }{}%
 }%
 \newcommand{\pointerror}[5][\fggraphcolor]{%
  \point[##1]{##2}{##3}%
  \ifthenelse{\equal{##4}{}}{}{%
   \FPsub\fgtempa{##2}{##4}%
   \FPadd\fgtempc{##2}{##4}%
   \FPmul\fgtempb\fgyzoom{##3}%
   \FPmul\fgtempa\fgtempa\fgxzoom%
   \FPmul\fgtempc\fgtempc\fgxzoom%
   \curve(\FPprint\fgtempa,\FPprint\fgtempb,\FPprint\fgtempc,\FPprint\fgtempb)%
   \FPadd\fgtempc\fgtempb\fgpointsize%
   \FPsub\fgtempb\fgtempb\fgpointsize%
   \curve(\FPprint\fgtempa,\FPprint\fgtempb,\FPprint\fgtempa,\FPprint\fgtempc)%
   \FPadd\fgtempa{##2}{##4}%
   \FPmul\fgtempa\fgtempa\fgxzoom%
   \curve(\FPprint\fgtempa,\FPprint\fgtempb,\FPprint\fgtempa,\FPprint\fgtempc)%
  }%
  \ifthenelse{\equal{##5}{}}{}{%
   \FPmul\fgtempa\fgxzoom{##2}%
   \FPsub\fgtempb{##3}{##5}%
   \FPadd\fgtempc{##3}{##5}%
   \FPmul\fgtempb\fgtempb\fgyzoom%
   \FPmul\fgtempc\fgtempc\fgyzoom%
   \curve(\FPprint\fgtempa,\FPprint\fgtempb,\FPprint\fgtempa,\FPprint\fgtempc)%
   \FPadd\fgtempc\fgtempa\fgpointsize%
   \FPsub\fgtempa\fgtempa\fgpointsize%
   \curve(\FPprint\fgtempa,\FPprint\fgtempb,\FPprint\fgtempc,\FPprint\fgtempb)%
   \FPadd\fgtempb{##3}{##5}%
   \FPmul\fgtempb\fgtempb\fgyzoom%
   \curve(\FPprint\fgtempa,\FPprint\fgtempb,\FPprint\fgtempc,\FPprint\fgtempb)%
  }%
 }%
}{\end{picture}}
