%PLAIN TEX OR AMSTEX

% THE TOP OF THIS FILE IS SPLINE.STY. 
% IT ENDS WITH THE LINE CONTAINING
%           END OF SPLINE.STY
%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% SPLINE.STY %%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                    Anders Thorup
%                 PSPICTURE (for DVIPS)
%
%Syntax:
%
%    \PSpicture<xdimen><ydimen><picture material>\endPSpicture
%
%

\chardef\atcode=\catcode`\@
\catcode`\@=11

\def\wl@g#1{\relax}
%FOR TESTS:
%\let\wl@g=\wlog

\def\PSpicture#1#2{\vbox to #2\bgroup\gdef\PSstr@ng{"}%
  \offinterlineskip
  \hrule height0pt width #1\relax\vfill\PSpictsetup}
\def\endPSpicture{\special{\PSstr@ng}\egroup}

%\PSpicture starts the "picture box", a \vbox of width xdimen and
%height ydimen. Most commands of the PICTURE MATERIAL will result in
%commands for the PostScript interpreter. These commands are appended
%to the \PSstr@ng.
%The \endPSpicture ships the \PSstr@ng with the \special
%command, and ends the box.

%Inside the picture box, coordinates and lengths are dimensionless.
%They are interpreted as multiples of \PSunit.
\newdimen\PSunit \PSunit=1bp

%The lower left vertex of the picture box has coordinates (0,0).
%To change the coordinates of the lower left vertex,
%give the command \llcoords{xcoord ycoord} as the very first
%command in PSPICTURE.
\def\llcoords#1{\begingroup\c@l=0 \st@ck#1 \end
  \ifnum\c@l=2 \else
      \errmessage{Two coordinates needed for \string\llcoords}\fi
   \dimen@x=\ll@x\dimen@y=\ll@y
   \global\ll@y=-\Acol \advance\c@l-1 \global\ll@x=-\Acol
   \advance\ll@x-\dimen@x \advance\ll@y-\dimen@y
   \PS{\The\ll@x\space\The\ll@y\space translate}\endgroup}

%Default line width for lines and curves drawn in PSPICTURE:
\newdimen\PSlinewidth \PSlinewidth=0.5pt

%The \PSlinewidth can be changed inside PSPICTURE. The change
%affects the following paths. Note that, contrary to the other
%commands inside PSpicture, the argument of \setPSlinewidth is a
%(usual) TeX dimension.
\def\setPSlinewidth#1{\PSlinewidth=#1 %
   \PS{\The\PSlinewidth\space\The\PSunit\space div setlinewidth}}

%The picture material to go inside the box could be direct commands
%to the PostScript interpreter, set with \PS. Example:
%          \PS{0 0 moveto 1.2 2.0 lineto stroke}
%will produce a line from (0,0) to (1.2,2.0).
\def\PS#1{\global\let\tmp=\PSstr@ng
   \global\edef\PSstr@ng{\tmp\space#1}}

%The picture setup macro allocates a couple of local registers,
%it sets the origin of the default coordinate system,
%and passes the global scale factor and the line width to PS
\def\PSpictsetup{\newlocregs \ll@x=0pt \ll@y=0pt %
  \count@=\PSunit\PS{\the\count@\space 65781.76 div dup scale}%
  \setPSlinewidth\PSlinewidth
  \defPSarrowh
  \setPSarrowheadlength{10\PSlinewidth}}

%The picture material also includes (horizontal) TeX material to be
%set in an \hbox OF WIDTH 0 at specified coordinates with the command
%\TX. The box is centered vertically. Example:
%         \TX{$A$\hss}{0 1}
%will produce a math A at the point with coordinates (0,1).
%The trailing \hss will set the A right to the point.
\def\TX#1#2{\begingroup\c@l=0 \st@ck#2 \end
  \ifnum\c@l=2 \else
     \errmessage{Two coordinates needed for \string\TX}\fi
  \advance\ll@y\Acol \advance\c@l-1 \advance\ll@x\Acol
  \ll@y=\The\ll@y\PSunit \ll@x=\The\ll@x\PSunit
  \vbox to 0pt{\kern-\ll@y\vss
       \hbox to 0pt{\kern\ll@x#1\kern-\ll@x}
       \vss\kern\ll@y}\endgroup}


\def\LTX#1{\TX{\hss#1}}
\def\CTX#1{\TX{\hss#1\hss}}
\def\RTX#1{\TX{#1\hss}}

%\rotateRTX is like \RTX with an extra rotation parameter determining the
%the amount of rotation. Thus
%   \rotateRTX{30}{text}{0 1}
%   will set the hbox containing the word text with its lower left
%   corner at (0,1), and rotate it 30 deg around the point.
%   
%   \rotateRTX{0}{tag}{0 1} is esentially equivalent to
%   \RTX{tag}{0 1}
%   except that the latter sets the hbox with tag centered vertically.
\def\rotateRTX#1#2#3{\begingroup\c@l=0 \st@ck#3 \end
  \ifnum\c@l=2 \else
     \errmessage{Two coordinates needed for \string\TX}\fi
  \advance\ll@y\Acol \advance\c@l-1 \advance\ll@x\Acol
  \ll@y=\The\ll@y\PSunit \ll@x=\The\ll@x\PSunit
  \vbox to 0pt{\kern-\ll@y\vss
       \hbox to 0pt{\kern\ll@x
    \special{ps: gsave currentpoint currentpoint translate #1
    rotate neg exch neg exch translate}#2\special{ps: grestore}%
    \hss\kern-\ll@x}\kern\ll@y}\endgroup}

