% TeXdraw toolbox macros, useful for extended TeXdraw commands

% $Id: txdtools.tex 1.11 2019/04/18 TeXdraw-v2r3 $

%   Copyright (C) 1991-2019  Peter Kabal

% This work is licensed under the Creative Commons Attribution (CC-BY)
% License, any version. To view the licenses, visit
% creativecommons.org/licenses/by or send a letter to
% Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.

%  Peter Kabal
%  Department of Electrical & Computer Engineering
%  McGill University

%  peter dot kabal at mcgill dot ca
%  http://www-mmsp.ece.mcgill.ca/MMSP/Documents/Software/

% ===============================================================

% These macros use temporary count registers defined by TeXdraw
%  \t@counta     \t@pixa
%  \t@countb     \t@pixb
%  \t@countc     \t@pixc
%                \t@pixd

\chardef\catamp=\the\catcode`\@
\catcode`\@=11


% ===== Real arithmetic
% Real addition
%  #1  - summand
%  #2  - summand
%  #3  - macro name to capture the real result
\def\realadd #1#2#3{\dimen0=#1pt
                    \dimen2=#2pt
                    \advance \dimen0 by \dimen2
                    \edef #3{\expandafter\c@lean\the\dimen0}}

% Real division
%  #1 - numerator
%  #2 - denominator (divisor)
%  #3 - macro name to capture the real result
\def\realdiv #1#2#3{\dimen0=#1pt
                    \t@counta=\dimen0
                    \dimen0=#2pt
                    \t@countb=\dimen0
                    \intdiv \t@counta \t@countb #3}

% ===== Integer arithmetic

% Length of the hypotenuse
% Find the length of a vector, lenhyp = sqrt(dx*dx + dy*dy)
%  #1 - integer value, dx
%  #2 - integer value, dy
%  #3 - count register to capture the integer value
\def\lenhyp #1#2#3{\t@counta=#1%
                   \multiply \t@counta by \t@counta
                   \t@countb=#2%
                   \multiply \t@countb by \t@countb
                   \advance \t@counta by \t@countb
                   \sqrtnum \t@counta #3}

% Square root of an integer
% Newton-Raphson iteration to find the square root, integer argument
% Let the current estimate of the square root of x be b(k).
% Form an error function, e(k)=b(k)*b(k)-x. Follow the gradient of the
% error to calculate the next guess,
%
%    e(k) - 0     d e(k)                          b(k) + x/b(k)
%   ----------  = ------  = 2*b(k)  ==>  b(k+1) = -------------
%   b(k)-b(k+1)   d b(k)                               2
%
% Note this iteration does not work for x=0, since the guess is then b(k)=0.
% Rename the count registers to have more suggestive names
\let\bk=\t@counta
\let\bn=\t@countb
\let\xval=\t@countc
\def\sqrtnum #1#2{\xval=#1%
                  \bk=\xval
                  \loop
                    \bn=\xval
                    \divide \bn by \bk
                    \advance \bn by \bk
                    \advance \bn by 1            % rounding
                    \divide \bn by 2
                  \ifnum \bn < \bk
                    \bk=\bn
                  \repeat
                  #2=\bn}

% ===== Coordinate macros

% Return the coordinates of the current position
%  #1 - macro name to capture the x-coordinate
%  #2 - macro name to capture the y-coordinate
\def\currentpos #1#2{\t@pixa=\x@pix
                     \advance \t@pixa by -\x@segoffpix
                     \pixtocoord \t@pixa #1
                     \t@pixa=\y@pix
                     \advance \t@pixa by -\y@segoffpix
                     \pixtocoord \t@pixa #2}

% Length of a vector
% Find the length of the vector between coordinate (#1 #2) and
% coordiante (#3 #4). The length is expressed relative to the
% current scaling.
%  (#1 #2) - vector start coordinates
%  (#3 #4) - vector end coordinates
%  #5 - macro name to receive the length
\def\vectlen (#1 #2)(#3 #4)#5{\getpos (#1 #2)\x@arga\y@arga
                              \getpos (#3 #4)\x@argb\y@argb
                              \coordtopix \x@arga \t@pixa
                              \coordtopix \x@argb \t@pixb
                              \advance \t@pixb by -\t@pixa
                              \coordtopix \y@arga \t@pixc
                              \coordtopix \y@argb \t@pixd
                              \advance \t@pixd by -\t@pixc
                              \lenhyp \t@pixb \t@pixd \t@pixc
                              \pixtocoord \t@pixc #5}

% Cossine and sine
% Find the cosine and sine of the angle of a vector directed from
% the coordinate (#1 #2) to the coordinate (#3 #4).
%  (#1 #2) - start coordinates
%  (#3 #4) - end coordinates
%  #5 - macro name to receive the cosine of the angle
%  #6 - macro name to receive the sine of the angle
\def\cossin (#1 #2)(#3 #4)#5#6{\getpos (#1 #2)\x@arga\y@arga
                               \getpos (#3 #4)\x@argb\y@argb
                               \coordtopix \x@arga \t@pixa
                               \coordtopix \x@argb \t@pixb
                               \advance \t@pixb by -\t@pixa
                               \coordtopix \y@arga \t@pixc
                               \coordtopix \y@argb \t@pixd
                               \advance \t@pixd by -\t@pixc
                               \lenhyp \t@pixb \t@pixd \t@pixc
                               \intdiv \t@pixb\t@pixc #5%
                               \intdiv \t@pixd\t@pixc #6}

\catcode`\@=\catamp
