summaryrefslogtreecommitdiff
path: root/graphics/texdraw/txdtools.tex
blob: eea68fbd0c8c539f72f07323523c9071d0e76b4b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
% 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