%The following construct:
%         \TX\markbox{1 2}
%will produce a small black box centered at the point (1,2).
\def\markbox{\hss\vrule height 3\PSlinewidth
      width 3\PSlinewidth \hss}

%The main purpose of this macro package is to define the macros
%\spline, \cspline, \dspline. The command inside PSpicture:
%    \spline{1 1.2 4 5.5 6.7 4.5 2.2 1}
%will produce a natural (third degree) spline through the points
%         (1 , 1.2) (4 , 5.5) (6.7 , 4.5) (2.2 , 1).
%and \cspline (with the same arguments) will produce a closed spline.
%The number of points has to be at least 3 (and the number of space
%separated coordinates has to be even and at least equal to 6).
%The best result for the natural spline is obtained when the points
%are evenly distributed along the curve.
%
%The spline is broken into Bezier curves drawn by PostScript.
%To do so, we let TeX compute the coordinates of the control points,
%using the algorithms described in the text following "endinput" below.
%
%Input to the algorithm is n points A1,...,An
%where each point is a pair of coordinates Ai=Bi,Ci. They are stored
%in 2n registers Aj; the odd Aj's are the Bi and the even Aj's are the
%Ci.
%
%Output is the set of n control points Zi=Xi,Yi. They are stored in
%2n registers Zj; the odd Zj's are the Xi and the even are the Yi.
%
%TeX is bad at arithmetics. In the code, each factor fi is between
%2-\sqrt3 and 1. We store fi in an integer register as Fi=fi*base,
%where base=2^15, approx the square root of maxint.

\newcount\base \base=32768
%Set instead \base=10000 for test, or for (old versions of) PCTeX!!
%A TeX count register should be able to hold a number less than the
%number 2^{31}, and in particular \base*\base. This is not the case
%for the TeX version produced by PCTeX, so for use with PCTeX you
%have to decrease the \base, resulting in loss of accuracy.

%The multiplication by a factor, Z:=Z*f in the algorithm, is
%interpreted as Z:=Z*F/B, implemented as follows:
%Split Z=Zh*B+Zl. Then Z*F/B=Zh*F+Zl*F/B, that is:
%  Zh:=Z/B, Zl:=Z-Zh*B, Z:=Zh*F+Zl*F/B
\def\m@ltf#1#2{\dimen@y=#1\divide\dimen@y\base
  \dimen@x=-\dimen@y \multiply\dimen@x\base\advance\dimen@x#1%
  \multiply\dimen@y#2\multiply\dimen@x#2\divide\dimen@x\base
  \advance\dimen@y\dimen@x#1=\dimen@y}

%The inversion f:=(m-f)^{-1} (where m is 2 or 4) is interpreted
%as F=B^2/(m*B-F)*B, implemented as follows:
\def\inv@rt#1#2{\count@@=#1\multiply\count@@\base
  \advance\count@@-#2#2=\base \multiply#2\base \divide#2\count@@}

%We want to allocate (locally) registers:
\def\newlocdimen#1{\advance\count11 by \@ne
  \ifnum\count11 <\insc@unt
     \else\errmessage{No room for the spline}\fi
  \dimendef#1=\count11 }
\def\newloccount#1{\advance\count10 by \@ne
  \ifnum\count10 <\insc@unt
     \else\errmessage{No room for the splines}\fi
  \countdef#1=\count10 }
\def\newdimenvar#1{\newlocdimen\currvar
   \expandafter\let\csname#1\the\c@l\endcsname=\currvar
   \wl@g{\expandafter\string\csname#1\the\c@l\endcsname
      =\string\dimen\the\count11 }}
\def\newcountvar#1{\newloccount\currvar
   \expandafter\let\csname#1\the\c@l\endcsname=\currvar
  \wl@g{\expandafter\string\csname#1\the\c@l\endcsname
   =\string\count\the\count10 }}

\def\newlocregs{\newloccount\c@l\newloccount\numc@ls
  \newloccount\prevF\newloccount\prevQ
  \newloccount\count@\newloccount\count@@
  \newlocdimen\dimen@\newlocdimen\dimen@x\newlocdimen\dimen@y
  \newlocdimen\ll@x\newlocdimen\ll@y}

\def\Acol{\csname A\the\c@l\endcsname} %If \c@l=3, then \Acol=\A3
\def\Fcol{\csname F\the\c@l\endcsname}
\def\Qcol{\csname Q\the\c@l\endcsname}
\def\Zcol{\csname Z\the\c@l\endcsname}

%Def of the three spline macros.  Structure
% def SPLINE#1
%             maybemarks         %Make \st@ck put marks at points if wanted
%            \c@l=0              %\c@l is number of arguments read so far
%            \st@ck #1           %Read arguments, set their number,
%                                %put them in dimen-registers Ai,
%                                %and (maybe) set marks on the points. 
%             checkarguments     %Even number and at least ....
%             Gauss              %Solve the equations: determine Z_i
%             PSwSPL@NE          %Write the Bezier cubics in special PS
%             PSwCfinish         %Finish with an extra cubic for \cspline
%             stroke             %stroke the spline
 
\def\spline@N#1{\begingroup
  \maybem@rks
  \c@l=0 \st@ck#1 \end
  \ch@ckeven\ch@ckthree
  \gauss@N
  \PSwSPL@NE \stroke
  \endgroup}
\def\spline@C#1{\begingroup
  \maybem@rks
  \c@l=0 \st@ck#1 \end
  \ch@ckeven\ch@ckthree
  \gauss@C   
  \PSwSPL@NE \PSw@Cfinish \stroke
  \endgroup}
