🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.text
Article #5029

EEPIC 1.0 (Part 2 of 2)

#5029
From: Conrad Kwok
Date: Tue, 23 Aug 1988 00:00
1018 lines
44553 bytes
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	eepic.sty
#	epic.sty
# This archive created: Sun Aug 21 00:04:25 1988
export PATH; PATH=/bin:$PATH
if test -f 'eepic.sty'
then
	echo shar: will not over-write existing file "'eepic.sty'"
else
sed 's/^X//' << \SHAR_EOF > 'eepic.sty'
X% eepic Version 1.0 < August 14, 1988 >
X%	Written by Conrad Kwok
X%
X% Internet : kwok@iris.ucdavis.edu
X% csnet    : kwok@ucd.csnet
X% csnet    : kwok%iris.ucdavis.edu@csnet.relay
X% UUCP	   : ...!ucbvax!ucdavis!iris!kwok
X%
X% The macros are in public domain.
X% You may distribute or modify it in any ways you like.
X% Please report any bugs, enhancements, comments, suggestions, etc.
X%
X% This style file modify some of the commands in epic[1] and LaTeX[2] such
X% that \special commands will be generated in drawing lines if approriate.
X% The \special commands generated is the subset of the \specials used
X% by tpic[3].
X%
X% [1] epic is written by Sunil Podar. Please read epic.sty for the
X%     copyright notice.
X% [2] LaTeX is written by Leslie Lamport. Please read the book LaTeX
X% [3] tpic is modified from pic by Tim Morgan
X%
X%% This file contains extensions of the following epic commands:
X%%	\dottedline	\dashline	\drawline
X%%	\jput
X%%
X%% It also contains extensions of the following LaTeX commands:
X%%	\circle		\line
X%%
X%% New commands include:
X%%	\Thicklines	\arc		\ellipse
X%%	\path		\spline
X%%
X%% For documentation, please see the accompanying manual
X%%
X\makeatletter
X\typeout{%
XExtension to Epic and LaTeX. Version 1.0 - Release August 14, 1988}
X%
X\newcount\@gphlinewidth
X\newcount\@eepictcnt
X\newdimen\@tempdimc
X\@gphlinewidth\@wholewidth \divide\@gphlinewidth 4736
X
X%% Redefine \thinlines, \thicklines
X%% See also latex.tex
X\def\thinlines{\let\@linefnt\tenln \let\@circlefnt\tencirc
X    \@wholewidth\fontdimen8\tenln \@halfwidth .5\@wholewidth
X    \@gphlinewidth\@wholewidth \divide\@gphlinewidth 4736\relax}
X\def\thicklines{\let\@linefnt\tenlnw \let\@circlefnt\tencircw
X    \@wholewidth\fontdimen8\tenlnw \@halfwidth .5\@wholewidth
X    \@gphlinewidth\@wholewidth \divide\@gphlinewidth 4736
X    \advance\@gphlinewidth\@ne   % Make the output looks better
X    \relax}
X%%
X%% To indicate whether the dot character is defined in the dotted join
X%%     environment or not (\@ifnodotdef)
X\newif\if@nodotdef \global\@nodotdeftrue
X%%
X%% Redefine \dottedjoin
X\def\dottedjoin{\global\@jointhemtrue \global\@joinkind=0\relax
X  \bgroup\@ifnextchar[{\global\@nodotdeffalse\@idottedjoin}%
X                      {\global\@nodotdeftrue\@idottedjoin[\@empty]}}
X%%----------------------------------------------------------------------
X%% Redefine \jput
X\long\def\jput(#1,#2)#3{\@killglue\raise#2\unitlength\hbox to \z@{\hskip
X#1\unitlength #3\hss}%
X\if@jointhem \if@firstpoint \gdef\x@one{#1} \gdef\y@one{#2} \global\@firstpointfalse
X \else\ifcase\@joinkind
X    \if@nodotdef
X        \@spdottedline{\dotgap@join\unitlength}%
X(\x@one\unitlength ,\y@one\unitlength)(#1\unitlength,#2\unitlength)
X    \else
X	\@dottedline[\dotchar@join]{\dotgap@join\unitlength}%
X(\x@one\unitlength,\y@one\unitlength)(#1\unitlength,#2\unitlength)
X    \fi
X	\or\@dashline[\dashlinestretch]{\dashlen@join\unitlength}[\dotgap@join]%
X(\x@one,\y@one)(#1,#2)
X	\else\@drawline[\drawlinestretch](\x@one,\y@one)(#1,#2)\fi
X    \gdef\x@one{#1}\gdef\y@one{#2}%
X \fi
X\fi\ignorespaces}
X%%
X%% Redefine \dottedline to generate special whenever possible.
X\def\dottedline{\@ifnextchar [{\@idottedline}{\@ispdottedline}}
X%% Similar to \@idottedline but it generate \special
X\def\@ispdottedline#1(#2,#3){\@ifnextchar (%
X{\@iispdottedline{#1}(#2,#3)}{\relax}}
X\def\@iispdottedline#1(#2,#3)(#4,#5){\@spdottedline{#1\unitlength}%
X(#2\unitlength,#3\unitlength)(#4\unitlength,#5\unitlength)%
X\@ispdottedline{#1}(#4,#5)}
X%
X\def\@spdottedline#1(#2,#3)(#4,#5){%
X    \@tempcnta \@gphlinewidth\relax
X    \advance\@tempcnta by 2     % solely for better output
X    \special{pn \the\@tempcnta}%
X    \@tempdimc=#2\relax
X    \@tempcnta \@tempdimc\relax \advance\@tempcnta 2368 \divide\@tempcnta 4736
X    \@tempdimc=#3\relax
X    \@tempcntb -\@tempdimc\relax\advance\@tempcntb -2368 \divide\@tempcntb 4736
X    \@paspecial{\the\@tempcnta}{\the\@tempcntb}%
X    \@tempdimc=#4\relax
X    \@tempcnta \@tempdimc\relax \advance\@tempcnta 2368 \divide\@tempcnta 4736
X    \@tempdimc=#5\relax
X    \@tempcntb -\@tempdimc\relax\advance\@tempcntb -2368 \divide\@tempcntb 4736
X    \@paspecial{\the\@tempcnta}{\the\@tempcntb}%
X    \@tempdimc=#1\relax
X%%
X%% Generate the pen width in terms of inch with 3 decimal digit.
X    \@tempcnta \@tempdimc\relax \advance\@tempcnta 2368 \divide\@tempcnta 4736
X%% \@tempcnta contain the pen width in terms of thousandth of a inch
X%% Then it is converted back to inch. I know the way I use is dumb but
X%% I cannot think of any better method
X    \@tempcntb \@tempcnta\relax \divide\@tempcntb 1000
X    \multiply \@tempcntb 1000 \advance\@tempcnta -\@tempcntb
X    \divide\@tempcntb 1000
X    \ifnum\@tempcnta < 10
X        \special{dt \the\@tempcntb.00\the\@tempcnta}%
X    \else\ifnum\@tempcnta < 100
X        \special{dt \the\@tempcntb.0\the\@tempcnta}%
X    \else
X        \special{dt \the\@tempcntb.\the\@tempcnta}%
X    \fi\fi
X    \ignorespaces
X}
X%
X\def\@iiidashline[#1]#2[#3](#4,#5)(#6,#7){%
X\@dashline[#1]{#2\unitlength}[#3](#4,#5)(#6,#7)%
X\@iidashline[#1]{#2}[#3](#6,#7)}
X%
X%% Redefine \@dashline
X\long\def\@dashline[#1]#2[#3](#4,#5)(#6,#7){{%
X\x@diff=#6\unitlength \advance\x@diff by -#4\unitlength
X\y@diff=#7\unitlength \advance\y@diff by -#5\unitlength
X%% correction to get actual width since the dash-length as taken in arguement
X%% is the center-to-center of the end-points.
X\@tempdima=#2\relax \advance\@tempdima -\@wholewidth
X\sqrtandstuff{\x@diff}{\y@diff}{\@tempdima}%
X\ifnum\num@segments <3 \num@segments=3\fi% min number of dashes I can plot
X% is 2, 1 at either end, thus min num@segments is 3 (including 'empty dash').
X\@tempdima=\x@diff \@tempdimb=\y@diff
X\divide\@tempdimb by\num@segments
X\divide\@tempdima by\num@segments
X%% ugly if-then-else. If optional dotgap specified, then use it otherwise
X%% make a solid dash.
X{\ifx#3\@empty \relax
X    \ifdim\@tempdima < 0pt \x@diff=-\@tempdima\else\x@diff=\@tempdima\fi
X    \ifdim\@tempdimb < 0pt \y@diff=-\@tempdimb\else\y@diff=\@tempdimb\fi
X    \global\setbox\@dotbox\hbox{%
X                \@absspdrawline(0pt,0pt)(\@tempdima,\@tempdimb)}%
X    \else\global\setbox\@dotbox\hbox{%
X        \@spdottedline{#3\unitlength}(0pt,0pt)(\@tempdima,\@tempdimb)}%
X    \fi}%
X\advance\x@diff by -\@tempdima % both have same sign
X\advance\y@diff by -\@tempdimb
X%
X%%here we correct the number of dashes to be put by reducing them
X%%appropriately. (num@segments*\@wholewidth) is in some way the slack we
X%%have,and division by dash-length gives the reduction. reduction =
X%%(2*num@segments*\@wholewidth)/dash-length
X%% (num@segments includes empty ones)
X\@tempdima=\num@segments\@wholewidth \@tempdima=2\@tempdima
X\@tempcnta\@tempdima\relax \@tempdima=#2\relax \@tempdimb=0.5\@tempdima
X\@tempcntb\@tempdimb\relax \advance\@tempcnta by \@tempcntb % round-off error
X\divide\@tempcnta by\@tempdima \advance\num@segments by -\@tempcnta
X%
X\ifnum #1=0 \relax\else\ifnum #1 < -100
X  \typeout{***dashline: reduction > -100 percent implies blankness!***}
X\else\num@segmentsi=#1 \advance\num@segmentsi by 100
X     \multiply\num@segments by\num@segmentsi \divide\num@segments by 100
X\fi\fi
X%
X\divide\num@segments by 2 % earlier num@segments included 'empty dashes' too.
X\ifnum\num@segments >0 % if =0 then don't divide => \x@diff & \y@diff
X \divide\x@diff by\num@segments%   remain same.
X \divide\y@diff by\num@segments
X \advance\num@segments by\@ne %for the last segment for which I subtracted
X	 		     %\@tempdima & \@tempdimb from \x@diff & \y@diff
X \else\num@segments=2 % one at each end.
X\fi
X%%\typeout{num@segments finally = \the\num@segments}
X%% equiv to \multiput(#4,#5)(\x@diff,\y@diff){\num@segments}{\copy\@dotbox}
X%% with arguements in absolute dimensions.
X\@xdim=#4\unitlength \@ydim=#5\unitlength
X\@killglue
X\loop \ifnum\num@segments > 0
X\unskip\raise\@ydim\hbox to\z@{\hskip\@xdim \copy\@dotbox\hss}%
X\advance\num@segments \m@ne\advance\@xdim\x@diff\advance\@ydim\y@diff%
X\repeat}%
X\ignorespaces}
X%% redefine \@drawline
X%
X\def\@drawline[#1](#2,#3)(#4,#5){{%
X\@drawitfalse\@horvlinefalse
X\ifnum#1 <0 \relax\else\@horvlinetrue\fi
X\if@horvline
X \@spdrawline(#2,#3)(#4,#5)
X\else\@drawittrue\fi
X%%-------------------------------
X\if@drawit
X\ifnum #1=0 \relax \else\ifnum #1 < -99
X  \typeout{***drawline: reduction <= -100 percent implies blankness!***}%
X\else\num@segmentsi=#1 \advance\num@segmentsi by 50
X     \multiply\num@segmentsi 2
X\fi\fi
X\@dashline[\num@segmentsi]{10pt}[\@empty](#2,#3)(#4,#5)
X\fi}\ignorespaces}% for \if@drawit
X%
X\def\@spdrawline(#1,#2)(#3,#4){%
X   \@absspdrawline(#1\unitlength,#2\unitlength)(#3\unitlength,#4\unitlength)
X   \ignorespaces
X}
X\def\@absspdrawline(#1,#2)(#3,#4){%
X    \special{pn \the\@gphlinewidth}%
X    \@tempdimc=#1\relax
X    \@tempcnta \@tempdimc\relax \advance\@tempcnta 2368 \divide\@tempcnta 4736
X    \@tempdimc=#2\relax
X    \@tempcntb -\@tempdimc\relax \advance\@tempcntb -2368 \divide\@tempcntb 4736
X    \@paspecial{\the\@tempcnta}{\the\@tempcntb}%
X    \@tempdimc=#3\relax
X    \@tempcnta\@tempdimc\relax \advance\@tempcnta 2368 \divide\@tempcnta 4736
X    \@tempdimc=#4\relax
X    \@tempcntb -\@tempdimc\relax \advance\@tempcntb -2368 \divide\@tempcntb 4736
X    \@paspecial{\the\@tempcnta}{\the\@tempcntb}%
X    \special{fp}%
X    \ignorespaces
X}
X%%----------------------------------------------------------------------
X\def\@paspecial#1#2{%
X    \special{pa #1 #2}%
X}
X%%
X%% Functions below modify the LaTeX commands and some additional commands
X%% are not supported by LaTeX nor epic such as ThickLines and arc.
X%%
X%% The macros are for use with LaTeX picture environment
X%% By including the macro file, you can draw
X%%   1) \line in any slope
X%%   2) \circle with any radius
X%%   3) \ellipse with any x-axis and y-axis length
X%%   4) Circular \arc by giving starting and ending angle (in radius)
X%%
X%% Furthermore you may draw lines in any thickness.
X%%
X%%
X%% Redefine \thinlines, \thicklines and define \Thickline
X%% See also latex.tex
X\def\Thicklines{\let\@linefnt\tenlnw \let\@circlefnt\tencircw
X    \@wholewidth\fontdimen8\tenlnw \@wholewidth 1.5\@wholewidth
X    \@halfwidth .5\@wholewidth
X    \@gphlinewidth\@wholewidth \divide\@gphlinewidth 4736\relax}
X%%
X%% Generate the \special command for drawing arc
X\def\@circlespecial#1#2#3#4{%
X	      \special{pn \the\@gphlinewidth}%
X	      \special{ar 0 0 #1 #2 #3 #4}
X}
X%%
X%% Command for drawing an arc. Elliptical arc command can be generated
X%% but all iptex program I saw so far does not support that.
X\def\@arc#1#2#3#4{%
X%% convert TeX dimension to length in terms thousandth of an inch
X	\@tempdima #1\unitlength
X	\@tempdimb #2\unitlength
X        \@tempcnta\@tempdima \advance\@tempcnta 4736 \divide\@tempcnta 9473
X	\@tempcntb\@tempdimb \advance\@tempcntb 4736 \divide\@tempcntb 9473
X	\setbox\@tempboxa\hbox{%
X	    \@circlespecial{\the\@tempcnta}{\the\@tempcntb}{#3}{#4}}%
X        \wd\@tempboxa\z@ \box\@tempboxa}
X%%
X%% Command for drawing Circle and Ellipse in terms of \@arc
X%% replace original \circle
X\def\circle{%
X    \@ifstar{\special{bk}\@circle}{\@circle}}
X\def\@circle#1{\@arc{#1}{#1}{0}{6.2832}}
X\def\ellipse{%
X    \@ifstar{\special{bk}\@ellipse}{\@ellipse}}
X\def\@ellipse#1#2{{\@arc{#1}{#2}{0}{6.2832}}}
X\def\arc#1#2#3{\@arc{#1}{#1}{#2}{#3}}
X%%
X%% Generate \special commands for drawing line
X\def\@linespecial#1#2{%
X	      \special{pn \the\@gphlinewidth}%
X	      \special{pa 0 0}%
X	      \special{pa #1 #2}%
X	      \special{fp}%
X}
X%%
X%% Replace original \@sline
X%% For description, see latex.tex
X\def\@sline{%
X	\ifnum\@xarg< 0
X	  \@negargtrue \@xarg -\@xarg \@tempdima -\@linelen
X	\else
X	  \@negargfalse \@tempdima\@linelen
X	\fi
X%% truncation is used in arithmetic
X	\@tempcnta\@linelen \divide\@tempcnta 4736
X        \@yyarg -\@yarg \multiply\@yyarg \@tempcnta \divide\@yyarg\@xarg
X 	\if@negarg
X	    \@tempcnta -\@tempcnta
X	\fi
X	\setbox\@linechar\hbox{\@linespecial{\the\@tempcnta}{\the\@yyarg}}%
X	\wd\@linechar\@tempdima
X	\@clnht\@linelen
X        \multiply\@clnht\@yarg
X        \divide\@clnht\@xarg
X	\ifnum\@yarg< 0
X	  \@clnht -\@clnht
X	  \ht\@linechar\z@ \dp\@linechar\@clnht
X	\else
X	  \ht\@linechar\@clnht \dp\@linechar\z@
X	\fi
X	\box\@linechar
X%% Codes below (till end of the command) is only necessary
X%% when used with \@svector
X	\if@negarg
X	  \@yyarg -\@yarg
X	\else
X	  \@yyarg \@yarg
X	\fi
X	\setbox\@linechar\hbox{\@linefnt\@getlinechar(\@xarg,\@yyarg)}%
X	\ifnum\@yarg> 0
X	  \let\@upordown\raise
X	  \advance\@clnht -\ht\@linechar
X	\else
X	  \let\@upordown\lower
X	\fi
X	\if@negarg \kern\wd\@linechar \fi
X}
X%%
X\def\spline(#1,#2){%
X    \special{pn \the\@gphlinewidth}%
X    \@spline(#1,#2)%
X}
X\def\@spline(#1,#2){%
X    \@tempdima #1\unitlength
X    \@tempdimb #2\unitlength
X    \@tempcnta \@tempdima \advance\@tempcnta 2368 \divide\@tempcnta 4736
X    \@tempcntb -\@tempdimb \advance\@tempcntb -2368 \divide\@tempcntb 4736
X    \@paspecial{\the\@tempcnta}{\the\@tempcntb}%
X    \@ifnextchar ({\@spline}{\special{sp}}%
X}
X\def\path(#1,#2){%
X    \special{pn \the\@gphlinewidth}%
X    \@path(#1,#2)%
X}
X\def\@path(#1,#2){%
X    \@tempdima #1\unitlength
X    \@tempdimb #2\unitlength
X    \@tempcnta \@tempdima \advance\@tempcnta 2368 \divide\@tempcnta 4736
X    \@tempcntb -\@tempdimb \advance\@tempcntb -2368 \divide\@tempcntb 4736
X    \@paspecial{\the\@tempcnta}{\the\@tempcntb}%
X    \@ifnextchar ({\@path}{\special{fp}}%
X}
X
X%%%%%%%%%% Beginning of \oval %%%%%%%%%%%%%%%
X\newdimen\maxovaldiam \maxovaldiam 40pt\relax
X
X\def\@oval(#1,#2)[#3]{\begingroup\boxmaxdepth \maxdimen
X  \@ovttrue \@ovbtrue \@ovltrue \@ovrtrue
X  \@tfor\@tempa :=#3\do{\csname @ov\@tempa false\endcsname}\@ovxx
X  #1\unitlength \@ovyy #2\unitlength
X  \@tempdimb \ifdim \@ovyy >\@ovxx \@ovxx\else \@ovyy \fi
X  \@ovro \ifdim \@tempdimb>\maxovaldiam \maxovaldiam\else\@tempdimb\fi\relax
X  \divide \@ovro \tw@
X  \@ovdx\@ovxx \divide\@ovdx \tw@
X  \@ovdy\@ovyy \divide\@ovdy \tw@
X  \setbox\@tempboxa \hbox{%
X  \if@ovr \@ovverta\fi
X  \if@ovl \kern \@ovxx \@ovvertb\kern -\@ovxx \fi
X  \if@ovt \@ovhorz \kern -\@ovxx \fi
X  \if@ovb \raise \@ovyy \@ovhorz \fi}
X  \ht\@tempboxa\z@ \dp\@tempboxa\z@
X  \@put{-\@ovdx}{-\@ovdy}{\box\@tempboxa}%
X  \endgroup}
X
X\def\@qcirc#1#2#3#4{%
X    \special{pn \the\@gphlinewidth}%
X    \@eepictcnt \@gphlinewidth \divide\@eepictcnt 2
X    \@tempcnta #1 
X      \advance\@tempcnta 2368 \divide\@tempcnta 4736
X      \advance\@tempcnta\@eepictcnt
X    \@tempcntb #2 \divide\@tempcntb 4736 \advance\@tempcntb 2
X    \hbox{%
X        \@qcircspecial{\the\@tempcnta}{-\the\@eepictcnt}{\the\@tempcntb}{#3}{#4}}%
X}
X\def\@qcircspecial#1#2#3#4#5{\special{ar #1 #2 #3 #3 #4 #5}}
X
X\def\@ovverta{\vbox to \@ovyy{%
X    \if@ovb
X        \kern \@ovro
X        \@qcirc{\@ovro}{\@ovro}{3.1416}{4.7124}\nointerlineskip
X    \else
X        \kern \@ovdy
X    \fi
X    \leaders\vrule width \@wholewidth\vfil \nointerlineskip
X    \if@ovt
X        \@qcirc{\@ovro}{\@ovro}{1.5708}{3.1416}\nointerlineskip
X        \kern \@ovro
X    \else
X        \kern \@ovdy
X    \fi
X}\kern -\@wholewidth}
X
X\def\@ovvertb{\vbox to \@ovyy{%
X    \if@ovb
X        \kern \@ovro
X        \@qcirc{-\@ovro}{\@ovro}{4.6124}{6.2832}\nointerlineskip
X    \else
X        \kern \@ovdy
X    \fi
X    \leaders\vrule width \@wholewidth\vfil \nointerlineskip
X    \if@ovt
X        \@qcirc{-\@ovro}{\@ovro}{0}{1.6708}\nointerlineskip
X        \kern \@ovro
X    \else
X        \kern \@ovdy
X    \fi
X}\kern -\@wholewidth}
X
X\def\@ovhorz{\hbox to \@ovxx{%
X    \if@ovr \kern \@ovro\else \kern \@ovdx \fi
X    \leaders \hrule height \@wholewidth \hfil
X    \if@ovl \kern \@ovro\else \kern \@ovdx \fi
X    }}
X%%%%%%%%% End of \oval %%%%%%%%%%%%%%
X
X\def\allinethickness#1{\let\@linefnt\tenlnw \let\@circlefnt\tencircw
X    \@wholewidth #1 \@halfwidth .5\@wholewidth
X    \@gphlinewidth\@wholewidth \divide\@gphlinewidth 4736\relax}
X\makeatother
X
SHAR_EOF
fi # end of overwriting check
if test -f 'epic.sty'
then
	echo shar: will not over-write existing file "'epic.sty'"
else
sed 's/^X//' << \SHAR_EOF > 'epic.sty'
X\makeatletter
X\typeout{%
XEnhancements to Picture Environment. Version 1.2 - Released June 1, 1986}
X%----------------------------------------------------------------------
X% Copyright (C) podar@sbcs (Sunil Podar) July 14,1986.
X% You may use this file in whatever way you wish. You are requested to 
X% leave this notice intact, and report any bugs, enhancements, comments,
X% suggestions, etc. to:
X% USmail: Sunil Podar,Dept. of Computer Science,SUNY at Stony Brook,NY 11794.
X%  CSNET: podar@sbcs.csnet
X%   ARPA: podar%suny-sb.csnet@csnet-relay.arpa
X%   UUCP: {allegra, hocsd, philabs, ogcvax}!sbcs!podar
X%----------------------------------------------------------------------
X% This file contains implementation of:
X% \multiputlist	\matrixput	\grid		\picsquare
X% \dottedline	\dashline	\drawline	\jput
X% \putfile
X% Environments: dottedjoin, dashjoin and drawjoin
X%
X% For documentation, see the accompanying manual.
X%----------------------------------------------------------------------
X% usage: \multiputlist(x,y)(delta-x,delta-y)[tbrl]{item1,item2,item3,.....}
X% \lop and \lopoff taken from TeXbook.
X%----------------------------------------------------------------------
X\def\lop#1\to#2{\expandafter\lopoff#1\lopoff#1#2}
X\long\def\lopoff,#1,#2\lopoff#3#4{\def#4{#1}\def#3{,#2}}
X\def\@@mlistempty{,}
X\newif\iflistnonempty
X\def\multiputlist(#1,#2)(#3,#4){\@ifnextchar
X[{\@imultiputlist(#1,#2)(#3,#4)}{\@imultiputlist(#1,#2)(#3,#4)[]}}
X
X\long\def\@imultiputlist(#1,#2)(#3,#4)[#5]#6{{%
X\@xdim=#1\unitlength \@ydim=#2\unitlength
X\listnonemptytrue \def\@@mlist{,#6,} % need this for end condition
X\loop
X\lop\@@mlist\to\@@firstoflist
X\@killglue\raise\@ydim\hbox to\z@{\hskip
X\@xdim\@imakepicbox(0,0)[#5]{\@@firstoflist}\hss}
X\advance\@xdim #3\unitlength\advance\@ydim #4\unitlength
X\ifx\@@mlist\@@mlistempty \listnonemptyfalse\fi
X\iflistnonempty
X\repeat\relax
X\ignorespaces}}
X%----------------------------------------------------------------------
X% two-dimensional version of \multiput
X% \matrixput(0,0)(20,0){5}(0,20){3}{\circle{2}}
X%----------------------------------------------------------------------
X\newcount\@@multicnt
X\def\matrixput(#1,#2)(#3,#4)#5(#6,#7)#8#9{%
X\ifnum#5>#8\@matrixput(#1,#2)(#3,#4){#5}(#6,#7){#8}{#9}%
X\else\@matrixput(#1,#2)(#6,#7){#8}(#3,#4){#5}{#9}\fi}
X
X%% here #5 >= #8
X\long\def\@matrixput(#1,#2)(#3,#4)#5(#6,#7)#8#9{{\@killglue%
X\@multicnt=#5\relax\@@multicnt=#8\relax%
X\@xdim=0pt%
X\@ydim=0pt%
X\setbox\@tempboxa\hbox{\@whilenum \@multicnt > 0\do {%
X%%\typeout{\the\@multicnt, \the\@@multicnt}%
X\raise\@ydim\hbox to \z@{\hskip\@xdim #9\hss}%
X\advance\@multicnt \m@ne%
X\advance\@xdim #3\unitlength\advance\@ydim #4\unitlength}}%
X\@xdim=#1\unitlength%
X\@ydim=#2\unitlength%
X\@whilenum \@@multicnt > 0\do {%
X\raise\@ydim\hbox to \z@{\hskip\@xdim \copy\@tempboxa\hss}%
X\advance\@@multicnt \m@ne%
X\advance\@xdim #6\unitlength\advance\@ydim #7\unitlength}%
X\ignorespaces}}
X%----------------------------------------------------------------------
X%\grid(wd,ht)(delta-wd,delta-ht)[initial-X-integer,initial-Y-integer]
X% example: 1. \put(0,0){\grid(95,100)(9.5,10)}
X%          2. \put(0,0){\grid(100,100)(10,5)[-10,0]}
X%          or \put(0,0){\tiny \grid(100,100)(5,5)[0,0]}%numbers in \tiny font
X%----------------------------------------------------------------------
X\newcount\d@lta
X\newdimen\@delta
X\newdimen\@@delta
X\newcount\@gridcnt
X\def\grid(#1,#2)(#3,#4){\@ifnextchar [{\@igrid(#1,#2)(#3,#4)}%
X{\@igrid(#1,#2)(#3,#4)[@,@]}}
X
X\long\def\@igrid(#1,#2)(#3,#4)[#5,#6]{%
X\makebox(#1,#2){%
X\@delta=#1pt\@@delta=#3pt\divide\@delta \@@delta\d@lta=\@delta%
X\advance\d@lta \@ne\relax\message{grid=\the\d@lta\space x}%
X%% copied the definition of \line(0,1){#2} for some efficiency!.
X\multiput(0,0)(#3,0){\d@lta}{\hbox to\z@{\hskip -\@halfwidth \vrule
X	 \@width \@wholewidth \@height #2\unitlength \@depth \z@\hss}}%
X\ifx#5@\relax\else%
X\global\@gridcnt=#5%
X\multiput(0,0)(#3,0){\d@lta}{%
X\makebox(0,-2)[t]{\number\@gridcnt\global\advance\@gridcnt by #3}}%
X\global\@gridcnt=#5%
X\multiput(0,#2)(#3,0){\d@lta}{\makebox(0,0)[b]{\number\@gridcnt\vspace{2mm}%
X\global\advance\@gridcnt by #3}}%
X\fi%
X\@delta=#2pt\@@delta=#4pt\divide\@delta \@@delta\d@lta=\@delta%
X\advance\d@lta \@ne\relax\message{\the\d@lta . }%
X%% copied the definition of \line(1,0){#1} for some efficiency!.
X\multiput(0,0)(0,#4){\d@lta}{\vrule \@height \@halfwidth \@depth \@halfwidth
X	 \@width #1\unitlength}%
X\ifx#6@\relax\else
X\global\@gridcnt=#6%
X\multiput(0,0)(0,#4){\d@lta}{%
X\makebox(0,0)[r]{\number\@gridcnt\ \global\advance\@gridcnt by #4}}%
X\global\@gridcnt=#6%
X\multiput(#1,0)(0,#4){\d@lta}{%
X\makebox(0,0)[l]{\ \number\@gridcnt\global\advance\@gridcnt by #4}}%
X\fi}}
X%----------------------------------------------------------------------
X% \picsquare is a centered square of dimensions governed by \thinlines,
X% \thicklines or \linethickness declarations.
X\def\picsquare{\hskip -0.5\@wholewidth%
X\vrule height \@halfwidth depth \@halfwidth width \@wholewidth}
X%
X% just a square dot with reference point at bottom-left
X\def\picsquare@bl{\vrule height \@wholewidth depth \z@  width \@wholewidth}
X%----------------------------------------------------------------------
X% \begin{dottedjoin}{interdot-gap in units}
X% .....			
X% \end{dottedjoin}
X% \begin{dashjoin}{dash-length in units}{interdotgap in each dash}
X% .....			
X% \end{dashjoin}
X% \begin{drawjoin}
X% .....
X% \end{drawjoin}
X% \jput(x,y){character}
X% \dottedline[opt. dotcharacter]{dotgap in units}(x1,y1)(x2,y2)...(xN,yN)
X% \dashline[#]{dash-length}[opt. dotgap](x1,y1)(x2,y2)...(xN,yN)
X% \drawline[#](x1,y1)(x2,y2)...(xN,yN)
X%----------------------------------------------------------------------
X% definitions for *join environment. had to do all this mess because of
X% optional arguments.
X%----------------------------------------------------------------------
X\newif\if@jointhem \global\@jointhemfalse
X\newif\if@firstpoint \global\@firstpointtrue
X\newcount\@joinkind
X%\newenvironment{dottedjoin}[1]%[opt char]{dotgap}
X%{\global\@jointhemtrue \gdef\dotgap@join{#1}\global\@joinkind=0\relax}%
X%{\global\@jointhemfalse \global\@firstpointtrue}
X%----------------------------------------------------------------------
X\def\dottedjoin{\global\@jointhemtrue \global\@joinkind=0\relax
X  \bgroup\@ifnextchar[{\@idottedjoin}{\@idottedjoin[\picsquare@bl]}}
X\def\@idottedjoin[#1]#2{\gdef\dotchar@join{#1}\gdef\dotgap@join{#2}}
X\def\enddottedjoin{\global\@jointhemfalse \global\@firstpointtrue\egroup}
X%----------------------------------------------------------------------
X\def\dashjoin{\global\@jointhemtrue \global\@joinkind=1\relax
X  \bgroup\@ifnextchar[{\@idashjoin}{\@idashjoin[\dashlinestretch]}}
X\def\@idashjoin[#1]#2{\edef\dashlinestretch{#1}\gdef\dashlen@join{#2}%
X\@ifnextchar[{\@iidashjoin}{\gdef\dotgap@join{}}}
X\def\@iidashjoin[#1]{\gdef\dotgap@join{#1}}
X\let\enddashjoin\enddottedjoin
X%----------------------------------------------------------------------
X\def\drawjoin{\global\@jointhemtrue \global\@joinkind=2\relax
X  \bgroup\@ifnextchar[{\@idrawjoin}{}}
X\def\@idrawjoin[#1]{\def\drawlinestretch{#1}}
X\let\enddrawjoin\enddottedjoin
X%----------------------------------------------------------------------
X%% this is equiv to \put(x,y){#1} when not in {dot*join} environment.
X\long\def\jput(#1,#2)#3{{\@killglue\raise#2\unitlength\hbox to \z@{\hskip
X#1\unitlength #3\hss}\ignorespaces}
X\if@jointhem
X \if@firstpoint \gdef\x@one{#1} \gdef\y@one{#2} \global\@firstpointfalse
X \else\ifcase\@joinkind
X	\@dottedline[\dotchar@join]{\dotgap@join\unitlength}%
X(\x@one\unitlength,\y@one\unitlength)(#1\unitlength,#2\unitlength)
X	\or\@dashline[\dashlinestretch]{\dashlen@join}[\dotgap@join]%
X(\x@one,\y@one)(#1,#2)
X	\else\@drawline[\drawlinestretch](\x@one,\y@one)(#1,#2)\fi
X    \gdef\x@one{#1} \gdef\y@one{#2}
X \fi
X\fi}
X%----------------------------------------------------------------------
X\newdimen\@dotgap
X\newdimen\@ddotgap
X\newcount\@x@diff
X\newcount\@y@diff
X\newdimen\x@diff
X\newdimen\y@diff
X\newbox\@dotbox
X\newcount\num@segments
X\newcount\num@segmentsi
X\newif\ifsqrt@done
X%% from sqrtandstuff func basically need \num@segments.
X%% given a deltax, deltay and dotgap, it calculates \num@segments = number of
X%% segments along the hypotenuse. used by \dottedline & \dashline.
X%% It finishes quickly if any of deltax or deltay are zero or close to zero.
X\def\sqrtandstuff#1#2#3{
X\ifdim #1 <0pt \@x@diff= -#1 \else\@x@diff=#1\fi
X\ifdim #2 <0pt \@y@diff= -#2 \else\@y@diff=#2\fi
X%% @diff's will be positive and diff's will retain their sign.
X\@dotgap=#3 \divide\@dotgap \tw@
X\advance\@x@diff \@dotgap \advance\@y@diff \@dotgap% for round-off errors
X\@dotgap=#3
X\divide\@x@diff \@dotgap \divide\@y@diff \@dotgap
X\sqrt@donefalse
X\ifnum\@x@diff < 2
X   \ifnum\@y@diff < 2 \num@segments=\@x@diff \advance\num@segments \@y@diff
X		      \sqrt@donetrue
X        \else\num@segments=\@y@diff \sqrt@donetrue\fi
X   \else\ifnum\@y@diff < 2 \num@segments=\@x@diff \sqrt@donetrue\fi
X\fi
X\ifsqrt@done \ifnum\num@segments=\z@ \num@segments=\@ne\fi\relax
X \else \ifnum\@y@diff >\@x@diff
X		 \@tempcnta=\@x@diff \@x@diff=\@y@diff \@y@diff=\@tempcnta
X       \fi    		%exchange @x@diff & @y@diff, so now @x@diff > @y@diff
X  \num@segments=\@y@diff
X  \multiply\num@segments \num@segments
X  \multiply\num@segments by 457
X  \divide\num@segments \@x@diff
X  \advance\num@segments by 750 % for round-off, going to divide by 1000.
X  \divide\num@segments \@m
X  \advance\num@segments \@x@diff
X		%num@segments = @x@diff + (0.457*sqr(@y@diff)/@x@diff)
X\fi}
X%----------------------------------------------------------------------
X% \dottedline[opt. char]{interdot gap in units}(x1,y1)(x2,y2)....(xN,yN)
X%----------------------------------------------------------------------
X%% Used the following construction earlier but that results in box memory
X%% full much too soon although it works perfectly.
X%% \setbox\@dotbox\vbox to\z@{\vss \hbox to\z@{\hss #1\hss}\vss}\relax}
X%% The cenetering of characters is achieved by substracting half the ht, wd
X%% of character from the (x,y) coordinates where they are to be put. We
X%% chose to use a macro for the ``dot'' instead of \copy\box to save memory
X%% at the expense of extra cpu, since memory becomes an issue very soon.
X%% \picsquare is already centered, whereas other characters, except \circle,
X%% will not be cenetered, hence to handle them all in a similar fashion,
X%% used \picsquare@bl.
X%
X% kind of tail recursion.
X\def\dottedline{\@ifnextchar [{\@idottedline}{\@idottedline[\picsquare@bl]}}
X\def\@idottedline[#1]#2(#3,#4){\@ifnextchar (%
X{\@iidottedline[#1]{#2}(#3,#4)}{\relax}}
X\def\@iidottedline[#1]#2(#3,#4)(#5,#6){\@dottedline[#1]{#2\unitlength}%
X(#3\unitlength,#4\unitlength)(#5\unitlength,#6\unitlength)%
X\@idottedline[#1]{#2}(#5,#6)}
X%
X%% user not supposed to use this directly. arguments in absolute dimensions.
X%% need to pass absolute dimens here because dashline calls dottedline and
X%% can supply only absolute dimensions.
X\long\def\@dottedline[#1]#2(#3,#4)(#5,#6){{%
X\x@diff=#5\relax\advance\x@diff by -#3\relax
X\y@diff=#6\relax\advance\y@diff by -#4\relax
X\sqrtandstuff{\x@diff}{\y@diff}{#2}
X\divide\x@diff \num@segments
X\divide\y@diff \num@segments
X\advance\num@segments \@ne     % to put the last point at destination.
X%%\typeout{num@segments= \the\num@segments}
X\setbox\@dotbox\hbox{#1}% just to get the dimensions of the character.
X\@xdim=#3 \@ydim=#4
X\ifdim\ht\@dotbox >\z@% otherwise its a circle.
X  \advance\@xdim -0.5\wd\@dotbox
X  \advance\@ydim -0.5\ht\@dotbox
X  \advance\@ydim .5\dp\@dotbox\fi
X%%circle's have a ht=0, this is one way I could think of to catch circles.
X%%following loop is equiv to
X%%\multiput(\@xdim,\@ydim)(\x@diff,\y@diff){\num@segments}{#1}
X%%with arguments in absolute dimensions.
X\@killglue
X\loop \ifnum\num@segments > 0
X\unskip\raise\@ydim\hbox to\z@{\hskip\@xdim #1\hss}%
X\advance\num@segments \m@ne\advance\@xdim\x@diff\advance\@ydim\y@diff%
X\repeat
X\ignorespaces}}
X%----------------------------------------------------------------------
X% \dashline[#]{dash-length}[optional dotgap](x1,y1)(x2,y2)...(xN,yN)
X% The minimum # of dashes put is 2, one at either end point; dash-length is
X% reduced accordingly if necessary. Also have to some dirty work to account
X% for stretch & shrink.
X% \renewcommand{\dashlinestretch}{-50}  %ONLY INTEGERS PERMITTED.
X%----------------------------------------------------------------------
X\def\dashlinestretch{0} %well, could have used a counter.
X\def\dashline{\@ifnextchar [{\@idashline}{\@idashline[\dashlinestretch]}}
X\def\@idashline[#1]#2{\@ifnextchar [{\@iidashline[#1]{#2}}%
X{\@iidashline[#1]{#2}[\@empty]}} %\@empty needed-- later checked with \ifx 
X\def\@iidashline[#1]#2[#3](#4,#5){\@ifnextchar (%
X{\@iiidashline[#1]{#2}[#3](#4,#5)}{\relax}}
X%
X\def\@iiidashline[#1]#2[#3](#4,#5)(#6,#7){%
X\@dashline[#1]{#2}[#3](#4,#5)(#6,#7)%
X\@iidashline[#1]{#2}[#3](#6,#7)}
X%
X\long\def\@dashline[#1]#2[#3](#4,#5)(#6,#7){{%
X\x@diff=#6\unitlength \advance\x@diff by -#4\unitlength
X\y@diff=#7\unitlength \advance\y@diff by -#5\unitlength
X%% correction to get actual width since the dash-length as taken in arguement
X%% is the center-to-center of the end-points.
X\@tempdima=#2\unitlength \advance\@tempdima -\@wholewidth
X\sqrtandstuff{\x@diff}{\y@diff}{\@tempdima}
X\ifnum\num@segments <3 \num@segments=3\fi% min number of dashes I can plot
X% is 2, 1 at either end, thus min num@segments is 3 (including 'empty dash').
X\@tempdima=\x@diff \@tempdimb=\y@diff
X\divide\@tempdimb by\num@segments
X\divide\@tempdima by\num@segments
X%% ugly if-then-else. If optional dotgap specified, then use it otherwise
X%% make a solid looking dash.
X{\ifx#3\@empty \relax
X    \ifdim\@tempdima < 0pt \x@diff=-\@tempdima\else\x@diff=\@tempdima\fi
X    \ifdim\@tempdimb < 0pt \y@diff=-\@tempdimb\else\y@diff=\@tempdimb\fi
X    \ifdim\x@diff < 0.3pt %it's a vertical dashline
X           \ifdim\@tempdimb > 0pt
X	        \global\setbox\@dotbox\hbox{\hskip -\@halfwidth \vrule
X		 \@width \@wholewidth \@height \@tempdimb}
X	   \else\global\setbox\@dotbox\hbox{\hskip -\@halfwidth \vrule
X		 \@width \@wholewidth \@height\z@ \@depth -\@tempdimb}\fi
X       \else\ifdim\y@diff < 0.3pt %it's a horizontal dashline
X               \ifdim\@tempdima >0pt
X		  \global\setbox\@dotbox\hbox{\vrule \@height \@halfwidth
X		 		\@depth \@halfwidth \@width \@tempdima}
X		\else\global\setbox\@dotbox\hbox{\hskip \@tempdima
X			 \vrule \@height \@halfwidth \@depth \@halfwidth
X				 \@width -\@tempdima \hskip \@tempdima}\fi
X	    \else\global\setbox\@dotbox\hbox{%
X\@dottedline[\picsquare]{0.98\@wholewidth}(0pt,0pt)(\@tempdima,\@tempdimb)}
X\fi\fi
X\else\global\setbox\@dotbox\hbox{%
X\@dottedline[\picsquare]{#3\unitlength}(0pt,0pt)(\@tempdima,\@tempdimb)}
X\fi}
X\advance\x@diff by -\@tempdima % both have same sign
X\advance\y@diff by -\@tempdimb
X%
X%%here we correct the number of dashes to be put by reducing them
X%%appropriately. (num@segments*\@wholewidth) is in some way the slack we
X%%have,and division by dash-length gives the reduction. reduction =
X%%(2*num@segments*\@wholewidth)/dash-length
X%% (num@segments includes empty ones)
X\@tempdima=\num@segments\@wholewidth \@tempdima=2\@tempdima 
X\@tempcnta=\@tempdima \@tempdima=#2\unitlength \@tempdimb=0.5\@tempdima
X\@tempcntb=\@tempdimb \advance\@tempcnta by \@tempcntb % round-off error
X\divide\@tempcnta by\@tempdima \advance\num@segments by -\@tempcnta
X%
X\ifnum #1=0 \relax\else\ifnum #1 < -100
X  \typeout{***dashline: reduction > -100 percent implies blankness!***}
X\else\num@segmentsi=#1 \advance\num@segmentsi by 100
X     \multiply\num@segments by\num@segmentsi \divide\num@segments by 100
X\fi\fi
X%
X\divide\num@segments by 2 % earlier num@segments included 'empty dashes' too.
X\ifnum\num@segments >0 % if =0 then don't divide => \x@diff & \y@diff
X \divide\x@diff by\num@segments%   remain same.
X \divide\y@diff by\num@segments
X \advance\num@segments by\@ne %for the last segment for which I subtracted
X	 		     %\@tempdima & \@tempdimb from \x@diff & \y@diff
X \else\num@segments=2 % one at each end.
X\fi
X%%\typeout{num@segments finally = \the\num@segments}
X%% equiv to \multiput(#4,#5)(\x@diff,\y@diff){\num@segments}{\copy\@dotbox}
X%% with arguements in absolute dimensions.
X\@xdim=#4\unitlength \@ydim=#5\unitlength
X\@killglue
X\loop \ifnum\num@segments > 0
X\unskip\raise\@ydim\hbox to\z@{\hskip\@xdim \copy\@dotbox\hss}%
X\advance\num@segments \m@ne\advance\@xdim\x@diff\advance\@ydim\y@diff%
X\repeat
X\ignorespaces}}
X%----------------------------------------------------------------------
X%%1.00   .833333  .80  .75  .66666   .60  .50  .40  .33333    .25 .20  .16666
X%% .916666 .816666 .775 .708333 .633333 .55 .45 .366666 .291666 .225 .183333
X%% 0.0
X%%0.083333
X%% the first line has absolute slopes corresponding to various permissible
X%% integer combinations representing slopes. The second line is the midpoint
X%% of all those slopes (attempted to show them in the middle of two entries).
X%%
X%% \lineslope(x@diff dimen, y@diff dimen)
X%% Given base (x@diff) and height (y@diff) in dimensions, determines the
X%% closest available slope and returns the two required integers in \@xarg
X%% and \@yarg. The given base and height can be ANYTHING, -ve or +ve, or
X%% even 0pt. \lineslope knows about (0,1) and (1,0) slopes too and returns
X%% correct values if the conditions regarding x@diff & y@diff are obeyed
X%% (see NOTE). Used by \drawline. This is the simplest and only way I could
X%% figure out to accomplish it!.
X%% NOTE: both the dimensions (x@diff & y@diff) must be in SAME units and the
X%% larger of the two dimensions must be atleast 1pt (i.e. 65536sp). To avoid
X%% dividing by 0, I make the larger dimension = 1pt if it is < 1pt.
X%% will need a similar one for vectors, or maybe this can be used. For
X%% vectors the range is -4, 4 unlike lines where it is -6, 6.
X\newif\if@flippedargs
X\def\lineslope(#1,#2){%
X\ifdim #1 <0pt \@xdim= -#1 \else\@xdim=#1\fi
X\ifdim #2 <0pt \@ydim= -#2 \else\@ydim=#2\fi
X%%\typeout{xdim,ydim= \the\@xdim, \the\@ydim}
X\ifdim\@xdim >\@ydim \@tempdima=\@xdim \@xdim=\@ydim \@ydim=\@tempdima
X\@flippedargstrue\else\@flippedargsfalse\fi% x < y
X\ifdim\@ydim >1pt \@tempcnta=\@ydim
X            \divide\@tempcnta by 65536% now \@tempcnta=integral part of #1.
X            \divide\@xdim \@tempcnta\fi
X\ifdim\@xdim <.083333pt \@xarg=1 \@yarg=0
X \else\ifdim\@xdim <.183333pt	\@xarg=6 \@yarg=1
X \else\ifdim\@xdim <.225pt 	\@xarg=5 \@yarg=1
X \else\ifdim\@xdim <.291666pt 	\@xarg=4 \@yarg=1
X \else\ifdim\@xdim <.366666pt 	\@xarg=3 \@yarg=1
X \else\ifdim\@xdim <.45pt 	\@xarg=5 \@yarg=2
X \else\ifdim\@xdim <.55pt 	\@xarg=2 \@yarg=1
X \else\ifdim\@xdim <.633333pt 	\@xarg=5 \@yarg=3
X \else\ifdim\@xdim <.708333pt 	\@xarg=3 \@yarg=2
X \else\ifdim\@xdim <.775pt 	\@xarg=4 \@yarg=3
X \else\ifdim\@xdim <.816666pt 	\@xarg=5 \@yarg=4
X \else\ifdim\@xdim <.916666pt 	\@xarg=6 \@yarg=5
X       \else			\@xarg=1 \@yarg=1%
X\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
X\if@flippedargs\relax\else\@tempcnta=\@xarg \@xarg=\@yarg
X			  \@yarg=\@tempcnta\fi
X\ifdim #1 <0pt \@xarg= -\@xarg\fi
X\ifdim #2 <0pt \@yarg= -\@yarg\fi
X%%\typeout{closest slope integers = \the\@xarg, \the\@yarg}
X}
X%----------------------------------------------------------------------
X% usage: \drawline[#](x1,y1)(x2,y2)....(xN,yN)
X%       		 % # is an optional integer between -100 & infinity.
X% \renewcommand{\drawlinestretch}{-50}  %ONLY INTEGERS PERMITTED.
X%----------------------------------------------------------------------
X\newif\if@toosmall
X\newif\if@drawit
X\newif\if@horvline
X\def\drawlinestretch{0} %well, could have used a counter.
X% kind of tail recursion.
X\def\drawline{\@ifnextchar [{\@idrawline}{\@idrawline[\drawlinestretch]}}
X\def\@idrawline[#1](#2,#3){\@ifnextchar ({\@iidrawline[#1](#2,#3)}{\relax}}
X\def\@iidrawline[#1](#2,#3)(#4,#5){\@drawline[#1](#2,#3)(#4,#5)
X\@idrawline[#1](#4,#5)}
X%
X\def\@drawline[#1](#2,#3)(#4,#5){{%
X\x@diff=#4\unitlength \advance\x@diff by -#2\unitlength
X\y@diff=#5\unitlength \advance\y@diff by -#3\unitlength
X%% override any linethickness declarations, and since horiz & vertical lines
X%% come out thinner than the slanted ones, assign slightly larger values.
X%% default values are: thinlines=0.4pt, thicklines=0.8pt
X\ifx\@linefnt\tenln \linethickness{0.5pt} \else \linethickness{0.9pt}\fi
X\lineslope(\x@diff,\y@diff)% returns the two integers in \@xarg & \@yarg.
X%------
X\@toosmalltrue
X{\ifdim\x@diff <\z@ \x@diff=-\x@diff\fi
X \ifdim\y@diff <\z@ \y@diff=-\y@diff\fi
X \ifdim\x@diff >10pt \global\@toosmallfalse\fi
X \ifdim\y@diff >10pt \global\@toosmallfalse\fi}
X%------
X%% For efficiency, if the line is horiz or vertical then we draw it in one
X%% shot, only if the stretch is not -ve and the line is not too small.
X\@drawitfalse\@horvlinefalse
X\ifnum#1 <0 \relax\else\@horvlinetrue\fi
X\if@toosmall\@horvlinetrue\fi% to get 'or' condition. We necessarily draw a 
X% solid line if the line is too small ignoring any -ve stretch.
X\if@horvline
X \ifdim\x@diff =0pt \put(#2,#3){\ifdim\y@diff >0pt \@linelen=\y@diff \@upline
X 				\else\@linelen=-\y@diff \@downline\fi}%
X \else\ifdim\y@diff =0pt
X          \ifdim\x@diff >0pt \put(#2,#3){\vrule \@height \@halfwidth \@depth
X				\@halfwidth \@width \x@diff}
X		\else \put(#4,#5){\vrule \@height \@halfwidth \@depth
X				\@halfwidth \@width -\x@diff}\fi
X       \else\@drawittrue\fi\fi % construct the line explicitly
X\else\@drawittrue\fi
X%-------------------------------
X\if@drawit
X\ifnum\@xarg< 0 \@negargtrue\else\@negargfalse\fi
X\ifnum\@xarg =0 \setbox\@linechar%
X\hbox{\hskip -\@halfwidth \vrule \@width \@wholewidth \@height 10.2pt
X \@depth \z@}
X\else \ifnum\@yarg =0 \setbox\@linechar%
X\hbox{\vrule \@height \@halfwidth \@depth \@halfwidth \@width 10.2pt}
X\else \if@negarg \@xarg -\@xarg \@yyarg -\@yarg
X        \else \@yyarg \@yarg\fi
X\ifnum\@yyarg >0 \@tempcnta\@yyarg \else \@tempcnta -\@yyarg\fi
X\setbox\@linechar\hbox{\@linefnt\@getlinechar(\@xarg,\@yyarg)}%
X\fi\fi
X%------
X\if@toosmall% => it isn't a horiz or vert line and is toosmall.
X  \@dottedline[\picsquare]{.98\@wholewidth}%
X(#2\unitlength,#3\unitlength)(#4\unitlength,#5\unitlength)%
X\else
X%% following is neat. The last segment takes \wd\@linechar & \ht\@linechar
X%% so plot the line as though it were from (#2,#3) to
X%% (#4-\wd\@linechar,#5-\ht\@linechar) (i.e. for positive slope; of course,
X%% signs are reversed for other slopes). For horizontal & vertical dashes we
X%% don't have to subtract the ht & wd resp. since they are already centered.
X\ifnum\@xarg=0\relax\else\ifdim\x@diff >\z@ \advance\x@diff -\wd\@linechar
X  \else\advance\x@diff \wd\@linechar\fi\fi
X\ifnum\@yarg=0\relax\else\ifdim\y@diff >\z@\advance\y@diff -\ht\@linechar
X  \else\advance\y@diff \ht\@linechar\fi\fi
X\ifdim\x@diff <\z@ \@x@diff=-\x@diff \else\@x@diff=\x@diff\fi
X\ifdim\y@diff <\z@ \@y@diff=-\y@diff \else\@y@diff=\y@diff\fi
X%%\typeout{x@diff,y@diff=\the\x@diff , \the\y@diff}
X\num@segments=0 \num@segmentsi=0
X\ifdim\wd\@linechar >1pt
X \num@segmentsi=\@x@diff \divide\num@segmentsi \wd\@linechar\fi
X\ifdim\ht\@linechar >1pt
X \num@segments=\@y@diff \divide\num@segments \ht\@linechar\fi
X\ifnum\num@segmentsi >\num@segments \num@segments=\num@segmentsi\fi
X\advance\num@segments \@ne %to account for round-off error
X%
X\ifnum #1=0 \relax \else\ifnum #1 < -99
X  \typeout{***drawline: reduction <= -100 percent implies blankness!***}
X\else\num@segmentsi=#1 \advance\num@segmentsi by 100
X     \multiply\num@segments \num@segmentsi
X     \divide\num@segments by 100
X\fi\fi
X%%\typeout{num@segments after = \the\num@segments}
X%
X\divide\x@diff \num@segments
X\divide\y@diff \num@segments
X\advance\num@segments \@ne %for the last segment for which I subtracted
X			  %\wd & \ht of \@linechar from \@x@diff & \@y@diff.
X%%\typeout{numseg,x@diff,y@diff= \the\num@segments, \the\x@diff, \the\y@diff}
X%
X\@xdim=#2\unitlength \@ydim=#3\unitlength
X\if@negarg \advance\@xdim -\wd\@linechar\fi
X\ifnum\@yarg <0 \advance\@ydim -\ht\@linechar\fi
X%%following loop equiv to \multiput@abs(\@xdim,\@ydim)%
X%%(\x@diff,\y@diff){\num@segments}{\copy\@linechar}
X%%with arguements in absolute dimensions.
X\@killglue
X\loop \ifnum\num@segments > 0
X\unskip\raise\@ydim\hbox to\z@{\hskip\@xdim \copy\@linechar\hss}%
X\advance\num@segments \m@ne\advance\@xdim\x@diff\advance\@ydim\y@diff%
X\repeat
X\ignorespaces
X\fi%the if of @toosmall
X\fi}}% for \if@drawit
X%----------------------------------------------------------------------
X%usage: \putfile{datafile}{OBJECT}
X% The OBJECT is plotted at EACH of the coordinates read from the datafile.
X% The idea of these macros is to generate (x,y) pairs using some program
X% and then directly use those coordinates. Since TeX doesn't have real
X% floating point calculations, it is much more efficient and accurate to do
X% things this way. One can also use the unix facility 'spline' now to
X% generate smooth curves with equidistant ``dots''.
X% NOTE: the external file of coordinates must have x y pairs with a space
X% between them. Also it is suggested that some extension such as '.put'
X% be used for such datafiles to distinguish them in which case it must
X% be explicitely specified in the 1st argument so that TeX doesn't look
X% for a .tex extension.
X% The % char remains valid as a comment char and such lines are ignored;
X% however, there should be atleast one space after the second entry if a
X% comment is on the same line as data since % eats up the newline.
X%-----------------------------------------------------------------------
X\long\def\splittwoargs#1 #2 {(#1,#2)}
X%
X\newif\if@stillmore
X\newread\@datafile
X\long\def\putfile#1#2{\openin\@datafile = #1
X\@stillmoretrue
X\loop
X\ifeof\@datafile\relax\else\read\@datafile to\@dataline\fi
X%if file nonexistent, do nothing.
X\ifeof\@datafile\@stillmorefalse
X\else\ifx\@dataline\@empty \relax
X     \else
X\expandafter\expandafter\expandafter\put\expandafter\splittwoargs%
X\@dataline{#2}
X     \fi
X\fi
X\if@stillmore
X\repeat
X\closein\@datafile
X}
X%----------------------------------------------------------------------
X\makeatother
SHAR_EOF
fi # end of overwriting check
#	End of shell archive
exit 0
Technical Details
Message-ID: <2870@ucdavis.ucdavis.edu>
Path: arc1-ca.pugleaf.net!utzoo!attcan!uunet!lll-winken!lll-tis!helios.ee.lbl.gov!pasteur!ucbvax!ucdavis!iris!kwok

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!attcan!uunet!lll-winken!lll-tis!helios.ee.lbl.gov!pasteur!ucbvax!ucdavis!iris!kwok
From: kwok@iris (Conrad Kwok)
Newsgroups: comp.text
Subject: EEPIC 1.0 (Part 2 of 2)
Message-ID: <2870@ucdavis.ucdavis.edu>
Date: 23 Aug 88 00:00:39 GMT
Sender: uucp@ucdavis.ucdavis.edu
Reply-To: kwok@iris (Conrad Kwok)
Organization: U.C. Davis - Department of Electrical Engineering and Computer Science
Lines: 1017