%D In order to support rotation over arbitrary angles, we need a sine
%D and  cosine calculator. For this purpose we borrow a few macros by
%D David  Carlisle (his trig package). Because local variables are
%D used, I patched the macros a bit. Also, I used a few different names
%D for variabels and macros and use existing auxiliary macros.

\unprotect

\chardef     \@iv         =     4
\chardef     \@xc         =    90 % was \nin@ty
\chardef     \@clxx       =   180
\chardef     \@lxxi       =    71
\mathchardef \@mmmmlxviii =  4068
\mathchardef \@xvi@k      = 16384

\chardef     \tr@coeffz   =    72
\chardef     \tr@coefb    =    42
\mathchardef \tr@coefc    =   840
\mathchardef \tr@coefd    =  5040

\def\tg@series
  {\!!dimena\@lxxi\!!dimena
   \divide\!!dimena\@mmmmlxviii
   \edef\!!stringa{\withoutpt\the\!!dimena}%
   \!!dimena\!!stringa\!!dimena
   \edef\!!stringb{\withoutpt\the\!!dimena}%
   \divide\!!dimena\tr@coeffz
   \advance\!!dimena\minusone\onepoint
   \!!dimena\!!stringb\!!dimena
   \advance\!!dimena \tr@coefb\onepoint
   \!!dimena\!!stringb\!!dimena
   \advance\!!dimena -\tr@coefc\onepoint
   \!!dimena\!!stringb\!!dimena
   \advance\!!dimena \tr@coefd\onepoint
   \!!dimena\!!stringa\!!dimena
   \divide\!!dimena \tr@coefd}

\def\tg@reduce#1#2%
  {\!!dimena#1#2\@xc\onepoint
   \advance\!!dimena#2-\@clxx\onepoint
   \!!dimena-\!!dimena
   \tg@@sin}

\def\tg@@sin
  {\ifdim\tg@reduce>+\else\ifdim\tg@reduce<-\else
     \tg@series
   \fi\fi}

%D Calculating a sine is a two step process: first a value is
%D calculated, and afterwards it can be used. This saves redundant
%D calculations.

\def\calculatesin#1%
  {{\expandafter\ifx\csname sin \number#1\endcsname\relax
      \!!dimena#1\onepoint
      \tg@@sin
      \expandafter\xdef\csname sin \number#1\endcsname{\withoutpt\the\!!dimena}%
    \fi}}

\def\calculatecos#1%
  {{\expandafter\ifx\csname cos \number#1\endcsname\relax
      \!!dimena\@xc\onepoint
      \advance\!!dimena-#1\onepoint
      \tg@@sin
      \expandafter\xdef\csname cos \number#1\endcsname{\withoutpt\the\!!dimena}%
    \fi}}

\def\calculatetan#1%
  {{\expandafter\ifx\csname tan \number#1\endcsname\relax
      \calculatesin{#1}%
      \calculatecos{#1}%
      \!!dimena\calculatedcos{#1}\onepoint
      \divide\!!dimena\@iv
      \!!dimenb\calculatedsin{#1}\onepoint
      \!!dimenb\@xvi@k\!!dimenb
      \divide\!!dimenb\!!dimena
      \expandafter\xdef\csname tan \number#1\endcsname{\withoutpt\the\!!dimenb}%
   \fi}}

%D The results are accessed with:

\def\calculatedsin#1{\csname sin \number#1\endcsname}
\def\calculatedcos#1{\csname cos \number#1\endcsname}
\def\calculatedtan#1{\csname tan \number#1\endcsname}

%D A more save implementation would be:

\def\calculatedsin#1{\executeifdefined{sin \number#1}\!!zerocount}
\def\calculatedcos#1{\executeifdefined{cos \number#1}\!!plusone}
\def\calculatedtan#1{\executeifdefined{tan \number#1}\!!zerocount}

%D A few values are predefined, although, on todays systems there
%D is no real reason for that. I've added the 270 ones and changed
%D the -90 tan. Also, I prefer text (\type {\!!..} instead of
%D counters \type {\..}.

\expandafter\let\csname sin   0\endcsname\!!zerocount
\expandafter\let\csname cos   0\endcsname\!!plusone
\expandafter\let\csname sin  90\endcsname\!!plusone
\expandafter\let\csname cos  90\endcsname\!!zerocount
\expandafter\let\csname sin 180\endcsname\!!zerocount
\expandafter\let\csname cos 180\endcsname\!!minusone
\expandafter\let\csname sin 270\endcsname\!!minusone
\expandafter\let\csname cos 270\endcsname\!!zerocount

\expandafter\let\csname sin -90\endcsname\!!minusone
\expandafter\let\csname cos -90\endcsname\!!zerocount

\expandafter\def\csname tan  90\endcsname{\writestatus\m!systems{infinite tan +90}}
\expandafter\def\csname tan -90\endcsname{\writestatus\m!systems{infinite tan -90}}

%D Usage: \type {\calculatesin{10}} and \type {\calculatedsin{10}}

\protect \endinput