\def\spline@D#1{\begingroup
  \maybem@rks
  \c@l=-2 \st@ck#1 \end
  \advance\numc@ls2 \ch@ckeven\ch@ckfour 
  \advance\numc@ls-4
         \ifnum\numc@ls>4 \let\next\gauss@D
                     \else\let\next\d@BEZIER\fi \next
  \PSwSPL@NE \stroke
  \endgroup}

%The coordinates are read and put into the dimen registers \Acol
%by 
%          \st@ck ... \end. 
%Each coordinate is a real in decimal
%notation, and they are separated by one or more spaces.
%The number of coordinates read is stored in \numc@ls
{\def\\{\global\let\sptoken= }\\ } %now \sptoken is a space token
\def\st@ck{\futurelet\nexttok\testst@ck}
\def\testst@ck{\ifx\nexttok\sptoken
   \let\next\eatspacest@ck
   \else\ifx\nexttok\end\let\next\stackfinish
   \else\def\next{\expandafter\st@ckit}\fi\fi\next}%If arg=\cs
\def\eatspacest@ck#1 {\st@ck}
\def\stackfinish#1{\numc@ls=\c@l}
\def\st@ckit#1 {\advance\c@l1 \newdimenvar A\Acol=#1pt %
  \markoptions\st@ck}

%The three spline algorithms are implemented in Gauss:
\def\gauss@N{\fwd@Ninit
      \loop\fwd@Nbody\ifnum\c@l<\numc@ls\repeat
      \fwd@Nfinish\solve@N}
\def\gauss@C{\fwd@Cinit
      \loop\fwd@Cbody\ifnum\c@l<\numc@ls\repeat
      \fwd@Cfinish\solve@C}
\def\gauss@D{\fwd@Dinit
      \loop\fwd@Nbody\ifnum\c@l<\numc@ls\repeat
      \fwd@Dfinish\solve@D}
\def\d@BEZIER{%Special case with only two points for a \dspline
  %Z1:=2A1-A{-1}, Z2:=2A2-A0 (Z_1)
  \c@l=1 \newdimenvar Z\currvar=2\Acol
    \advance\c@l-2 \advance\currvar -\Acol
  \c@l=2 \newdimenvar Z\currvar=2\Acol
    \advance\c@l-2 \advance\currvar -\Acol
  \fwd@Dfinish}

%The Bezier cubics are written to PostScript by \PSwSPL@NE:
\def\PSwSPL@NE{\PSw@init
  \loop\PSw@ZWA\ifnum\c@l<\numc@ls\repeat}
%Extra cubic for the closed spline
\def\PSw@Cfinish{\PSw@\Zcol
  \c@l=0 \PSw@Wcol\PSw@\Acol\PS{curveto}}


%\def\spline{\begingroup\spl@ne}
%\def\cspline{\begingroup\let\d@spline=\d@cspline
%   \let\PSw@finish=\PSw@Cfinish\spl@ne}
%\def\dspline{\begingroup\dspl@ne}
%\def\spl@ne#1{\maybem@rks\c@l=0 \st@ck#1 \end
%   \ch@ckeven\ch@ckthree
%   \d@spline\d@PSw\PSw@finish\stroke\endgroup}
%%\def\dspl@ne#1{\maybem@rks\c@l=0 \dst@ck#1 \end
%%AT\def\dspl@ne#1{\maybem@rks\c@l=0 \st@ck#1 \end
%\def\dspl@ne#1{\maybem@rks\c@l=-2 \st@ck#1 \end
%%AT   \ch@ckeven\ch@ckfour\advance\numc@ls-2 %
%   \ch@ckeven\ch@ckthree\advance\numc@ls-2 %
%%AT   \ifnum\numc@ls>6 %
%   \ifnum\numc@ls>4 %
%     \let\next\d@dspline 
%   \else
%     \let\next\d@dspecial
%   \fi\next\let\PSw@init=\PSw@dinit\d@PSw\PSw@finish\stroke\endgroup}

% We need special stack handling that doesn't
% put marks at control points for a directed spline
% NO, we will also mark the control points for a directed spline.
% So following code not needed.
%\def\dst@ck{\futurelet\nexttok\testdst@ck}
%\def\testdst@ck{\ifx\nexttok\sptoken
%   \let\next\eatspacedst@ck
%   \else\ifx\nexttok\end\let\next\dstackfinish
%   \else\def\next{\expandafter\dst@ckit}\fi\fi\next}
%\def\eatspacedst@ck#1 {\dst@ck}
%\def\dstackfinish#1{\numc@ls=\c@l}
%\def\dst@ckit#1 {\ifnum\c@l>3 \markoptions\fi %
% \advance\c@l1 \newdimenvar A\Acol=#1pt \dst@ck}


%Check arguments:
\def\ch@ckfour{\ifnum\numc@ls<8 %
      \errmessage{At least four points needed for directed spline}\fi}
\def\ch@ckthree{\ifnum\numc@ls<6 %
      \errmessage{At least three points needed for SPLINE}\fi}
\def\ch@cktwo{\ifnum\numc@ls<4 %
      \errmessage{At least two points needed}\fi}
\def\ch@ckeven{\ifodd\numc@ls
       \errmessage{Even number of coordinates needed}\fi}

