thrd-trg.mkii / last modification: 2020-01-30 14:15
%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

% compare: \number 0.5 \number -0.5 \number 1.5 \number -1.5
%
% so we need:

\def\realnumber#1{\withoutpt\the\dimexpr#1\points\relax} % brrr

\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
\!!dimena\!!stringb\!!dimena
\!!dimena\!!stringb\!!dimena
\!!dimena\!!stringb\!!dimena
\!!dimena\!!stringa\!!dimena
\divide\!!dimena \tr@coefd}

\def\tg@reduce#1#2%
{\!!dimena#1#2\@xc\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 \realnumber{#1}\endcsname\relax
\!!dimena#1\onepoint
\tg@@sin
\expandafter\xdef\csname sin \realnumber{#1}\endcsname{\withoutpt\the\!!dimena}%
\fi}}

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

\def\calculatetan#1%
{{\expandafter\ifx\csname tan \realnumber{#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 \realnumber{#1}\endcsname{\withoutpt\the\!!dimenb}%
\fi}}

%D The results are accessed with:

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

%D A more save implementation would be:

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

%D these):

\def\setcalculatedsin#1#2{\calculatesin{#2}\edef#1{\calculatedsin{#2}}}
\def\setcalculatedcos#1#2{\calculatecos{#2}\edef#1{\calculatedcos{#2}}}
\def\setcalculatedtan#1#2{\calculatetan{#2}\edef#1{\calculatedtan{#2}}}

%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 \realnumber{  0}\endcsname\!!zerocount
\expandafter\let\csname cos \realnumber{  0}\endcsname\!!plusone
\expandafter\let\csname sin \realnumber{ 90}\endcsname\!!plusone
\expandafter\let\csname cos \realnumber{ 90}\endcsname\!!zerocount
\expandafter\let\csname sin \realnumber{180}\endcsname\!!zerocount
\expandafter\let\csname cos \realnumber{180}\endcsname\!!minusone
\expandafter\let\csname sin \realnumber{270}\endcsname\!!minusone
\expandafter\let\csname cos \realnumber{270}\endcsname\!!zerocount

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

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

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

\protect \endinput