%\def\d@spline{\fwd@Ninit\loop\fwd@Nbody\ifnum\c@l<\numc@ls\repeat
%  \fwd@Nfinish\solve@N}
%\def\d@cspline{\fwd@Cinit\loop\fwd@Cbody\ifnum\c@l<\numc@ls\repeat
%  \fwd@Cfinish\solve@C}
%\def\d@dspline{\fwd@Dinit%
%  \loop\fwd@Nbody\ifnum\c@l<\numc@ls\repeat\fwd@Dfinish\solve@D}
%\def\d@dspecial{%Special case with only two points for a \dspline
%  %Z3:=2A3-A1, Z4:=2A4-A2 (Z_1)
%%AT  \c@l=3 \newdimenvar Z\currvar=2\Acol
%  \c@l=1 \newdimenvar Z\currvar=2\Acol
%    \advance\c@l-2 \advance\currvar -\Acol
%%AT  \c@l=4 \newdimenvar Z\currvar=2\Acol
%  \c@l=2 \newdimenvar Z\currvar=2\Acol
%    \advance\c@l-2 \advance\currvar -\Acol
%  \fwd@Dfinish}
%


%After having read the arguments, \numc@ls=\c@l is equal to 2n.
%The linear equations are solved by Gauss elimination in Gauss,
%using the algorithms described in the manual. . 
%Macros for the individual parts of the algorithm:
%
%Initialization of the forward loops:
\def\fwd@Ninit{%        %set F2=\prevF:=base/2, Z1:=A1+2*A3, Z2:=A2+2*A4
  \c@l=1 \newdimenvar Z\currvar=\Acol
    \advance\c@l2 \advance\currvar 2\Acol
  \c@l=2 \prevF=\base \divide\prevF2 \newcountvar F\Fcol=\prevF
    \newdimenvar Z\currvar=\Acol
    \advance\c@l2 \advance\currvar 2\Acol
  \c@l=4 }
\def\fwd@Cinit{%       %Q1=\prevQ:=base, F2=\prevF:=base/4,
                   %Z1:=4A1+2A3, Z2:=4A2+2A4
                   %lastF=4*base, lastX=4A{2n-1}+2A1, lastY=4A{2n}+2A2
  \c@l=\numc@ls
   \newcountvar F\let\lastF=\currvar \lastF\base \multiply\lastF4 %
   \newdimenvar Z\let\lastY=\currvar \lastY=4\Acol
  \advance\c@l-1 \newdimenvar Z\let\lastX=\currvar\lastX=4\Acol
  \c@l=1 \advance\lastX 2\Acol
   \prevQ=\base\newcountvar Q\Qcol=\prevQ
   \newdimenvar Z\Zcol=4\Acol\advance\c@l2 \advance\currvar 2\Acol
  \c@l=2 \advance\lastY 2\Acol
   \prevF=\base \divide\prevF4 \newcountvar F\Fcol=\prevF
   \newdimenvar Z\Zcol=4\Acol\advance\c@l2 \advance\currvar 2\Acol
  \c@l=4 }
\def\fwd@Dinit{%       %set F6=\prevF:=base/4
                       %    Z3:=2A3-A1, Z4:=2A4-A2 (Z_1)
                       %    Z5:=4A5+2A7-Z3, Z6:=4A6+2A8-Z4 (Z_2)
%AT  \c@l=3 \newdimenvar Z\currvar=2\Acol
  \c@l=1 \newdimenvar Z\currvar=2\Acol
    \advance\c@l-2 \advance\currvar -\Acol
%AT  \c@l=4 \newdimenvar Z\currvar=2\Acol
  \c@l=2 \newdimenvar Z\currvar=2\Acol
    \advance\c@l-2 \advance\currvar -\Acol
%AT  \c@l=5 \newdimenvar Z\currvar=4\Acol
  \c@l=3 \newdimenvar Z\currvar=4\Acol
    \advance\c@l2 \advance\currvar 2\Acol
    \advance\c@l-4 \advance\currvar -\Zcol
%AT  \c@l=6 \prevF=\base \divide\prevF4 \newcountvar F\Fcol=\prevF
  \c@l=4 \prevF=\base \divide\prevF4 \newcountvar F\Fcol=\prevF
    \newdimenvar Z\currvar=4\Acol
    \advance\c@l2 \advance\currvar 2\Acol
    \advance\c@l-4 \advance\currvar -\Zcol
%AT  \c@l=8 }
  \c@l=6 }

%The bodies of the forward loops (same bodies of spline@N and spline@D):
\def\fwd@Nbody{%      %Zi=:-Z{i-2}*\prevF+4Ai+2A{i+2}. If i is even,
                    %Fi=\prevF:=(4-\prevF)^{-1}
                    %At entrance, \c@l=i+1, at exit \c@l=i+2
  \advance\c@l-1 \newdimenvar Z%
  \advance\c@l-2 \currvar=-\Zcol \m@ltf\currvar\prevF
  \advance\c@l2 \advance\currvar 4\Acol
  \advance\c@l2 \advance\currvar 2\Acol
  \advance\c@l-2 \ifodd\c@l\else
     \inv@rt4\prevF\newcountvar F\Fcol=\prevF\fi
  \advance\c@l2 }
\def\fwd@Cbody{%     %Zi=:-Z{i-2}*\prevF+4Ai+2A{i+2}. If i is even,
                    %\tmpQ=\prevQ
                    %Q{i-1}=\prevQ:=-\prevQ*\prevF
                    %\lastF:=\lastF+\prevQ*\tmpQ
                    %\lastX:=\lastX+\prevQ*Z{i-1}
                    %\lastY:=\lastY+\prevQ*Zi
                    %\prevQ:=\newQ
                    %Fi=\prevF:=(4-\prevF)^{-1}
  \advance\c@l-1 \newdimenvar Z%
  \advance\c@l-2\currvar=-\Zcol \m@ltf\currvar\prevF
  \advance\c@l2 \advance\currvar 4\Acol
  \advance\c@l2 \advance\currvar 2\Acol
  \advance\c@l-2 \ifodd\c@l\else
     \count@=\prevQ
     \prevQ=-\prevQ \multiply\prevQ\prevF \divide\prevQ\base
     \multiply\count@\prevQ \divide\count@\base
     \advance\lastF\count@
     \advance\c@l-2 \dimen@=\Zcol \m@ltf\dimen@\prevQ
       \advance\lastY\dimen@
     \advance\c@l-1 \dimen@=\Zcol \m@ltf\dimen@\prevQ
       \advance\lastX\dimen@
     \advance\c@l2 \newcountvar Q\Qcol=\prevQ
     \advance\c@l1 \inv@rt4\prevF\newcountvar F\Fcol=\prevF\fi
  \advance\c@l2 }
%\fwd@Dbody = \fwd@Nbody

%Finishing the forward loops:
\def\fwd@Nfinish{%     %Z{2n-1}:=3A{2n-1}-Z{2n-3}*\prevF
                     %Z{2n}:=3A{2n}-Z{2n-2}*\prevF
                     %F{2n}=\prevF:=(2-\prevF)^{-1}
  \c@l=\numc@ls
  \advance\c@l-1 \newdimenvar Z%
  \advance\c@l-2 \currvar=-\Zcol\m@ltf\currvar\prevF
  \advance\c@l2 \advance\currvar 3\Acol
  \advance\c@l1 \newdimenvar Z%
  \advance\c@l-2 \currvar=-\Zcol\m@ltf\currvar\prevF
  \advance\c@l2 \advance\currvar 3\Acol
  \inv@rt2\prevF \newcountvar F\Fcol=\prevF}
\def\fwd@Cfinish{%    %\prevQ:=1+\prevQ
                     %tmpQ=-\prevQ*\prevF
                     %\lastX:=\lastX+tmpQ*Z{2n-3}
                     %\lastY:=\lastY+tmpQ*Z{2n-2}
                     %\lastF:=\lastF+tmpQ*\prevQ
                     %\lastF:=1/\lastF
  \c@l=\numc@ls \advance\prevQ\base
    \count@=-\prevQ \multiply\count@\prevF\divide\count@\base
  \advance\c@l-2 \dimen@=\Zcol
    \m@ltf\dimen@\count@\advance\lastY\dimen@
  \advance\c@l-1 \dimen@=\Zcol
    \m@ltf\dimen@\count@\advance\lastX\dimen@
    \multiply\count@\prevQ \divide\count@\base\advance\lastF\count@
  \prevF=\base \multiply\prevF\base \divide\prevF\lastF \lastF=\prevF
  \c@l=\numc@ls}
\def\fwd@Dfinish{%   %Z{2n-1}:=A{2n+1}, Z{2n}:=A{2n+2}
  \c@l=\numc@ls
  \advance\c@l-1 \newdimenvar Z%
  \advance\c@l2 \currvar=\Acol
  \advance\c@l-1 \newdimenvar Z%
  \advance\c@l2 \currvar=\Acol}

%Now the backwards substitutions to solve the equations:
\def\solve@N{\c@l=\numc@ls \m@ltf\Zcol\prevF
  \advance\c@l-1 \m@ltf\Zcol\prevF
  \loop\advance\c@l-1 %
    \ifodd\c@l \else \prevF=\Fcol\fi
    \advance\c@l2 \dimen@=-\Zcol
    \advance\c@l-2 \advance\Zcol\dimen@\m@ltf\Zcol\prevF
    \ifnum\c@l>1 \repeat}
\def\solve@C{\c@l=\numc@ls \m@ltf\Zcol\prevF
  \advance\c@l-1 \m@ltf\Zcol\prevF
  \loop\advance\c@l-1 %
    \ifodd\c@l \dimen@=-\lastX
         \else \dimen@=-\lastY \prevF=\Fcol
               \advance\c@l-1 \prevQ=\Qcol\advance\c@l1 \fi
    \m@ltf\dimen@\prevQ
    \advance\c@l2 \advance\dimen@-\Zcol
    \advance\c@l-2 \advance\dimen@\Zcol \m@ltf\dimen@\prevF
    \Zcol=\dimen@ \ifnum\c@l>1\repeat}
\def\solve@D{\c@l=\numc@ls \advance\c@l-1
  \loop\advance\c@l-1 %
    \ifodd\c@l \else \prevF=\Fcol\fi
    \advance\c@l2 \dimen@=-\Zcol
    \advance\c@l-2 \advance\Zcol\dimen@\m@ltf\Zcol\prevF
%AT    \ifnum\c@l>5 \repeat}
    \ifnum\c@l>3 \repeat}


%Next we come to the PostScript writing:
%Dirty tricks, the TeX book page 375:
{\catcode`p=12 \catcode`t=12 \gdef\STRIPPT#1pt{#1}}
\def\The#1{\expandafter\STRIPPT\the#1}

%The start of the writing is identical for both splines:
\def\PSw@#1{\advance\c@l-1 \PS{\The#1}\advance\c@l1 \PS{\The#1}}
\def\PSw@Wcol{\advance\c@l1 \dimen@x=2\Acol\advance\dimen@x-\Zcol
  \advance\c@l1 \dimen@y=2\Acol\advance\dimen@y-\Zcol
  \PS{\The\dimen@x\space\The\dimen@y}}
\def\PSw@init{\c@l=2 \newpath\PSw@\Acol\moveto}
%AT\def\PSw@dinit{\c@l=4 \newpath\PSw@\Acol\moveto}
%\def\PSw@dinit{\c@l=2 \newpath\PSw@\Acol\moveto}
\def\PSw@ZWA{%write: Zi   Wi=2A{i+1}-Z{i+1}   A{i+1}   curveto
             %at entrance, \c@l=2i, at exit \c@l=\c@l+2
  \PSw@\Zcol\PSw@Wcol\PSw@\Acol\PS{curveto}}
%The finish is different:
%\def\PSw@finish{\relax}
%\def\PSw@Cfinish{\PSw@\Zcol
%  \c@l=0 \PSw@Wcol\PSw@\Acol\PS{curveto}}
%\def\d@PSw{\PSw@init
%  \loop\PSw@ZWA\ifnum\c@l<\numc@ls\repeat}

\def\normalpaths{\def\stroke{\PS{stroke}}%
  \def\moveto{\PS{moveto}}\def\newpath{\PS{newpath}}}
%The default is normal paths:
\normalpaths


\def\PSline{\begingroup\PSl@ne}
\def\PSl@ne#1{\maybem@rks\c@l=0 \st@ck#1 \end
  \ch@ckeven\ch@cktwo
  \c@l=2 \newpath\PSw@\Acol\moveto
  \loop\advance\c@l2 \PSw@\Acol\PS{lineto}%
  \ifnum\c@l<\numc@ls\repeat\PSl@nefinish\stroke\endgroup}
\let\PSl@nefinish=\relax
\def\PScline{\begingroup\def\PSl@nefinish{\PS{closepath}}\PSl@ne}

\def\PSarc{\begingroup\PS@rc}
\def\PSarcn{\begingroup\let\PS@arcfinish=\PS@arcnfinish\PS@rc}
\def\PS@rc#1#2{\c@l=0 \st@ck#2 #1 \end
  \ifnum\c@l=5 \else
     \errmessage{Wrong number of arguments for circles/arcs}\fi
  \newpath\c@l=0 \loop
       \advance\c@l1 \PS{\The\Acol}\ifnum\c@l<5 \repeat
  \PS@arcfinish\stroke\endgroup}
\def\PS@arcfinish{\PS{arc}}
\def\PS@arcnfinish{\PS{arcn}}
\def\PScircle{\PSarc{0 360}}

%Various marks:
\let\markoptions=\relax
\def\putTeXmarks{\def\maybem@rks{\let\markoptions=\TeXm@rks}}
\def\putPSmarks{\def\maybem@rks{\let\markoptions=\PSm@rks}}
\def\nomarks{\let\maybem@rks=\relax}
 %make nomarks the global default
\nomarks
\def\TeXm@rks{\ifodd\c@l\else
  \begingroup \advance\ll@y\Acol \advance\c@l-1 \advance\ll@x\Acol
  \ll@y=\The\ll@y\PSunit \ll@x=\The\ll@x\PSunit
  \vbox to 0pt{\kern-\ll@y\vss
       \hbox to 0pt{\kern\ll@x\markbox\kern-\ll@x}
       \vss\kern\ll@y}\endgroup\fi}
\newdimen\PSmarkradius \PSmarkradius=2\PSlinewidth
%Old version had: \let\PSmarkradius=\PSlinewidth
\def\PSm@rks{\ifodd\c@l\else\PS{newpath}\PSw@\Acol
   \PS{\The\PSmarkradius\space\The\PSunit\space div
         0 360 arc fill stroke}\fi}
\def\TeXmark{\begingroup\let\markoptions=\TeXm@rks\m@rk}
\def\PSmark{\begingroup\let\markoptions=\PSm@rks\m@rk}
\def\m@rk#1{\c@l=0 \st@ck#1 \end\ch@ckeven\endgroup}

\def\setdash#1{\dimen@=#1\relax
  \PS{[\The\dimen@\space\The\PSunit\space div] 0 setdash}}
\def\nodashes{\PS{[] 0 setdash}}

\def\longpath#1{\c@l=0 \st@ck#1 \end
  \ifnum\c@l=2 \else
     \errmessage{Wrong number of arguments for \string\longpath}\fi
  \PSw@\Acol\PS{moveto}%
  \let\newpath\relax\let\stroke\relax\def\moveto{\PS{lineto}}}
\def\shortpaths{\def\moveto{\PS{moveto}}}
\def\subpaths{\PS{newpath}\let\newpath\relax
   \let\stroke\relax\def\moveto{\PS{moveto}}}

%arrows:
\def\defPSarrowh{\PS{/arrowh {
 /curmtx matrix currentmatrix def
 currentpoint translate
 arrlen dup scale
 rotate
 -1  0
 -2.5  0.5
 -3  1
 curveto
 -2.5  0.5
 -2.5  -0.5
 -3  -1
 curveto
 -2.5  -0.5
 -1  0
 0 0
 curveto closepath fill
 curmtx setmatrix} def}}
\def\setPSarrowheadlength#1{\dimen@=#1\relax
  \PS{/arrlen \The\dimen@\space\The\PSunit\space div 3 div def}}

\def\PSarrow#1{\begingroup
  \c@l=0 \st@ck#1 \end
  \ifnum\c@l=4 \else
  \errmessage{Two points needed for \string\PSarrow}\fi
  \PS{newpath}\c@l=2 \PSw@\Acol\PS{moveto}\c@l=4 \PSw@\Acol
  \PS{lineto}\stroke\PS{newpath}\PSw@\Acol\PS{moveto}
  \dimen@y=\Acol\advance\c@l-1 \dimen@x=\Acol
  \advance\c@l-1 \advance\dimen@y-\Acol
  \advance\c@l-1 \advance\dimen@x-\Acol
  \ifdim\dimen@x=0pt\ifdim\dimen@y=0pt
      \errmessage{equal endpoints of \string\PSarrow}\fi\fi
  \PS{\The\dimen@y\space\The\dimen@x\space atan arrowh}\endgroup}

\let\spline=\spline@N
\let\cspline=\spline@C
\let\dspline=\spline@D
\catcode`\@=\atcode


%\endinput % END OF SPLINE.STY
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% PENTOMINOS:

%Controlsequence to define the twelve pentomino cs's (and six mirrors).
%
% A pentomino cs takes two parameters: 
%              #1 = angle of rotation
%              #2 = position of base point (two coordinates)
% (base point = leftmost point of lower boundary). 

\def\pdef#1#2{\def#1##1 ##2{\PS{
  gsave ##2 moveto currentpoint currentpoint translate ##1 rotate
  #2 lineto  closepath stroke
  neg exch neg exch translate grestore}}}

%The following defs redefine \P and \S and maybe others, so 
%better make them local, that is, give the command \pentominos
%inside the PSpicture environment.

\def\pentominos{
\def\\{ lineto }
\pdef\F{1 0\\1 2\\2 2\\2 3\\0 3\\0 2\\-1 2\\-1 1\\0 1}
\pdef\FL{1 0\\1 1\\2 1\\2 2\\1 2\\1 3\\-1 3\\-1 2\\0 2}
\pdef\T{0 2\\-1 2\\-1 3\\2 3\\2 2\\1 2\\1 0}
\pdef\W{2 0\\2 1\\3 1\\3 3\\2 3\\2 2\\1 2\\1 1\\0 1}
\pdef\V{3 0\\3 1\\1 1\\1 3\\0 3}
\pdef\X{1 0\\1 1\\2 1\\2 2\\1 2\\1 3\\0 3\\0 2\\-1 2\\-1 1\\0 1}
\pdef\YL{1 0\\1 4\\0 4\\0 3\\-1 3\\-1 2\\0 2}
\pdef\YR{1 0\\1 2\\2 2\\2 3\\1 3\\1 4\\0 4}
\pdef\I{1 0\\1 5\\0 5}
\pdef\P{1 0\\1 1\\2 1\\2 3\\0 3}
\pdef\Q{1 0\\1 3\\-1 3\\-1 1\\0 1}
\pdef\S{2 0\\2 2\\3 2\\3 3\\1 3\\1 1\\0 1}
\pdef\Z{2 0\\2 1\\1 1\\1 3\\-1 3\\-1 2\\0 2}
\pdef\U{3 0\\3 2\\2 2\\2 1\\1 1\\1 2\\0 2}
\pdef\L{2 0\\2 1\\1 1\\1 4\\0 4}
\pdef\J{2 0\\2 4\\1 4\\1 1\\0 1}
\pdef\N{1 0\\1 2\\2 2\\2 4\\1 4\\1 3\\0 3}
\pdef\NL{1 0\\1 3\\0 3\\0 4\\-1 4\\-1 2\\0 2}
}

\def\vplace#1#2#3#4#5#6#7#8{
\CTX{#1}{0 1}
\CTX{#2}{0 2}
\CTX{#3}{0 3}
\CTX{#4}{0 4}
\CTX{#5}{0 5}
\CTX{#6}{0 6}
\CTX{#7}{0 7}
\CTX{#8}{0 8}
}

\def\hplace#1#2#3#4#5#6#7#8{
\CTX{\strut#1}{1 0}
\CTX{\strut#2}{2 0}
\CTX{\strut#3}{3 0}
\CTX{\strut#4}{4 0}
\CTX{\strut#5}{5 0}
\CTX{\strut#6}{6 0}
\CTX{\strut#7}{7 0}
\CTX{\strut#8}{8 0}
}






\def\thetitle{\centerline{\bf PENTOMINO BATTLE FOR SOPHIE}
\vskip1truecm
\noindent\hbox to 14\PSunit{\bf The pentominos:\hss}
\rlap{\bf The aim of the battle:}
\bigskip}


\def\thenames{\PSpicture{12\PSunit}{5\PSunit}
\pentominos
\CTX{`V'}{5.5 0.5}                     \V90 {6 0}
\CTX{`S'}{9.5 2.5}		       \Z0 {9 1}     
\CTX{Pistol}{11 2.5}		       \YR180 {12 5}
\CTX{Zigzag}{7 3.5}		       \W-90 {6 5}
\CTX{`T'}{6.5 1.5}	               \T90 {9 1}
\CTX{Charles}{4 2.6}\CTX{XII}{4.5 2.2} \F0 {4 1}
\CTX{Flash}{4 4.5}	               \NL90 {6 4}
\CTX{`L'}{10 4.5}	               \J90 {11 3}
\CTX{Stick}{9.5 0.5}	               \I-90 {7 1}
\CTX{Lump}{1.3 4.5}	               \Q90 {3 4}
\CTX{Cross}{2.5 1.5}	               \X0 {2 0}
\CTX{`U'}{0.5 1.5}                     \U-90 {0 3}
\endPSpicture
}

\def\theaim{\vbox{\hsize 4.8truecm\parindent=0pt
 Find the four empty positions on your opponent's board.  Four shots
in each round. For your shots in the third round, place the number 3
at the four positions of the shots, and the number 3 in your four
hits.  Draw (parts of) your opponent's configuration when determined
by your shots. 
 }}

\def\twoboards{\noindent \hskip1\PSunit\rlap{\bf Your configuration:}
\hskip10\PSunit{\bf Your shots:}
\bigskip
\PSpicture{20\PSunit}{8\PSunit}
\llcoords{-0.5 0.5}\vplace12345678
\llcoords{-10 0.5}\vplace12345678
\llcoords{-19.5 0.5}\vplace12345678
\llcoords{-0.5 0.5}\hplace abcdefgh
\llcoords{-10.5 0.5}\hplace abcdefgh
%
\llcoords{-1 0}
\subpaths\shortpaths
\PScline{0 1 8 1 8 2 0 2}
\PScline{0 3 8 3 8 4 0 4}
\PScline{0 5 8 5 8 6 0 6}
\PScline{0 7 8 7 8 8 0 8}
\PScline{0 0 1 0 1 8 0 8}
\PScline{2 0 3 0 3 8 2 8}
\PScline{4 0 5 0 5 8 4 8}
\PScline{6 0 7 0 7 8 6 8}
\PS{gsave 0.95 setgray eofill grestore}
\normalpaths
\PScline{0 0 8 0 8 8 0 8}
\pentominos
\pentconf
%
%
%
\llcoords{-11 0}\subpaths
\shortpaths
\PScline{0 1 8 1 8 2 0 2}
\PScline{0 3 8 3 8 4 0 4}
\PScline{0 5 8 5 8 6 0 6}
\PScline{0 7 8 7 8 8 0 8}
\PScline{0 0 1 0 1 8 0 8}
\PScline{2 0 3 0 3 8 2 8}
\PScline{4 0 5 0 5 8 4 8}
\PScline{6 0 7 0 7 8 6 8}
\PS{gsave 0.95 setgray eofill grestore}
\normalpaths
\PScline{0 0 8 0 8 8 0 8}
\endPSpicture
}



\def\thehits{\noindent {\bf Your hits:}
\bigskip
\PSpicture{20\PSunit}{3\PSunit}
\pentominos
\V0 {0 0}
\S90 {4 0}
\YR-90 {2 3}
\W0 {4 0}
\T180 {8 3}
\F90 {11 1}
\N-90 {9 3}
\L90 {14 0}
\I-90 {12 3}
\P90 {17 0}
\X0 {17 0}
\U90 {20 0}
\llcoords{0 1.5}\PScline{0 0 1 0 1 1 0 1}
\llcoords{-2 1.5}\PScline{0 0 1 0 1 1 0 1}
\llcoords{-4 1.5}\PScline{0 0 1 0 1 1 0 1}
\llcoords{-6 1.5}\PScline{0 0 1 0 1 1 0 1}
\endPSpicture
}

\def\thesignature{\hfill Anders Thorup}

\def\onepage{
\thetitle
\line{\thenames \hskip1\PSunit \theaim\hss}
\vskip1truecm
\twoboards
\vskip1truecm
\thehits
\vskip1truecm
\thesignature
}

%Here we go:

\PSunit=0.75truecm

\let\pentconf\relax
\onepage
\vfill\eject

\def\pentconf{
\J-90 {0 2}
\YL180 {1 6}
\Q0 {1 5}
\Z-90 {1 3}
\X0 {2 3}
\W-90 {2 8}
\N90 {7 6}
\V180 {8 8}
\T-90 {2 2}
\U90 {7 0}
\F180 {6 6}
\I0 {7 0}
}
\onepage \vfill\eject

\def\pentconf{
\U0 {0 0}
\X0 {1 1}
\T90 {3 4}
\Q90 {3 7}
\W0 {1 5}
\V90 {6 0}
\S0 {3 1}
\F0 {3 2}
\NL-90 {3 6}
\L-90 {4 8}
\YL0 {6 2}
\I0 {7 2}
}
\onepage \vfill\eject

\def\pentconf{
\I-90 {0 1}
\V0 {0 1}
\N-90 {0 6}
\L-90 {0 8}
\Z0 {1 2}
\YL-90 {2 7}
\Q180 {4 4}
\T0 {4 3}
\U0 {5 0}
\F90 {8 2}
\X0 {6 3}
\W90 {8 5}
}
\onepage \vfill\eject

\def\pentconf{
\I0 {0 0}
\P90 {4 0}
\W0 {1 2}
\FL0 {1 3}
\S90 {3 5}
\U0 {3 5}
\J90 {5 6}
\X0 {4 0}
\NL180 {6 5}
\V90 {8 0}
\T0 {6 5}
\YR180 {8 7}
 }
\onepage \vfill\eject


\def\pentconf{
\J-90 {0 2}
\YL0 {1 1}
\FL90 {3 5}
\I-90 {0 8}
\NL90 {6 2}
\T90 {5 3}
\W-90 {3 7}
\X0 {5 5}
\Z90 {7 1}
\U90 {8 5}
\V90 {8 0}
\Q-90 {5 4}
}
\onepage \vfill\eject

\bye




\vfill\eject
\PSpicture{20\PSunit}{3\PSunit}
\CTX{`V'}{0.5 0.5}	       
\CTX{`S'}{2.5 1.5}	       
\CTX{Pistol}{4 2.5}	       
\CTX{Zigzag}{6 1.5}	       
\CTX{`T'}{7.5 0.5}	       
\CTX{Charles XII}{9.5 1.5}     
\CTX{FLash}{10.5 2.5}	       
\CTX{`L'}{12 0.5}	       
\CTX{Stick}{14.5 2.5}	       
\CTX{Lump}{15.5 0.5}	       
\CTX{Cross}{17.5 1.5}	       
\CTX{`U'}{19.5 1.5}            

\V0 {0 0}
\S90 {4 0}
\YR-90 {2 3}
\W0 {4 0}
\T180 {8 3}
\F90 {11 1}
\N-90 {9 3}
\L90 {14 0}
\I-90 {12 3}
\P90 {17 0}
\X0 {17 0}
\U90 {20 0}
\endPSpicture


