% \iffalse % This is the coordsys package, coordsys.dtx % Copyright 2000--06 by Mogens Lemvig Hansen. % % Run first coordsys.ins then this file, coordsys.dtx, % through LaTeX and read the documentation in coordsys.dvi % % This program may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.2 % of this license or (at your option) any later version. % The latest version of this license is in % http://www.latex-project.org/lppl.txt % and version 1.2 or later is part of all distributions of LaTeX % version 2003/12/01 or later. % % This program consists of the files coordsys.dtx and coordsys.ins % %<*docdriver> \documentclass{ltxdoc}[1996/01/11] \usepackage{url,varioref,color,coordsys,logsys} \IfFileExists{eepic.sty}{\usepackage{epic,eepic}}{\relax} \CodelineIndex%\EnableCrossrefs %\OnlyDescription \MakeShortVerb{\"} \makeatletter \DoNotIndex{\@circlefnt, \@empty, \@ifpackageloaded, \@ifstar, \@tempcnta, \@tempcntb, \@tempdima, \@tempdimb, \@tempdimc, \@wholewidth, \\, \addtocounter, \addtolength, \advance, \afterassignment, \arabic, \baselineskip, \char, \color@begingroup, \color@endgroup, \colorbox, \count@, \DeclareOption, \def, \divide, \edef, \ensuremath, \ExecuteOptions, \fontdimen, \frac, \hbox, \hfill, \hrule, \hskip, \hspace, \hss, \if, \else, \fi, \ifdim, \fi, \ifnum, \fi, \ifx, \repeat, \ignorespaces, \leaders, \leavevmode, \let, \line, \lineskip, \loop, \makebox, \mbox, \MessageBreak, \multiply, \multiput, \n, \NeedsTeXFormat, \newcommand, \newif, \next, \offinterlineskip, \p@, \PackageError, \PackageWarning, \PassOptionsToPackage, \phantom, \ProcessOptions, \providecommand, \ProvidesPackage, \put, \raisebox, \relax, \renewcommand, \RequirePackage, \rule, \scriptsize, \setcounter, \setlength, \settodepth, \settoheight, \settowidth, \space, \stepcounter, \string, \t, \textfont, \the, \thicklines, \thinlines, \unitlength, \value, \vbox, \vector, \vee, \vfill, \vrule, \vskip, \vss, \wedge, \width, \z@} \newcommand{\nextlinelabel}[2][1]{\@bsphack \@tempcnta\c@CodelineNo \advance\@tempcnta#1\relax \def\@currentlabel{\the\@tempcnta}\label{#2}% \@esphack} \makeatother \begin{filecontents*}{parabola.put} -10 10 -9.5640569167 9.1471184705 -9.1847451708 8.4359543853 -8.7581694417 7.6705531969 -8.3287660917 6.936834461 -7.9014036208 6.2432179179 -7.5051839042 5.6327785435 -7.0949213375 5.0337908785 -6.6706272042 4.4497267297 -6.2476937875 3.9033677662 -5.8126547833 3.378695563 -5.4294721917 2.947916828 -4.99809935 2.4980997112 -4.56495525 2.0838816435 -4.14754065 1.7202093443 -3.7684882042 1.4201503345 -3.3177581833 1.1007519363 -2.9359307333 .8619689271 -2.4917746375 .6208940844 -2.0986212333 .4404211081 -1.6672696375 .2779788044 -1.2565209125 .1578844804 -.8279477083 .0685497408 -.4343837208 .0188689217 0 0 .4310767958 .0185827204 .8149238375 .0664100861 1.2294891583 .151164359 1.6577757 .2748220272 2.076770525 .4312975814 2.4821695625 .6161165737 2.932296075 .8598360271 3.3367547667 1.1133932373 3.76860075 1.4202351613 4.1599173958 1.730491274 4.58772985 2.1047265177 4.9902680292 2.4902775003 5.4110364125 2.9279315057 5.8224144167 3.3900509639 6.2530890625 3.9101122824 6.6678799333 4.4460622805 7.0920635083 5.0297364806 7.5127346292 5.6441181608 7.8992877 6.2398746167 8.3423211417 6.9594322031 8.7385755333 7.6362702352 9.1610653625 8.3925118576 9.5654420375 9.1497681373 10 10 \end{filecontents*} \begin{filecontents*}{cubic.put} -30.000000 -20.000000 -28.474199 -15.804432 -27.146608 -12.516116 -25.653593 -9.202436 -24.150681 -6.258297 -22.654913 -3.698008 -21.268144 -1.636385 -19.832225 .199365 -18.347195 1.796657 -16.866928 3.103311 -15.344292 4.170472 -14.003153 4.894524 -12.493348 5.486493 -10.977343 5.863124 -9.516392 6.039119 -8.189709 6.055876 -6.612154 5.918569 -5.275758 5.685123 -3.721211 5.298481 -2.345174 4.870173 -.835444 4.326615 .602177 3.755721 2.102183 3.124225 3.479657 2.529189 4.965449 1.889690 6.508769 1.248590 7.852233 .726681 9.303212 .218408 10.802215 -.227277 12.268697 -.565992 13.687593 -.784166 15.263036 -.879136 16.678642 -.813612 18.190103 -.566101 19.559711 -.166508 21.057054 .479871 22.465938 1.305413 23.938627 2.412189 25.378450 3.753353 26.885812 5.451531 28.337580 7.390383 29.822222 9.700301 31.294571 12.337014 32.647507 15.080062 34.198124 18.620739 35.585014 22.164125 37.063729 26.352494 38.479047 30.775514 40.000000 36.000000 \end{filecontents*} \begin{filecontents*}{cardioid.put} 100.000000 0.000000 112.588564 15.516766 121.244557 31.750443 124.934677 41.835945 127.659260 52.494751 129.345482 63.695172 129.903543 75.248573 129.285785 86.969731 127.460693 98.778657 124.672157 109.684223 120.825477 120.432570 115.738369 131.275035 109.553790 141.702160 102.046822 151.919323 93.471064 161.432430 83.935655 170.093229 73.505467 177.822188 61.952700 184.694870 49.689167 190.381106 38.407582 194.343741 26.780487 197.281781 13.407329 199.324137 -.119421 199.999947 -13.700122 199.294213 -27.122592 197.211115 -39.763584 193.927228 -51.980365 189.433046 -62.599453 184.351359 -72.673348 178.372314 -83.827620 170.181864 -93.966999 160.931907 -101.680605 152.366833 -108.531015 143.226867 -115.353429 131.996377 -120.892496 120.269314 -124.697389 109.601644 -127.460410 98.780030 -129.296948 86.861074 -129.903806 75.032811 -129.373414 63.979985 -127.809263 53.247345 -121.489566 32.332819 -112.548072 15.455006 -100.309649 .311093 -85.706682 -11.678463 -72.243183 -18.910373 -57.735843 -23.480262 -43.580925 -24.999414 -31.218159 -23.852436 -21.108797 -20.873626 -12.318983 -16.218684 -6.659458 -11.563205 -2.788086 -6.843880 -.903254 -3.342623 -.108179 -.830565 -.000001 -.000467 .107213 -.825650 .848070 -3.209033 2.934090 -7.064121 6.712690 -11.616493 12.726954 -16.492235 20.994604 -20.827287 30.567066 -23.721204 43.583975 -24.999401 56.641796 -23.700328 71.394649 -19.264856 85.586513 -11.757441 100.000000 .000000 \end{filecontents*} \begin{filecontents*}{csc1.put} 5.769525 100.000000 7.337294 78.302278 11.176475 51.591183 15.041105 38.533870 18.887368 30.891960 22.453345 26.182739 26.145708 22.693468 29.964355 20.021578 33.770756 17.989772 37.686107 16.357639 41.134750 15.201446 45.017106 14.137915 48.915403 13.267173 52.672134 12.575790 56.083606 12.050332 60.140176 11.530753 63.576624 11.166568 67.574028 10.818141 71.112409 10.569087 74.994573 10.353025 78.691312 10.197995 82.548471 10.085170 86.090547 10.023324 89.911154 10.000012 93.879691 10.022969 97.334315 10.082493 101.065402 10.189434 104.919981 10.348899 108.690935 10.556753 112.339526 10.811422 116.390665 11.163403 120.030793 11.550591 123.917407 12.050475 127.439256 12.594486 131.289569 13.308769 134.912412 14.120566 138.699328 15.151274 142.401730 16.390185 146.277801 18.012607 150.010919 20.006604 153.828571 22.672736 157.614611 26.258119 161.093589 30.861980 165.080890 38.841725 168.647180 50.800081 172.449588 76.104387 174.258156 100.000000 \end{filecontents*} \begin{filecontents*}{csc2.put} 185.769525 -100.000000 187.337294 -78.302274 191.176476 -51.591181 195.041106 -38.533869 198.887368 -30.891960 202.453345 -26.182739 206.145708 -22.693468 209.964356 -20.021578 213.770756 -17.989772 217.686107 -16.357639 221.134751 -15.201446 225.017106 -14.137915 228.915403 -13.267173 232.672134 -12.575790 236.083606 -12.050332 240.140177 -11.530753 243.576624 -11.166568 247.574028 -10.818141 251.112409 -10.569087 254.994573 -10.353025 258.691312 -10.197995 262.548471 -10.085170 266.090547 -10.023324 269.911154 -10.000012 273.879691 -10.022969 277.334314 -10.082493 281.065402 -10.189434 284.919981 -10.348899 288.690935 -10.556753 292.339526 -10.811422 296.390664 -11.163403 300.030793 -11.550591 303.917407 -12.050475 307.439256 -12.594486 311.289568 -13.308769 314.912412 -14.120566 318.699327 -15.151274 322.401729 -16.390185 326.277801 -18.012607 330.010919 -20.006604 333.828571 -22.672736 337.614611 -26.258119 341.093589 -30.861980 345.080890 -38.841724 348.647179 -50.800079 352.449588 -76.104383 354.258156 -100.000000 \end{filecontents*} \begin{filecontents*}{logistic.put} -10.000000 -17.371858 -9.564057 -16.614591 -9.184745 -15.955715 -8.758169 -15.214772 -8.328766 -14.468968 -7.901404 -13.726787 -7.505184 -13.038795 -7.094921 -12.326581 -6.670627 -11.590267 -6.247694 -10.856714 -5.812655 -10.102801 -5.429472 -9.439561 -4.998099 -8.694276 -4.564955 -7.948131 -4.147541 -7.232254 -3.768488 -6.586185 -3.317758 -5.825368 -2.935931 -5.190082 -2.491775 -4.466789 -2.098621 -3.846618 -1.667270 -3.196723 -1.256521 -2.617930 -.827948 -2.068053 -.631166 -1.837450 -.434384 -1.622076 -.222128 -1.407750 -.009872 -1.212716 .210603 -1.030806 .431077 -.869735 .623000 -.745941 .814924 -.636672 1.229489 -.445644 1.657776 -.303009 2.076771 -.205126 2.482170 -.139415 2.932296 -.090166 3.336755 -.060688 3.768601 -.039646 4.159917 -.026906 4.587730 -.017588 4.990268 -.011779 5.411036 -.007743 5.822414 -.005135 6.253089 -.003340 6.667880 -.002207 7.092064 -.001444 7.512735 -.000948 7.899288 -.000644 8.342321 -.000414 8.738576 -.000278 9.161065 -.000182 9.565442 -.000122 10.000000 -.000079 \end{filecontents*} \begin{document} \DocInput{coordsys.dtx} \end{document} % % \fi % \CheckSum{2292} % \CharacterTable % {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z % Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z % Digits \0\1\2\3\4\5\6\7\8\9 % Exclamation \! Double quote \" Hash (number) \# % Dollar \$ Percent \% Ampersand \& % Acute accent \' Left paren \( Right paren \) % Asterisk \* Plus \+ Comma \, % Minus \- Point \. Solidus \/ % Colon \: Semicolon \; Less than \< % Equals \= Greater than \> Question mark \? % Commercial at \@ Left bracket \[ Backslash \\ % Right bracket \] Circumflex \^ Underscore \_ % Grave accent \` Left brace \{ Vertical bar \| % Right brace \} Tilde \~} % % \def\fileversion{1.4} \def\filedate{2006/02/03} \def\docdate{\filedate} % \title{The \textsf{coordsys} and \textsf{logsys} Packages\thanks{This % file describes version \fileversion, \filedate.}} % \author{\copyright\ Mogens Lemvig Hansen\thanks{% % The \textsf{coordsys} and \textsf{logsys} packages are distributed under % the \LaTeX\ Project % Public License; please see Section~\ref{sec:license}.}\\ % mlhansen@uniserve.com} % \date{\docdate} % \maketitle % \begin{abstract} % The \textsf{coordsys} package provides commands for typesetting % number lines (coordinate axes), coordinate systems, and grids % in the \textsf{picture} environment. % The \textsf{logsys} package extends the \textsf{coordsys} package by % providing logarithmic, semi-logarithmic, and double-logarithmic % coordinate systems and grids. % \end{abstract} % % \tableofcontents % % \section{Regular Coordinate Systems} % Load the \textsf{coordsys} package with the "\usepackage" command. % \begin{quote} % "\usepackage"\oarg{options}"{coordsys}" % \end{quote} % The \textsf{coordsys} package has three \meta{options}, % \textsf{centred} (the default), \textsf{outside}, and \textsf{inside}, that % control the % appearance of tick marks; see Section~\ref{sec:tickstyle} on % page~\pageref{sec:tickstyle}. % % \subsection{One Dimension} % \DescribeMacro{\numbline} % The "\numbline" command typesets a number line.\index{number line|(usage} % For example, % \begin{quote} % \begin{verbatim} % \begin{picture}(200,20)(-75,-15) % \numbline{-75}{125} % \end{picture} % \end{verbatim} % \begin{picture}(200,20)(-75,-15) % \numbline{-75}{125} % \end{picture} % \end{quote} % You should always use the "\numbline" command inside a % \textsf{picture} environment. % Do not forget to leave room for the labels on the number line. % In the following examples I omit the "\begin{picture}" % and "\end{picture}" commands to reduce clutter. % % The tick marks are by default separated by 10 units; % give "\numbline" an optional first argument to change that. % For example % \begin{quote} % \begin{verbatim} % \numbline[7]{-75}{125} % \end{verbatim} % \begin{picture}(200,20)(-75,-15) % \numbline[7]{-75}{125} % \end{picture} % \end{quote} % % \DescribeMacro{\numbline*} % The starred version of "\numbline" omits the labels. % \begin{quote} % \begin{verbatim} % \numbline*[7]{-75}{125} % \end{verbatim} % \begin{picture}(200,6)(-75,-3) % \numbline*[7]{-75}{125} % \end{picture} % \end{quote} % % Thus, % \begin{quote} % "\numbline"\oarg{spacing}\marg{from}\marg{to}\\ % "\numbline*"\oarg{spacing}\marg{from}\marg{to} % \end{quote} % typeset\label{numblinesyntax} (horizontal) number lines % from \meta{from} to \meta{to} with % \meta{spacing} % units between the tick marks (the default is 10); % use the starred command to suppresses the labels. % All the arguments must be integers. % % \DescribeMacro{\vnumbline}\DescribeMacro{\vnumbline*} % The "\vnumbline" and "\vnumbline*" commands similarly % typeset vertical number lines. % \begin{quote} % "\vnumbline"\oarg{spacing}\marg{from}\marg{to}\\ % "\vnumbline*"\oarg{spacing}\marg{from}\marg{to} % \end{quote} % The syntax is similar to that of the "\numbline" command % \vpageref[above]{numblinesyntax}.\index{number line|)usage} % \begin{quote} % \begin{minipage}{.2\linewidth} % \begin{picture}(20,100)(-17,20) % \vnumbline{20}{120} % \end{picture} % \end{minipage} % \qquad % \begin{minipage}{.6\linewidth} % \begin{verbatim} % \vnumbline{20}{120} % \end{verbatim} % \end{minipage} % \end{quote} % % \subsection{Two Dimensions} % \DescribeMacro{\coordsys} % Use the "\coordsys"\index{coordinate system>with intersecting axes|usage} % command to typeset coordinate systems. % \begin{quote} % \begin{picture}(200,110)(-50,-50) % \coordsys(-50,-50)(150,60) % \put(75,25){\texttt{\textbackslash coordsys(-50,-50)(150,60)}} % \end{picture} % \end{quote} % \DescribeMacro{\coordsys*} % Thus, % \begin{quote} % "\coordsys"\oarg{h-spacing}\oarg{v-spacing}\parg{ll}\parg{ur}\\ % "\coordsys*"\oarg{h-spacing}\oarg{v-spacing}\parg{ll}\parg{ur} % \end{quote} % typeset\label{coordsyssyntax} coordinate systems where % \parg{ll} is the lower-left corner % and \parg{ur} is the upper-right corner. % The optional argument \meta{h-spacing} gives the spacing between the % tick marks on the horizontal axis; the default is 10 units. % The optional argument \meta{v-spacing} gives the spacing between the % tick marks on the vertical axis; the default is to use the same % spacing as on the horizontal axis. % The starred version omits the labels. % All the arguments must be integers. % % Regular coordinate systems with intersecting axes are not always % appropriate, for example when the point $(0,0)$ is not in the range % of the coordinate system. % The \textsf{coordsys} package therefore provides some alternative % styles. All the coordinate-system-drawing commands have similar syntax. % % \DescribeMacro{\fcoordsys}\DescribeMacro{\fcoordsys*} % The "\fcoordsys"\index{coordinate system>framed|usage} % command typesets framed coordinate systems; that is, the % axes are at the left and bottom edges of the system. % \begin{quote} % "\fcoordsys"\oarg{h-spacing}\oarg{v-spacing}\parg{ll}\parg{ur}\\ % "\fcoordsys*"\oarg{h-spacing}\oarg{v-spacing}\parg{ll}\parg{ur} % \end{quote} % The syntax is similar to that of the "\coordsys" command % \vpageref[above]{coordsyssyntax}. % \begin{quote} % \begin{picture}(220,125)(30,35) % \fcoordsys[5](50,50)(250,160) % \put(155,125){\texttt{\textbackslash fcoordsys[5](-50,-50)(150,60)}} % \end{picture} % \end{quote} % % \DescribeMacro{\bcoordsys}\DescribeMacro{\bcoordsys*} % The "\bcoordsys"\index{coordinate system>boxed|usage} % command typesets boxed coordinate systems. % \begin{quote} % "\bcoordsys"\oarg{h-spacing}\oarg{v-spacing}\parg{ll}\parg{ur}\\ % "\bcoordsys*"\oarg{h-spacing}\oarg{v-spacing}\parg{ll}\parg{ur} % \end{quote} % The syntax is similar to that of the "\coordsys" command % \vpageref[above]{coordsyssyntax}. % \begin{quote} % \begin{picture}(265,125)(-70,-65) % \bcoordsys[15][5](-50,-50)(195,60) % \put(-30,25){\texttt{\textbackslash bcoordsys[15][5](-50,-50)(195,60)}} % \end{picture} % \end{quote} % % \DescribeMacro{\window}\DescribeMacro{\window*} % The "\window" command typesets a plotting window as on a graphing % calculator. % \begin{quote} % "\window"\oarg{h-spacing}\oarg{v-spacing}\parg{ll}\parg{ur}\\ % "\window*"\oarg{h-spacing}\oarg{v-spacing}\parg{ll}\parg{ur} % \end{quote} % The syntax is similar to that of the "\coordsys" command % \vpageref[above]{coordsyssyntax}. % \begin{quote} % \begin{picture}(302,127)(-107,-67) % \window(-50,-50)(195,60) % \put(15,25){\texttt{\textbackslash window(-50,-50)(195,60)}} % \end{picture} % \end{quote} % The labels will look nicer if you use the \textsf{amstext} package (which is % part of the \textsf{amsmath} package). % % \DescribeMacro{\coordgrid} % The "\coordgrid"\index{grid|(usage}\index{grid>dotted|usage} % command typesets a coordinate grid. % \begin{quote} % \begin{picture}(300, 125) % \coordgrid(0,0)(300,125) % \put(15,25){\texttt{\textbackslash coordgrid(0,0)(300,125)}} % \end{picture} % \end{quote} % The "\coordgrid" command does not print any labels % but you can superimpose a coordinate system. % \begin{quote} % \begin{verbatim} % \coordgrid[15][5](-50,-50)(195,60) % \coordsys[15][5](-50,-50)(195,60) % \end{verbatim} % \begin{picture}(245,110)(-50,-50) % \coordgrid[15][5](-50,-50)(195,60) % \coordsys[15][5](-50,-50)(195,60) % \end{picture} % \end{quote} % If you load the \textsf{color} package before the \textsf{coordsys} % package, the labels will be printed on a % white background.\index{labels>background of|usage} % % Typesetting pretty grids with dotted lines is not easy. % If a grid does come out ugly,\index{grid>ugly|usage} % try to increase "\unitlength" % to allow for more dots between the lines. % You may also reduce the size of the dots; % see the "\gridstyle" command \vpageref[below]{gridstyle}. % \DescribeMacro{\coordgrid*} % Alternatively you can use the "\coordgrid*" command which % typesets a coordinate grid with solid lines.\index{grid>solid|usage} % You could then use the % \textsf{color} package to colour the grid, say, gray; again, see % the "\gridstyle" command \vpageref[below]{gridstyle}. % % Thus, % \begin{quote} % "\coordgrid"\oarg{h-spacing}\oarg{v-spacing}\parg{ll}\parg{ur}\\ % "\coordgrid*"\oarg{h-spacing}\oarg{v-spacing}\parg{ll}\parg{ur} % \end{quote} % typeset coordinate grids with a syntax similar to that of % the "\coordsys" command \vpageref[above]{coordsyssyntax}. % The starred version uses solid lines; % the un-starred version uses dotted lines.\index{grid|)usage} % % \DescribeMacro{\gridstyle}\label{gridstyle} % The default size of the dots is the with of "\thinlines" % and "\thicklines".\index{grid>size of dots|usage}\index{grid>style|(usage} % If you intend to print your grids at a % sufficiently high resolution, you should reduce the size of the % dots by issuing a "\gridstyle" command. On my 600\,dpi printer, % these sizes look nice for points: % \begin{quote} % \begin{verbatim} % \gridstyle{\linethickness{0.24pt}}{\linethickness{0.48pt}} % \end{verbatim} % \gridstyle{\linethickness{0.24pt}}{\linethickness{0.48pt}} % \begin{picture}(245,110)(-50,-50) % \coordgrid[15][5](-50,-50)(195,60) % \coordsys[15][5](-50,-50)(195,60) % \end{picture} % \end{quote} % When I use solid lines, I can get away with half that, % \begin{quote} % \begin{verbatim} % \gridstyle{\linethickness{0.12pt}}{\linethickness{0.24pt}} % \end{verbatim} % \gridstyle{\linethickness{0.12pt}}{\linethickness{0.24pt}} % \begin{picture}(245,110)(-50,-50) % \coordgrid*[15][5](-50,-50)(195,60) % \coordsys[15][5](-50,-50)(195,60) % \end{picture} % \end{quote} % % If you make grids for the screen, I recommend using % colour.\index{grid>coloured|usage} For example, % \begin{quote} % \begin{verbatim} % \definecolor{gray}{gray}{0.5} % \definecolor{lightgray}{gray}{0.75} % \gridstyle{\thinlines\color{lightgray}}{\thinlines\color{gray}} % \coordgrid*(-109,-65)(200,100) % \coordsys(-109,-65)(200,100) % \end{verbatim} % \begin{picture}(245,110)(-50,-50) % \definecolor{gray}{gray}{0.5} % \definecolor{lightgray}{gray}{0.75} % \gridstyle{\thinlines\color{lightgray}}{\thinlines\color{gray}} % \coordgrid*[15][5](-50,-50)(195,60) % \coordsys[15][5](-50,-50)(195,60) % \end{picture} % \end{quote} % % In general, % \begin{quote} % "\gridstyle"\marg{thin declaration}\marg{thick declaration} % \end{quote} % Note that these are \emph{declarations}: the \meta{thin declarations} % apply also to the thick grid lines unless explicitly overruled by the % \meta{thick declaration}. % The current "\gridstyle" applies to all types of grids: % dotted, solid, regular, or logarithmic. % The default style is % "\gridstyle{\thinlines}{\thicklines}".\label{defaultgridstyle}\index{grid>style|)usage} % % % \subsection{Bells and Whistles} % \subsubsection{Manual Labels} % \DescribeMacro{\sethlabel}\DescribeMacro{\setvlabel} % All the number-line and coordinate-system commands format the % labels\index{labels>manual|usage}\index{manual labels|usage} using % the commands "\sethlabel" (for labels on horizontal axes) and % "\setvlabel" (for labels on vertical axes). If you set labels manually, % you should use the same commands for a uniform appearance. % \begin{quote} % \begin{verbatim} % \numbline{-75}{125} % \put(125,0){\sethlabel{x}} % \end{verbatim} % \begin{picture}(200,20)(-75,-15) % \numbline{-75}{125} % \put(125,0){\sethlabel{x}} % \end{picture} % \end{quote} % The syntax is % \begin{quote} % "\sethlabel"\oarg{alignment}\marg{label}\\ % "\setvlabel"\oarg{alignment}\marg{label} % \end{quote} % The \meta{label} is set in math mode. % The default \meta{alignment} is "[t]" for "\sethlabel" and % "[r]" for "\setvlabel". You may want to add to these defaults % (as in "\sethlabel[tl]"); you probably do not want to replace the % defaults. % % If you want your labels set in some other style, you must re-define % "\sethlabel" and "\setvlabel". % % \subsubsection{Thick Tick Density} % \DescribeMacro{\hthickratio} % \DescribeMacro{\vthickratio} % By default every fifth tick mark is % thick.\index{thick ticks|usage}\index{ticks>ratio of thick|usage} % You can change that by redefining % the commands "\hthickratio" and "\vthickratio". % \begin{quote} % \begin{verbatim} % \renewcommand{\hthickratio}{4} % \numbline[25]{0}{350} % \end{verbatim} % \setlength{\unitlength}{.3pt} % \begin{picture}(350,80)(0,-50) % \renewcommand{\hthickratio}{4} % \numbline[25]{0}{350} % \end{picture} % \end{quote} % % \subsubsection{Different Scales on the Two Axes} % \DescribeMacro{\rescaleby} % LaTeX\ (the \textsf{picture} environment) does not support different % scales\index{labels>re-scaled|usage}\index{scaling labels|usage} % on the two axes; "\unitlength" is used for both the % horizontal and the vertical direction. % However, you may create the \emph{appearance} of different scales by % scaling the labels on the axes. % Here is a coordinate system that has been rigged to contain the graph of % $y=x^2$ for $x$ between $-10$ and $10$. % \begin{quote} % \setlength{\unitlength}{5pt} % \rescaleby{10}{1}{\vlabel} % \begin{picture}(22,15)(-10,-3) % \coordsys[1](-10,0)(12,12) % \end{picture} % \begin{minipage}[b]{.5\linewidth} % \begin{verbatim} % \rescaleby{10}{1}{\vlabel} % \coordsys[1](-10,0)(12,12) % \end{verbatim} % \end{minipage} % \end{quote} % That is, % \begin{quote} % "\rescaleby"\oarg{symb}\marg{num}\marg{den}\marg{cmd} % \end{quote} % multiplies the labels by $\frac{\meta{num}}{\meta{den}}\meta{symb}$; % both \meta{num} and \meta{den} must be integers; % and \meta{den} must be positive.\footnote{Multiplying the labels by % a negative number does not reverse the arrows, so I suggest using % boxed coordinate systems in that case.} % The optional argument, if present, represents a symbolic % (non-numeric) scale factor; see the example below. % The last argument, \meta{cmd}, must be one of "\hlabel" % or "\vlabel". % % The following coordinate system has been rigged for graphing $\sin$ or % $\cos$. Note that only that labels have been scaled; % the real coordinates of the small circle are still $(90,50)$. % \begin{quote} % \begin{verbatim} % \renewcommand{\hthickratio}{6} % \rescaleby[\pi]{1}{180}{\hlabel} % \rescaleby{1}{100}{\vlabel} % \coordsys[15][10](0,-100)(400,115) % \put(90,50){\circle{6}} % \end{verbatim} % \setlength{\unitlength}{.5pt} % \begin{picture}(435,215)(-35,-100) % \renewcommand{\hthickratio}{6} % \rescaleby[\pi]{1}{180}{\hlabel} % \rescaleby{1}{100}{\vlabel} % \coordsys[15][10](0,-100)(400,115) % \put(90,50){\circle{6}} % \end{picture} % \end{quote} % % \subsubsection{Different Styles of Tick Marks} % \label{sec:tickstyle} % \DescribeMacro{\tickstyle} % As you can affect the width of the dots or lines of a % "\coordgrid" with a "\gridstyle" command, % so you can affect the width of the tick marks with a % "\tickstyle"\index{ticks>style of|usage} command: % \begin{quote} % "\tickstyle"\marg{thin declaration}\marg{thick declaration} % \end{quote} % Note that these are \emph{declarations}: the \meta{thin declarations} % apply also to the thick tick marks unless explicitly overruled by the % \meta{thick declaration}.\footnote{And the declarations that apply % to the thick tick marks spill over to the labels which maybe they % shouldn't, so let's not talk about that.} % The default style is % "\tickstyle{\thinlines}{\thicklines}".\footnote{When % I wrote \vpageref[above]{defaultgridstyle} that the default grid style is % \texttt{\textbackslash gridstyle\{\textbackslash thinlines\}\{\textbackslash % thicklines\}} I lied. The default grid style is the follow the current % \texttt{\textbackslash tickstyle}.} % % \DescribeMacro{\ticklength} % The "\ticklength" command controls the length of the % tick marks.\index{ticks>length of|usage} % \begin{quote} % \begin{verbatim} % \tickstyle{\thinlines\renewcommand{\ticklength}{4pt}} % {\thinlines\renewcommand{\ticklength}{8pt}} % \end{verbatim} % \tickstyle{\thinlines\renewcommand{\ticklength}{4pt}} % {\thinlines\renewcommand{\ticklength}{8pt}} % \begin{picture}(200,20)(-75,-15) % \numbline{-75}{125} % \end{picture} % \end{quote} % Note that the \emph{command} "\ticklength" must be changed with % "\renewcommand". % % If you prefer tick marks\index{ticks>style of|usage} % just on the outside of the coordinate axes, load % \textsf{coordsys} with the \textsf{outside} option. % \begin{quote} % \begin{verbatim} % \usepackage[outside]{coordsys} % \end{verbatim} % \makeatletter % \renewcommand{\vtickmark}{\makebox(0,0)[t]{\rule{\@wholewidth}{3pt}}} % \renewcommand{\htickmark}{\makebox(0,0)[r]{\rule{3pt}{\@wholewidth}}} % \makeatother % \begin{picture}(200,110)(-50,-50) % \coordsys(-50,-50)(150,60) % \end{picture} % \end{quote} % % Similarly, the \textsf{inside} option puts the tick marks on the inside of % the axes. The default option is \textsf{centred}. % % % % \section{Logarithmic Coordinate Systems} % Load the \textsf{logsys} package with the "\usepackage" command. % \begin{quote} % "\usepackage"\oarg{options}"{coordsys,logsys}" % \end{quote} % The \textsf{logsys} package supports the same options, \textsf{centred}, % \textsf{outside}, and \textsf{inside}, as the \textsf{coordsys} package. % % \subsection{One Dimension} % \DescribeMacro{\logline} % The "\logline" command typesets a horizontal, logarithmic number % line.\index{number line>logarithmic|(usage} % \begin{quote} % \begin{verbatim} % \logline{-60}{210} % \end{verbatim} % \begin{picture}(270,20)(-60,-15) % \logline{-60}{210} % \end{picture} % \end{quote} % The "\logline" command typesets only whole blocks of tick marks % (whole powers of $10$). % Making the axis long enough that the tick marks do not % collide with the arrow and yet not so long that it looks ridiculous is the % users responsibility. % The default distance between the thick tick marks (the powers of $10$) is % 50~units. % Therefore I made the axis above extend from $-60$ (a bit below $-50$ which % appears as $10^{-1} = \frac1{10}$) to $210$ (a bit above $200$ which appears % as $10^4$). % % \DescribeMacro{\logline*} % Thus,\label{loglinesyntax} % \begin{quote} % "\logline"\oarg{spacing}\marg{from}\marg{to}\\ % "\logline*"\oarg{spacing}\marg{from}\marg{to} % \end{quote} % typeset horizontal, logarithmic number lines from \meta{from} to % \meta{to} with \meta{spacing} units between the powers of $10$; the default % is 50. % The starred version omits the labels. % All the arguments must be integers. % % The "\logline" command only typesets an axis; it does not change the % way \LaTeX\ and the \textsf{picture} environment interprets coordinates. % The equation below gives the relationship between the coordinate to % "\put", $x_p$, and the apparent coordinate, % $x_a$.\index{labels>logarithmic|usage} % \[ % x_p = \meta{spacing} \log_{10} x_a. % \] % For example: % \begin{quote} % \begin{verbatim} % \logline[40]{-50}{210} % \put(87.04,10){\makebox(0,0)[b]{150}} % 40*log(150) = 87.04 % \put(87.04,10){\vector(0,-1){10}} % \end{verbatim} % \begin{picture}(260, 40)(-50,-15) % \logline[40]{-50}{210} % \put(87.04,10){\makebox(0,0)[b]{150}} ^^A% 40*log(150) = 87.04 % \put(87.04,10){\vector(0,-1){10}} % \end{picture} % \end{quote} % % \DescribeMacro{\vlogline} % \DescribeMacro{\vlogline*} % The vertical equivalent is "\vlogline": % \begin{quote} % "\vlogline"\oarg{spacing}\marg{from}\marg{to}\\ % "\vlogline*"\oarg{spacing}\marg{from}\marg{to} % \end{quote} % The syntax is similar to that of the "\logline" command % \vpageref[above]{loglinesyntax}.\index{number line>logarithmic|)usage} % % % \subsection{Two Dimensions} % \DescribeMacro{\logsys} % Use the "\logsys"\index{coordinate system>logarithmic|(usage} % command to typeset logarithmic coordinate systems. % \begin{quote} % \begin{picture}(220,125)(-70,-65) % \logsys[5](-50,-50)(150,60) % \put(55,25){\texttt{\textbackslash logsys[5](-50,-50)(150,60)}} % \end{picture} % \end{quote} % \DescribeMacro{\logsys*} % Thus, % \begin{quote} % "\logsys"\oarg{h-spacing}\oarg{v-spacing}\parg{ll}\parg{ur}\\ % "\logsys*"\oarg{h-spacing}\oarg{v-spacing}\parg{ll}\parg{ur} % \end{quote} % typeset coordinate systems with logarithmic vertical axis, % where \parg{ll} is the lower-left corner % and \parg{ur} is the upper-right corner. % The optional argument \meta{h-spacing} gives the spacing between the % tick marks on the horizontal axis; the default is 10 units. % The optional argument \meta{v-spacing} gives the spacing between the % thick tick marks (powers of $10$) on the vertical axis; % the default is 50 units. % The starred version omits the labels. % All the arguments must be integers. % % \DescribeMacro{\semilogsys} % Use the "\semilogsys" command to typeset semi-logarithmic % coordinate systems. % \begin{quote} % \begin{picture}(230,125)(-70,-65) % \semilogsys[25](-50,-50)(160,60) % \put(55,25){\texttt{\textbackslash semilogsys[25](-50,-50)(160,60)}} % \end{picture} % \end{quote} % \DescribeMacro{\semilogsys*} % Thus, % \begin{quote} % "\semilogsys"\oarg{h-spacing}\oarg{v-spacing}\parg{ll}\parg{ur}\\ % "\semilogsys*"\oarg{h-spacing}\oarg{v-spacing}\parg{ll}\parg{ur} % \end{quote} % typeset coordinate systems with logarithmic horizontal axis, % where \parg{ll} is the lower-left corner % and \parg{ur} is the upper-right corner. % The optional argument \meta{h-spacing} gives the spacing between the % thick tick marks (powers of $10$) on the horizontal axis; % the default is 50 units. % The optional argument \meta{v-spacing} gives the spacing between the % tick marks on the vertical axis; % the default is 10 units. % The starred version omits the labels. % All the arguments must be integers. % % \DescribeMacro{\loglogsys} % Use the "\loglogsys" command to typeset double-logarithmic % coordinate systems. % \begin{quote} % \begin{picture}(230,125)(-70,-65) % \loglogsys(-50,-50)(160,60) % \put(55,25){\texttt{\textbackslash loglogsys(-50,-50)(150,60)}} % \end{picture} % \end{quote} % \DescribeMacro{\loglogsys*} % Thus, % \begin{quote} % "\loglogsys"\oarg{h-spacing}\oarg{v-spacing}\parg{ll}\parg{ur}\\ % "\loglogsys*"\oarg{h-spacing}\oarg{v-spacing}\parg{ll}\parg{ur} % \end{quote} % typeset coordinate systems with two logarithmic axes, % where \parg{ll} is the lower-left corner % and \parg{ur} is the upper-right corner. % The optional argument \meta{h-spacing} gives the spacing between the % thick tick marks (powers of $10$) on the horizontal axis; % the default is 50 units. % The optional argument \meta{v-spacing} gives the spacing between the % thick tick marks (powers of $10$) on the vertical axis; % the default is 50 units. % The starred version omits the labels. % All the arguments must be % integers.\index{coordinate system>logarithmic|)usage} % % \DescribeMacro{\loggrid} % \DescribeMacro{\loggrid*} % \DescribeMacro{\semiloggrid} % \DescribeMacro{\semiloggrid*} % \DescribeMacro{\logloggrid} % \DescribeMacro{\logloggrid*} % The "\loggrid",\index{grid>logarithmic|(usage} % "\loggrid*", "\semiloggrid", % "\semiloggrid*", "\logloggrid", and "\logloggrid*" commands % typeset logarithmic grids. % \begin{quote} % \begin{verbatim} % \logloggrid*(0,0)(300,100) % \end{verbatim} % \begin{picture}(300, 100) % \logloggrid*(0,0)(300,100) % \end{picture} % \end{quote} % Thus, % \begin{quote} % "\loggrid"\oarg{h-spacing}\oarg{v-spacing}\parg{ll}\parg{ur}\\ % "\loggrid*"\oarg{h-spacing}\oarg{v-spacing}\parg{ll}\parg{ur}\\ % "\semiloggrid"\oarg{h-spacing}\oarg{v-spacing}\parg{ll}\parg{ur}\\ % "\semiloggrid*"\oarg{h-spacing}\oarg{v-spacing}\parg{ll}\parg{ur}\\ % "\logloggrid"\oarg{h-spacing}\oarg{v-spacing}\parg{ll}\parg{ur}\\ % "\logloggrid*"\oarg{h-spacing}\oarg{v-spacing}\parg{ll}\parg{ur} % \end{quote} % typeset logarithmic, semi-logarithmic, and double-logarithmic % coordinate grids where \parg{ll} is the lower-left corner % and \parg{ur} is the upper-right corner. % The optional argument \meta{h-spacing} gives the spacing between the % vertical grid lines and % the optional argument \meta{v-spacing} gives the spacing between the % horizontal grid lines; % The default spacing is 10 units on linear axes and 50 units between the % thick tick marks (the powers of $10$) on logarithmic axes. % The starred versions use solid lines; % the un-starred versions use dotted lines. % All the arguments must be integers.\index{grid>logarithmic|)usage} % % % \section{Filling the Coordinate Systems} % The purpose of the \textsf{coordsys} and \textsf{logsys} packages % is to typeset coordinate systems, so maybe the package should end here. % However, I have had to write a bit of code to help me fill my % coordinate systems, so I'll share that. % % \subsection{Intervals} % \DescribeMacro{\interval} % The "\interval" command takes as argument an interval in standard notation % and draws it on the horizontal coordinate axis or number line. % \begin{quote} % \begin{verbatim} % \numbline{-15}{65} % \interval[-7.5,30) % \end{verbatim} % \begin{picture}(80,15)(-15,-12) % \numbline{-15}{65} % \interval[-7.5,30) % \end{picture} % \end{quote} % The interval can be open, half-open, or closed as in % $(a,b)$, $(a,b]$, $[a,b)$, and $[a,b]$\footnote{The notation % $\left]a,b\right[$ for open (or half-open) intervals is also % supported.} You can specify infinite intervals with "<" or ">". % \begin{quote} % \begin{verbatim} % \numbline{-15}{65} % \interval<-14,30[ % \end{verbatim} % \begin{picture}(80,15)(-15,-12) % \numbline{-15}{65} % \interval<-14,30[ % \end{picture} % \end{quote} % \DescribeMacro{\intervalthickness} % The "\intervalthickness" command sets the thickness of the fat line % that marks the interval. % An optional argument allows you to draw the fat line off centre. % \begin{quote} % \begin{verbatim} % \numbline{-15}{65} % \intervalthickness[0.5pt]{1pt} % \interval[-7.5,30] % \color{red} % \intervalthickness[-0.5pt]{1pt} % \interval(10,55> % \end{verbatim} % \begin{picture}(80,15)(-15,-12) % \numbline{-15}{65} % \intervalthickness[0.5pt]{1pt} % \interval[-7.5,30] % \color{red} % \intervalthickness[-0.5pt]{1pt} % \interval(10,55> % \end{picture} % \end{quote} % \DescribeMacro{\vinterval} % The "\vinterval" command similarly draws intervals on the vertical axis. % \begin{quote} % \begin{verbatim} % \fcoordsys[5](150,50)(350,160) % \interval[200,300] % \vinterval(75,150> % \end{verbatim} % \begin{picture}(220,125)(130,35) % \fcoordsys[5](150,50)(350,160) % \interval[200,300] % \vinterval(75,150> % \end{picture} % \end{quote} % % To sum up: % \begin{quote} % "\interval"\meta{L-delim}\meta{from}","\meta{to}\meta{R-delim}\\ % "\vinterval"\meta{L-delim}\meta{from}","\meta{to}\meta{R-delim}\\ % "\intervalthickness"\oarg{offset}\marg{width} % \end{quote} % Here \meta{L-delim} must be one of "[", "(", "<", or "]", and % \meta{R-delim} must be one of "]", ")", ">", or "[". % Both \meta{from} and \meta{to} are numbers, integers or % decimals\footnote{Due to implementation details, a decimal % must have at least one digit on either side of the decimal point. % Thus \texttt{0.5} is ok but \texttt{.5} is not.} % Both \meta{offset} and \meta{width} must be lengths. % The centre of the fat interval line will drawn \meta{offset} above the % horizontal axis or \meta{offset} to the right of the vertical axis. % % % \subsection{Curves} % For plotting curves\index{curves|(usage} % I recommend the \textsf{epic} and % \textsf{eepic} packages.\footnote{Both are old \LaTeX209 packages that work % fine in \LaTeXe. The \textsf{eepic} package re-implements the \textsf{epic} % package making use of \textsc{PostScript}. The \textsf{eepic} package % works well with dvips and dvipdfm but not with pdf\LaTeX.} % I especially like \textsf{(e)epic}'s "\putfile" command which allows % you to calculate your plot with some external program, export the points to % plot to a text file, and import that file to have \LaTeX\ draw the plot. % For external program I use Maple.\index{curves>with Maple|usage} % The \textsf{coordsys} package includes a piece of % Maple code that exports a Maple plot in the form "\putfile" expects. % You can therefore take advantage of Maple adaptive plotting % algorithm\footnote{Maple cleverly calculates more points where the curve % wiggles.} in your \LaTeX\ plots. % % Here is how it works:\index{putfile|usage} % In Maple, read in the file \url{putfile} which is part of the % \textsf{coordsys} package. % \begin{verbatim} % > read "/where/you/placed/putfile"; % \end{verbatim} % Make your plot, here $y=\frac{x^2}{10}$. % \begin{verbatim} % > plot( x^2/10, x=-10..10, title="x^2/10"); % \end{verbatim} % When you are happy with your plot, assign it to a variable. % \begin{verbatim} % > P := %: % \end{verbatim} % Then use the "putfile" command to export the curve to the file % \url{parabola.put}. % \begin{verbatim} % > putfile( "parabola.put", P ); % \end{verbatim} % % In \LaTeX, use the "\putfile" command to put "\picsquare"s at each % point listed in \url{parabola.put}. % \begin{quote} % \begin{verbatim} % \coordsys[1](-10,0)(11,11) % \putfile{parabola.put}{\picsquare} % \end{verbatim} % \ifx\putfile\undefined % You do not have the \textsf{epic} and \textsf{eepic} packages, % so \LaTeX\ cannot generate the result of the above commands. % \else % \setlength{\unitlength}{7pt} % \begin{picture}(21,13)(-10,-2) % \coordsys[1](-10,0)(11,11) % \putfile{parabola.put}{\picsquare} % \end{picture} % \fi % \end{quote} % % The \textsf{(e)epic} package provides an environment, % \textsf{drawjoin}, that joins all points set with the % special "\put" command "\jput". % Thus, to draw a curve with the "\putfile" command you enter a % \textsf{drawjoin} environment, let "\put" be a synonym for % "\jput", and call "\putfile". % \begin{quote} % \begin{verbatim} % \coordsys[1](-10,0)(11,11) % \begin{drawjoin} % \let\put=\jput % \putfile{parabola.put}{\picsquare} % \end{drawjoin} % \end{verbatim} % \ifx\putfile\undefined % You do not have the \textsf{epic} and \textsf{eepic} packages, % so \LaTeX\ cannot generate the result of the above commands. % \else % \setlength{\unitlength}{7pt} % \begin{picture}(21,13)(-10,-2) % \coordsys[1](-10,0)(11,11) % \begin{drawjoin} % \let\put=\jput % \putfile{parabola.put}{\picsquare} % \end{drawjoin} % \end{picture} % \fi % \end{quote} % % To draw a curve that requires (or looks best with) different scales on % the two axes, you can use the "scale" option to % "putfile"\index{curves>scaled|(usage}\index{putfile>scale|(usage} % in Maple: % \begin{verbatim} % > plot( (x+2)*(x-1)*(x-2), x=-3..4 ); % > putfile( "cubic.put", %, scale=[10, 1] ); % \end{verbatim} % Now all the $x$-coordinates in "cubic.put" are $10$ times larger % than they should be. Thus re-scale the horizontal labels % by~$\frac{1}{10}$.\index{labels>re-scaled|(usage}\index{scaling labels|(usage} % \begin{quote} % \begin{verbatim} % \rescaleby{1}{10}{\hlabel} % \coordsys[2](-30,-20)(40,36) % \begin{drawjoin} % \let\put=\jput % \putfile{cubic.put}{\picsquare} % \end{drawjoin} % \end{verbatim} % \ifx\putfile\undefined % You do not have the \textsf{epic} and \textsf{eepic} packages, % so \LaTeX\ cannot generate the result of the above commands. % \else % \setlength{\unitlength}{2.3pt} % \begin{picture}(70,56)(-30,-20) % \rescaleby{1}{10}{\hlabel} % \coordsys[2](-30,-20)(40,36) % \begin{drawjoin} % \let\put=\jput % \putfile{cubic.put}{\picsquare} % \end{drawjoin} % \end{picture} % \fi % \end{quote} % % Scaling can be necessary even when the two axes do use the same % scale. Consider the graph of $r=1+\sin\theta$ in polar coordinates. The % graph is $2.6$ units wide and $2.25$ units tall. All the arguments to the % "\coordsys" command must be integers, so the smallest distance between % tick marks is $1$ unit; the coordinate system will have very few tick marks. % Instead scale up by, say, a factor $100$. % In Maple: % \begin{verbatim} % > polarplot( 1+sin(theta), theta=0..2*Pi ); % > putfile( "cardioid.put", %, scale=[100,100] ); % \end{verbatim} % In \LaTeX: % \begin{quote} % \begin{verbatim} % \rescaleby{1}{100}{\hlabel} % \rescaleby{1}{100}{\vlabel} % \coordsys(-130,-25)(130,215) % \begin{drawjoin} % \let\put=\jput % \putfile{cardioid.put}{\picsquare} % \end{drawjoin} % \end{verbatim} % \ifx\putfile\undefined % You do not have the \textsf{epic} and \textsf{eepic} packages, % so \LaTeX\ cannot generate the result of the above commands. % \else % \setlength{\unitlength}{0.5pt} % \begin{picture}(260,240)(-130,-25) % \rescaleby{1}{100}{\hlabel} % \rescaleby{1}{100}{\vlabel} % \coordsys(-130,-25)(130,215) % \begin{drawjoin} % \let\put=\jput % \putfile{cardioid.put}{\picsquare} % \end{drawjoin} % \end{picture} % \fi % \end{quote} % % If the plot contains more than one curve, % "putfile"\index{putfile>multiple curves|usage} generates % one file for each. You can of course specify multiple curves % directly, but they can also be the result of the "discont" % option to "plot". % \begin{verbatim} % > plot( csc(x), x=0..2*Pi, y=-10..10, discont=true ); % > putfile( "csc.put", %, scale=[180/Pi, 10] ); % \end{verbatim} % Here "putfile" wrote two files calling them "csc1.put" % and "csc2.put". These two curves must be drawn by different % \textsf{drawjoin} environments. % \begin{quote} % \begin{verbatim} % \renewcommand{\hthickratio}{3} % \rescaleby[\pi]{1}{180}{\hlabel} % \rescaleby{1}{10}{\vlabel} % \coordsys(0,-100)(360,115) % \begin{drawjoin} % \let\put=\jput % \putfile{csc1.put}{\picsquare} % \end{drawjoin} % \begin{drawjoin} % \let\put=\jput % \putfile{csc2.put}{\picsquare} % \end{drawjoin} % \end{verbatim} % \ifx\putfile\undefined % You do not have the \textsf{epic} and \textsf{eepic} packages, % so \LaTeX\ cannot generate the result of the above commands. % \else % \setlength{\unitlength}{0.5pt} % \begin{picture}(400,215)(-40,-100) % \renewcommand{\hthickratio}{3} % \rescaleby[\pi]{1}{180}{\hlabel} % \rescaleby{1}{10}{\vlabel} % \coordsys(0,-100)(360,115) % \begin{drawjoin} % \let\put=\jput % \putfile{csc1.put}{\picsquare} % \end{drawjoin} % \begin{drawjoin} % \let\put=\jput % \putfile{csc2.put}{\picsquare} % \end{drawjoin} % \end{picture} % \fi % \end{quote} % % For logarithmic plots % scaling\index{curves>logarithmic|usage}\index{scaling labels>logarithmic|usage} % is almost always necessary. % Consider the % graph of $y=\frac{1}{1+e^{-x}}$ for $x$ running from $-10$ to $10$. % The $y$-coordinates extend over five powers of $10$, so scale by $4$ % to make it comparable to the range of $x$-coordinates. % \begin{verbatim} % > logplot(1/(1+exp(-x)), x=-10..10); % > putfile("logistic.put", %, scale=[1,4]); % \end{verbatim} % The "\rescaleby" command is not suitable for logarithmic axes. % Instead set the optional \meta{spacing} argument to the correct % distance between the powers of~$10$, in this case~$4$. % \begin{quote} % \begin{verbatim} % \logsys[1][4](-10,-20)(11,1) % \begin{drawjoin} % \let\put=\jput % \putfile{logistic.put}{\picsquare} % \end{drawjoin} % \end{verbatim} % \ifx\putfile\undefined % You do not have the \textsf{epic} and \textsf{eepic} packages, % so \LaTeX\ cannot generate the result of the above commands. % \else % \setlength{\unitlength}{7pt} % \begin{picture}(25,23)(-14,-22) % \definecolor{gray}{gray}{0.5} % \definecolor{lightgray}{gray}{0.75} % \gridstyle{\linethickness{0.12pt}\color{lightgray}}% % {\linethickness{0.12pt}\color{gray}} % \loggrid*[1][4](-10,-20)(11,1) % \logsys[1][4](-10,-20)(11,1) % \color{red} % \begin{drawjoin} % \let\put=\jput % \putfile{logistic.put}{\picsquare} % \end{drawjoin} % \end{picture} % \fi % \end{quote} % \index{curves>scaled|)usage}\index{putfile>scale|)usage}% % \index{labels>re-scaled|)usage}\index{scaling labels|)usage} % % Use the "putfile" command as follows:\index{putfile>syntax|usage} % \begin{quote} % "putfile(" \meta{filename}"," \meta{PLOT structure} ["," % \meta{options} ] ");" % \end{quote} % If \meta{filename} is a string and the \meta{PLOT structure} contains % more than one curve, "putfile" will append $1, 2, 3, \dots$ as needed; % "putfile" also appends an extension of ".tex" if the \meta{filename} % has no extension. % If the \meta{filename} is a list or set of filenames, they are used % as is. (So if you do not want "putfile" to meddle with your filename, % give it in a set.) % % The only possible option is\index{putfile>scale|(usage} % \begin{quote} % "scale" "=" "[" \meta{number}"," \meta{number} "]" % \end{quote} % The "putfile" command will multiply all $x$-coordinates by the first % number and all $y$-coordinates by the second number. % Both numbers must be "evalf"able. % % If you scale the coordinates of a curve, you must % of course compensate for that to get an honest % representation of your data in \LaTeX. % \begin{itemize} % \item If you scale a regular (linear) axis by, say, % "scale=[3/5,1]", you should use "\rescaleby{5}{3}{\hlabels}" % to re-scale the labels. % % \item If you scale a logarithmic axis by, say, "scale=[1,30]" % you should use the optional \meta{spacing} argument to % the command that draws the coordinate system, say % "\logsys[30]("\dots % \end{itemize}\index{putfile>scale|)usage}\index{curves|)usage} % % % \section{Installation} % Extract\index{installation|usage} the \url{.sty} files from % the \url{.dtx} file by running \url:coordsys.ins: through \LaTeX. % Then generate the documentation for the \textsf{coordsys} and % \textsf{logsys} packages % by running the file \url:coordsys.dtx: through % \LaTeX---thrice to resolve cross references.\footnote{If you want an index, % you must run MakeIndex % (\texttt{makeindex -s gind.ist coordsys}) between the second and third % \LaTeX{} run.} % % You now have to decide what to do with several files. % \begin{itemize} % \item Move the files \url:coordsys.sty: and \url:logsys.sty: to some % directory where \LaTeX\ can find it; % \url:(local)texmf/tex/latex/misc: would be % the natural choice. % \item Move the documentation, \url:coordsys.dvi: or \url:coordsys.pdf:, to % \url:(local)texmf/doc/latex/misc:. % \item You may discard the source files, \url:coordsys.dtx: and % \url:coordsys.ins:, or store them in % \url:(local)texmf/source/latex/misc:. % \item If you ran \url{coordsys.dtx} through \LaTeX, several \url{.put} % were created. You can discard those. % \end{itemize} % % % % \section{License}\label{sec:license} % This program may be distributed and/or modified under the % conditions of the \LaTeX\ Project Public License, either version 1.3 % of this license or (at your option) any later version. % The latest version of this license is in % \url;http://www.latex-project.org/lppl.txt; % and version 1.2 or later is part of all distributions of \LaTeX \ % version 2003/12/01 or later. % % This program consists of the files \url:coordsys.dtx: and % \url:coordsys.ins:. % % % \section{Acknowledgements} % Thank you to Scott Pakin % for his input on the implementation of Euclid's % algorithm. % % Thank you to Svend Daugaard Pedersen % for catching an error in the logarithmic systems % and for suggestions that led to "\gridstyle". % % Thank you to Staffan Lundberg % who found an error in my understanding % of Maple's structured types and thus prompted me to polish the % Maple code for "putfile". % % Thank you to Jan Hegewald % whose questions led to an improved description and implementation % of "\rescaleby". % % % \StopEventually{ % \PrintIndex % } % % \section{Implementation} % % \subsection{The \textsf{coordsys} Package} % \subsubsection{Identification} % First we must declare ourselves. % \begin{macrocode} %<*coordsys> \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{coordsys}[2006/02/03 version 1.4] % \end{macrocode} % % \subsubsection{Declaration of Options} % \begin{macro}{\ticklength} % \begin{macro}{\vtickmark} % \begin{macro}{\htickmark} % The options define "\ticklength", "vtickmark", and % "\htickmark". First check that these three commands are not defined % elsewhere. % \begin{macrocode} \newcommand{\ticklength}{\relax} \newcommand{\vtickmark}{\relax} \newcommand{\htickmark}{\relax} % \end{macrocode} % The "\vtickmark" and "\htickmark" commands set the individual % ticks; "\vtickmark" sets vertical ticks on a horizontal axis, % and "\htickmark" sets horizontal ticks on a vertical axis. % "\@wholewidth" is the current line width, % that is, the width of "\thinlines" or "\thicklines". % \begin{macrocode} \DeclareOption{centred}{% \def\vtickmark{\makebox(0,0){\rule{\@wholewidth}{\ticklength}}}% \def\htickmark{\makebox(0,0){\rule{\ticklength}{\@wholewidth}}}% \def\ticklength{6\p@}% } \DeclareOption{outside}{% \def\vtickmark{\makebox(0,0)[t]{\rule{\@wholewidth}{\ticklength}}}% \def\htickmark{\makebox(0,0)[r]{\rule{\ticklength}{\@wholewidth}}}% \def\ticklength{3\p@}% } \DeclareOption{inside}{% \def\vtickmark{\makebox(0,0)[b]{\rule{\@wholewidth}{\ticklength}}}% \def\htickmark{\makebox(0,0)[l]{\rule{\ticklength}{\@wholewidth}}}% \def\ticklength{3\p@}% } % \end{macrocode} % \end{macro}\end{macro}\end{macro} % % \subsubsection{Execution of Options} % The default option is \textsf{centred}. % \begin{macrocode} \ExecuteOptions{centred} \ProcessOptions % \end{macrocode} % % \subsubsection{Main Code} % \begin{macro}{\vgridfromto} % \begin{macro}{\hgridfromto} % The "\vgridfromto" and "\hgridfromto" commands typeset vertical % and horizontal dotted lines for the dotted coordinate grids. % \begin{quote} % "\vgridfromto"\marg{from}\marg{to}\\ % "\hgridfromto"\marg{from}\marg{to} % \end{quote} % The dotted line is to run from ($y$- or $x$-coordinate) \meta{from} to ($y$- % or $x$-coordinate) \meta{to}. The two commands set the lines by means of % leaders in a box. The box is set at $y$- or $x$-coordinate zero and the % leaders extend to the right length by skipping back and forth. This way the % dots line up nicely in a predictable manner. When "\vgridfromto" or % "\hgridfromto" is called, "\coordsys@w" should contain the size % (height or width) of the box containing each dot. % \begin{macrocode} \newcommand{\vgridfromto}[2]{% \vbox to \z@{\vskip -#2\unitlength \leaders\vbox to \coordsys@w{\vss\hbox{\picsquare}\vss} \vfill \vskip #1\unitlength}} \newcommand{\hgridfromto}[2]{% \hbox to \z@{\hskip #1\unitlength \leaders\hbox to \coordsys@w{\hss\picsquare\hss}\hfill \hskip-#2\unitlength}} % \end{macrocode} % \end{macro}\end{macro} % \begin{macro}{\vgridlength} % \begin{macro}{\hgridlength} % The "\vgriglength" and "\hgridlength" command typesets % solid vertical and horizontal lines. % \begin{quote} % "\vgridlength"\marg{length}\\ % "\hgridlength"\marg{length} % \end{quote} % The line is to have length \meta{length} and is set at the left-hand or % bottom edge of the coordinate system. % \begin{macrocode} \newcommand{\vgridlength}[1]{\line(0,1){#1}} \newcommand{\hgridlength}[1]{\line(1,0){#1}} % \end{macrocode} % \end{macro}\end{macro} % % \begin{macro}{\setvlabel} % \begin{macro}{\sethlabel} % The "\setvlabel" and "\sethlabel" commands typeset the labels on % the vertical and horizontal axes, respectively. % The "\setvlabel" command sets 5\,pt of space between the label and the % axis, which is about right, considering that the tick marks extend 3\,pt on % either side of the axis. % The "\sethlabel" command places the labels on a baseline 3\,pt plus % the current "\baselineskip" below the axis by means of a strut (a % zero-width rule).\nextlinelabel{cl:setlabels} % \begin{macrocode} \@ifpackageloaded{color}{% \newcommand{\setvlabel}[2][r]{% \makebox(0,0)[#1]{\colorbox{white}{$#2$}\hspace{5pt}}} \newcommand{\sethlabel}[2][t]{% \makebox(0,0)[#1]{% \setlength{\@tempdimc}{3pt}% \addtolength{\@tempdimc}{\baselineskip}% \rule{0pt}{\@tempdimc}\colorbox{white}{$#2$}}}% }{% no colour \newcommand{\setvlabel}[2][r]{% \makebox(0,0)[#1]{$#2$\hspace{5\p@}}} \newcommand{\sethlabel}[2][t]{% \makebox(0,0)[#1]{% \setlength{\@tempdimc}{3\p@}% \addtolength{\@tempdimc}{\baselineskip}% \rule{\z@}{\@tempdimc}$#2$}}% }% end if color package % \end{macrocode} % You may want to redefine "\setvlabel" and "\sethlabel" to present % the labels in a different way---use a smaller font, increase the distance to % the axes,\dots. Your redefined commands must take one optional and one % mandatory argument---the "\window" command uses the optional argument. % Do not assume that the mandatory argument is always a number---the % "\window" command uses "\setvlabel" and "\sethlabel" to % typeset the min\slash max labels. % \end{macro}\end{macro} % % \begin{macro}{\hlabel} % \begin{macro}{\vlabel} % The "\hlabel" and "\vlabel" commands calculate the labels that % "\setvlabel" and "\sethlabel" typeset. The default definitions % of "\hlabel" and "\vlabel" do nothing, but you can redefine them % with the "\rescaleby" command. % \begin{macrocode} \newcommand{\hlabel}[1]{#1}% \newcommand{\vlabel}[1]{#1}% % \end{macrocode} % \end{macro}\end{macro} % % \begin{macro}{\rescaleby} % The "\rescaleby" command redefines it's fourth argument % (the third mandatory argument) % which should be either "\hlabel" or "\vlabel". % After % \begin{quote} % "\rescaleby"\oarg{symb}\marg{num}\marg{den}"{\hlabel}" % \end{quote} % the result of "\hlabel"\marg{x} should be % $\frac{\meta{num}\times \meta{x}}{\meta{den}} \meta{symb}$. % \begin{macrocode} \newcommand{\rescaleby}[4][]{\renewcommand{#4}[1]{{% \count@=##1\relax \ifnum\count@=0\relax \@tempcntb=1\relax \else \multiply\count@ #2\relax \ifnum\count@<0\count@=-\count@\fi \@EuclidGCD{\count@}{#3}% \count@=##1\relax \multiply\count@ #2\relax \divide\count@\@tempcnta \@tempcntb=#3\relax \divide\@tempcntb\@tempcnta \fi % \end{macrocode} % We have reduced the fraction. Now print it nicely. % \begin{macrocode} \ifnum\count@<0\relax -% \count@=-\count@ \fi \def\coordsys@a{#1}% \ifx\coordsys@a\@empty\relax \ifnum\@tempcntb=1\relax \the\count@ \else \frac{\the\count@}{\the\@tempcntb}% \fi \else \ifnum\@tempcntb=1\relax \ifnum\count@=1\relax \coordsys@a \else \the\count@\coordsys@a \fi \else \ifnum\count@=1\relax \frac{\coordsys@a}{\the\@tempcntb}% \else \frac{\the\count@}{\the\@tempcntb}\coordsys@a \fi \fi \fi }}} % \end{macrocode} % \end{macro} % % \begin{macro}{\hthickratio} % \begin{macro}{\vthickratio} % By default every fifth tick mark is thick. % \begin{macrocode} \newcommand{\hthickratio}{5} \newcommand{\vthickratio}{5} % \end{macrocode} % \end{macro}\end{macro} % % \begin{macro}{\text} % Hopefully the \textsf{amstext} package will override this very simple % "\text" command intended for subscripts only. % \begin{macrocode} \providecommand{\text}[1]{\mbox{\scriptsize #1}} % \end{macrocode} % \end{macro} % \begin{macro}{\picsquare} % The "\picsquare" command typesets a square of size the current line % width---as in the \textsf{epic} package. % \begin{macrocode} \providecommand{\picsquare}{% \makebox(0,0){\rule{\@wholewidth}{\@wholewidth}}} % \end{macrocode} % \end{macro} % % \begin{macro}{\count@} % \begin{macro}{\c@@coord} % \begin{macro}{\@tenpcnta} % \begin{macro}{\@tenpcntb} % \begin{macro}{\if@numbline} % We need three counters. \LaTeX\ inherits one, "\count@", from plain % \TeX\ and defines two more, "\@tempcnta" and "\@tempcntb". % We create a \LaTeX\ counter, "@coord",\nextlinelabel{cl:@coord} without % allocating a new counter % by making "\c@@coord" a synonym for "\count@"\footnote{I don't % quite understand why I bother do that; I copied the idea from Lamport's % \textsf{graphpap} package, which is where the \textsf{coordsys} package % began.} % The "\if" controls whether to set labels. % \begin{macrocode} \let\c@@coord\count@ \newif\if@numbline % \end{macrocode} % \end{macro}\end{macro}\end{macro}\end{macro}\end{macro} % % \begin{macro}{\tickstyle} % \begin{macro}{\thin@ticks} % \begin{macro}{\thick@ticks} % The commands "\thin@ticks" and "\thick@ticks" store the style of % the tick marks. The "\tickstyle" command defines those two. The % default is "\thinlines" for the thin tick marks and "\thicklines" % for the thick tick marks. % \begin{macrocode} \newcommand{\tickstyle}[2]{% \def\thin@ticks{#1}% \def\thick@ticks{#2}} \tickstyle{\thinlines}{\thicklines} % \end{macrocode} % \end{macro}\end{macro}\end{macro} % % \begin{macro}{\@set@ticks} % The "\@set@ticks" command calculates the positions of the % tick marks. % \begin{quote} % "\@set@ticks"\marg{thickratio}\marg{spacing}^^A % \marg{from}\marg{to}\marg{tickfree}\marg{cmd} % \end{quote} % \begin{macro}{\coordsys@a} % \begin{macro}{\coordsys@b} % \begin{macro}{\coordsys@c} % The "\@set@ticks" command calculates three parameters: % "\coordsys@a" is the position of the first tick; % "\coordsys@b" is the number of ticks to set; and % "\coordsys@c" is the spacing between the ticks (that is, % \meta{spacing} for the thin ticks and $\meta{thickratio}\meta{spacing}$ % for the thick ticks). % \end{macro}\end{macro}\end{macro} % Then "\@set@ticks" calls \meta{cmd} to actually set the ticks using % these parameters.\nextlinelabel{cl:BeginTickCalc} % \begin{macrocode} \newcommand{\@set@ticks}[6]{% \thin@ticks \edef\coordsys@c{#2}% % \end{macrocode} % First we must round \meta{from} up to a multiple of \meta{spacing}. % Knuth's implementation of integer division % always rounds toward zero, % so for negative \meta{from} we can simply divide and multiply % by \meta{spacing}. If \meta{from} is positive, we must play around a % little to round up instead of down. % \begin{macrocode} \@tempcnta=#3\relax \ifnum\@tempcnta>0\advance\@tempcnta -1\relax\fi \divide\@tempcnta \coordsys@c\relax \ifnum #3>0\advance\@tempcnta 1\relax\fi \multiply\@tempcnta \coordsys@c\relax \edef\coordsys@a{\the\@tempcnta}% % \end{macrocode} % Then we must calculate how many ticks to set. % To avoid collision between ticks and arrowheads, % there is to be no ticks in the last \meta{tickfree} length. % \begin{macrocode} \@tempcntb=#4\relax \advance\@tempcntb -\@tempcnta\relax \setlength{\@tempdima}{\@tempcntb\unitlength}% \addtolength{\@tempdima}{-#5}% \ifdim\@tempdima<\z@\relax \def\coordsys@b{0}% \else \divide\@tempdima\unitlength\relax \divide\@tempdima\coordsys@c\relax \@tempcntb=\@tempdima% \advance\@tempcntb 1\relax% \edef\coordsys@b{\the\@tempcntb}% \fi #6% % \end{macrocode} % \nextlinelabel[0]{cl:EndTickCalc} % Then the thick ticks. % This time the spacing is $\meta{thickratio}\meta{spacing}$, so calculate % that number % and store it in "\coordsys@c". % \begin{macrocode} \thick@ticks \@tempcntb=#1\relax \multiply\@tempcntb \coordsys@c\relax \edef\coordsys@c{\the\@tempcntb}% % \end{macrocode} % Calculate the position of the first (thick) tick as above. % \begin{macrocode} \@tempcnta=#3\relax \ifnum\@tempcnta>0\advance\@tempcnta -1\relax\fi \divide\@tempcnta \coordsys@c\relax \ifnum #3>0\advance\@tempcnta 1\relax\fi \multiply\@tempcnta \coordsys@c\relax \edef\coordsys@a{\the\@tempcnta}% % \end{macrocode} % Then calculate the number of \emph{thin} ticks % between the first thick tick ("\@tempcnta") and % \meta{to} less \meta{tickfree}, namely % $\left\lfloor\frac{\meta{to}-\meta{first}-\meta{tickless}}{\meta{spacing}}\right\rfloor+1$. % \begin{macrocode} \@tempcntb=#4\relax \advance\@tempcntb -\@tempcnta\relax \setlength{\@tempdima}{\@tempcntb\unitlength}% \addtolength{\@tempdima}{-#5}% \ifdim\@tempdima<\z@\relax \def\coordsys@b{0}% \else \divide\@tempdima\unitlength\relax \divide\@tempdima#2\relax \@tempcntb=\@tempdima% % \advance\@tempcntb 1\relax % \end{macrocode} % The number of thick ticks is then % $\left\lceil\frac{\meta{number of thin ticks}}{\meta{thickratio}}\right\rceil$. % \begin{macrocode} % \advance\@tempcntb -1\relax \divide\@tempcntb #1\relax \advance\@tempcntb 1\relax \edef\coordsys@b{\the\@tempcntb}% \fi #6% } % \end{macrocode} % \end{macro} % % \begin{macro}{\numbline} % The "\numbline" command checks for a star, % \begin{macrocode} \newcommand{\numbline}{% \@ifstar{\@numblinefalse\hnumbline@i} {\@numblinetrue \hnumbline@i}} % \end{macrocode} % \begin{macro}{\hnumbline@i} % then "\hnumbline@i" picks up the optional argument, % \begin{macrocode} \newcommand{\hnumbline@i}[1][10]{\leavevmode\hnumbline@ii{#1}} % \end{macrocode} % \end{macro} % \begin{macro}{\hnumbline@ii} % and "\hnumbline@ii" does the work: % Calculate the length of the arrow and set it, then call "\@set@ticks" % to set the tick marks. The extra set of braces localizes the % "\tickstyle" declarations. % \begin{macrocode} \newcommand{\hnumbline@ii}[3]{{\color@begingroup \thinlines \@tempcnta=#3\relax \advance\@tempcnta -#2\relax \edef\coordsys@w{\the\@tempcnta}% \put(#2,0){\vector(1,0){\coordsys@w}}% \@set@ticks{\hthickratio}{#1}{#2}{#3}{6\p@}{ \multiput(\coordsys@a,0)(\coordsys@c,0)\coordsys@b\vtickmark}% % \end{macrocode} % Set the labels if we have to. % The parameters "\coordsys@a", "\coordsys@b", and % "\coordsys@c" that "\@set@ticks" calculated for the thick tick % marks are still available. In particular, "\coordsys@a" is the % position and, hence, the value of the first label. % \begin{macrocode} \if@numbline \setcounter{@coord}{\coordsys@a}% \multiput(\coordsys@a,0)(\coordsys@c,0)\coordsys@b{% \edef\coordsys@a{\arabic{@coord}}% \sethlabel{\hlabel{\coordsys@a}}% \addtocounter{@coord}{\coordsys@c}} \fi \color@endgroup}% % \end{macrocode} % Finally store the vertical coordinate of the number line in % "\coordsys@w" for the sake of the "\interval" command. % \begin{macrocode} \def\coordsys@w{0}% } % \end{macrocode} % \end{macro}\end{macro} % % \begin{macro}{\vnumbline} % \begin{macro}{\vnumbline@i} % \begin{macro}{\vnumbline@ii} % The "\vnumbline" command and friends work in much the same way. % \begin{macrocode} \newcommand{\vnumbline}{% \@ifstar{\@numblinefalse\vnumbline@i} {\@numblinetrue \vnumbline@i}} \newcommand{\vnumbline@i}[1][10]{\leavevmode\vnumbline@ii{#1}} \newcommand{\vnumbline@ii}[3]{{\color@begingroup \thinlines \@tempcnta=#3\relax \advance\@tempcnta -#2\relax \edef\coordsys@h{\the\@tempcnta}% \put(0,#2){\vector(0,1){\coordsys@h}}% \@set@ticks{\vthickratio}{#1}{#2}{#3}{6\p@}{% \multiput(0,\coordsys@a)(0,\coordsys@c)\coordsys@b\htickmark}% \if@numbline \setcounter{@coord}{\coordsys@a}% \multiput(0,\coordsys@a)(0,\coordsys@c)\coordsys@b{% \edef\coordsys@a{\arabic{@coord}}% \setvlabel{\vlabel{\coordsys@a}}% \addtocounter{@coord}{\coordsys@c}} \fi \color@endgroup}% \def\coordsys@h{0}% } % \end{macrocode} % \end{macro}\end{macro}\end{macro} % % \begin{macro}{\coordsys} % All the coordinate-system drawing command use similar syntax, so we use a % unified approach for picking up the arguments. % The "\coordsys" command defines the temporary variable % "\coordsys@c" to be the name of the command that does the real work. % Then "\coordsys" checks for the presence of a star. % \begin{macrocode} \newcommand{\coordsys}{% \def\coordsys@c{\coordsys@i}% \@ifstar{\@numblinefalse\coordsys@args@i} {\@numblinetrue \coordsys@args@i}} % \end{macrocode} % \begin{macro}{\coordsys@args@i} % \begin{macro}{\@hticksep} % The "\coordsys@args@i" command picks up the first optional argument % storing it % in "\@hticksep" so that we can use that variable as the default for the % second optional argument. % \begin{macrocode} \newcommand{\coordsys@args@i}[1][10]{\leavevmode \def\@hticksep{#1}% \coordsys@args@ii} % \end{macrocode} % \end{macro}\end{macro} % \begin{macro}{\coordsys@args@ii} % \begin{macro}{\@vticksep} % Then "\coordsys@args@ii" picks up the second optional argument, % \begin{macrocode} \newcommand{\coordsys@args@ii}[1][\@hticksep]{% \def\@vticksep{#1}% \coordsys@args@iii} % \end{macrocode} % \end{macro}\end{macro} % \begin{macro}{\coordsys@args@iii} % and the "\coordsys@args@iii" command picks up the first point and % brutally % replaces whatever the following may be with a "(". Since \TeX\ ignores % spaces when looking for an argument, this allows the user to leave a space % between the first and the second point. % \begin{macrocode} \def\coordsys@args@iii(#1,#2)#3{\coordsys@c{#1}{#2}(} % \end{macrocode} % \end{macro} % \begin{macro}{\coordsys@i} % Finally the real command, "\coordsys@c", that is "\coordsys@i", % picks up the second point (as well as the first), and gets to work: % First calculate the length of each axis and set it. % \begin{macrocode} \def\coordsys@i#1#2(#3,#4){{\color@begingroup \thinlines \@tempcnta=#3\relax \advance\@tempcnta -#1\relax \edef\coordsys@w{\the\@tempcnta}% \put(#1,0){\vector(1,0){\coordsys@w}}% \@tempcnta=#4\relax \advance\@tempcnta -#2\relax \edef\coordsys@h{\the\@tempcnta}% \put(0,#2){\vector(0,1){\coordsys@h}}% % \end{macrocode} % Then set the tick marks on the horizontal axis. % \begin{macrocode} \@set@ticks{\hthickratio}{\@hticksep}{#1}{#3}{6\p@}{% \multiput(\coordsys@a,0)(\coordsys@c,0)\coordsys@b\vtickmark}% % \end{macrocode} % This style of coordinate system has intersecting axes, so we must suppress % the label ``0''. % \begin{macrocode} \if@numbline \setcounter{@coord}{\coordsys@a}% \multiput(\coordsys@a,0)(\coordsys@c,0)\coordsys@b{% \ifnum\value{@coord}=0\relax\else \edef\coordsys@a{\arabic{@coord}}% \sethlabel{\hlabel{\coordsys@a}}% \fi \addtocounter{@coord}{\coordsys@c}}% \fi % \end{macrocode} % Then do the tick marks and labels on the vertical axis. % \begin{macrocode} \@set@ticks{\vthickratio}{\@vticksep}{#2}{#4}{6\p@}{% \multiput(0,\coordsys@a)(0,\coordsys@c)\coordsys@b\htickmark}% \if@numbline \setcounter{@coord}{\coordsys@a}% \multiput(0,\coordsys@a)(0,\coordsys@c)\coordsys@b{% \ifnum\value{@coord}=0\relax\else \edef\coordsys@a{\arabic{@coord}}% \setvlabel{\vlabel{\coordsys@a}}% \fi \addtocounter{@coord}{\coordsys@c}}% \fi \color@endgroup}% % \end{macrocode} % Finally store the location of the axis in "\coordsys@w" and "\coordsys@h" % for the sake of the "\interval" command. % \begin{macrocode} \def\coordsys@w{0}% \def\coordsys@h{0}% } % \end{macrocode} % \end{macro}\end{macro} % % \begin{macro}{\fcoordsys} % \begin{macro}{\fcoordsys@i} % The "\fcoordsys" and "\fcoordsys@i" commands work much like % "\coordsys" and "\coordsys@i" above. % \begin{macrocode} \newcommand{\fcoordsys}{% \def\coordsys@c{\fcoordsys@i}% \@ifstar{\@numblinefalse\coordsys@args@i} {\@numblinetrue \coordsys@args@i}} \def\fcoordsys@i#1#2(#3,#4){{\color@begingroup \thinlines \@tempcnta=#3\relax \advance\@tempcnta -#1\relax \edef\coordsys@w{\the\@tempcnta}% \put(#1,#2){\vector(1,0){\coordsys@w}}% \@tempcnta=#4\relax \advance\@tempcnta -#2\relax \edef\coordsys@h{\the\@tempcnta}% \put(#1,#2){\vector(0,1){\coordsys@h}}% \@set@ticks{\hthickratio}{\@hticksep}{#1}{#3}{6\p@}{% \multiput(\coordsys@a,#2)(\coordsys@c,0)\coordsys@b\vtickmark}% \if@numbline \setcounter{@coord}{\coordsys@a}% \multiput(\coordsys@a,#2)(\coordsys@c,0)\coordsys@b{% \edef\coordsys@a{\arabic{@coord}}% \sethlabel{\hlabel{\coordsys@a}}% \addtocounter{@coord}{\coordsys@c}}% \fi \@set@ticks{\vthickratio}{\@vticksep}{#2}{#4}{6\p@}{% \multiput(#1,\coordsys@a)(0,\coordsys@c)\coordsys@b\htickmark}% \if@numbline \setcounter{@coord}{\coordsys@a}% \multiput(#1,\coordsys@a)(0,\coordsys@c)\coordsys@b{% \edef\coordsys@a{\arabic{@coord}}% \setvlabel{\vlabel{\coordsys@a}}% \addtocounter{@coord}{\coordsys@c}}% \fi \color@endgroup}% \def\coordsys@h{#1}% \def\coordsys@w{#2}% } % \end{macrocode} % \end{macro}\end{macro} % % \begin{macro}{\bcoordsys} % \begin{macro}{\bcoordsys@i} % The "\bcoordsys" and "\bcoordsys@i" commands work much like % "\coordsys" and "\coordsys@i" above. % \begin{macrocode} \newcommand{\bcoordsys}{% \def\coordsys@c{\bcoordsys@i}% \@ifstar{\@numblinefalse\coordsys@args@i} {\@numblinetrue \coordsys@args@i}} \def\bcoordsys@i#1#2(#3,#4){{\color@begingroup \thinlines \@tempcnta=#3\relax \advance\@tempcnta -#1\relax \edef\coordsys@w{\the\@tempcnta}% \put(#1,#2){\line(1,0){\coordsys@w}}% \put(#1,#4){\line(1,0){\coordsys@w}}% \@tempcnta=#4\relax \advance\@tempcnta -#2\relax \edef\coordsys@h{\the\@tempcnta}% \put(#1,#2){\line(0,1){\coordsys@h}}% \put(#3,#2){\line(0,1){\coordsys@h}}% \@set@ticks{\hthickratio}{\@hticksep}{#1}{#3}{\z@}{% \multiput(\coordsys@a,#2)(\coordsys@c,0)\coordsys@b\vtickmark}% \if@numbline \setcounter{@coord}{\coordsys@a}% \multiput(\coordsys@a,#2)(\coordsys@c,0)\coordsys@b{% \edef\coordsys@a{\arabic{@coord}}% \sethlabel{\hlabel{\coordsys@a}}% \addtocounter{@coord}{\coordsys@c}}% \fi \@set@ticks{\vthickratio}{\@vticksep}{#2}{#4}{\z@}{% \multiput(#1,\coordsys@a)(0,\coordsys@c)\coordsys@b\htickmark}% \if@numbline \setcounter{@coord}{\coordsys@a}% \multiput(#1,\coordsys@a)(0,\coordsys@c)\coordsys@b{% \edef\coordsys@a{\arabic{@coord}}% \setvlabel{\vlabel{\coordsys@a}}% \addtocounter{@coord}{\coordsys@c}}% \fi \color@endgroup}% \def\coordsys@h{#1}% \def\coordsys@w{#2}% } % \end{macrocode} % \end{macro}\end{macro} % % \begin{macro}{\window} % \begin{macro}{\window@i} % And yet another modification of the same old thing. % \begin{macrocode} \newcommand{\window}{% \def\coordsys@c{\window@i}% \@ifstar{\let\coordsys@a\phantom\coordsys@args@i} {\let\coordsys@a\relax \coordsys@args@i}} \def\window@i#1#2(#3,#4){{% \thinlines \@tempcnta=#3\relax \advance\@tempcnta-#1\relax \edef\coordsys@w{\the\@tempcnta}% \@tempcnta=#4\relax \advance\@tempcnta-#2\relax \edef\coordsys@h{\the\@tempcnta}% \put(#1,#2){\line(1,0){\coordsys@w}}% \put(#1,#2){\line(0,1){\coordsys@h}}% \put(#3,#4){\line(-1,0){\coordsys@w}}% \put(#3,#4){\line(0,-1){\coordsys@h}}% % \end{macrocode} % Set the labels; "\ensuremath" for the sake of the % subscripts. % \begin{macrocode} \put(#1,#2){\sethlabel[tl]% {\ensuremath{x_{\text{min}}=\coordsys@a{#1}}}}% \put(#3,#2){\sethlabel[tr]% {\ensuremath{x_{\text{max}}=\coordsys@a{#3}}}}% \put(#1,#2){\setvlabel[rb]% {\ensuremath{y_{\text{min}}=\coordsys@a{#2}}}}% \put(#1,#4){\setvlabel[rt]% {\ensuremath{y_{\text{max}}=\coordsys@a{#4}}}}% % \end{macrocode} % If the axes are in the window, typeset them (without labels). % \begin{macrocode} \ifnum #1<0\relax\ifnum #3>0\relax \vnumbline*[\@vticksep]{#2}{#4}% \fi\fi \ifnum #2<0\relax\ifnum #4>0\relax \numbline*[\@hticksep]{#1}{#3}% \fi\fi }% \def\coordsys@h{#1}% \def\coordsys@w{#2}% } % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\gridstyle} % \begin{macro}{\grid@style} % The "\gridstyle" command defines "\grid@style" to issue a suitable % "\tickstyle" command at the proper time. The default % "\grid@style" is to do nothing---that is, use the current % "\tickstyle" unchanged. % \begin{macrocode} \newcommand{\gridstyle}[2]{\def\grid@style{\tickstyle{#1}{#2}}} \newcommand{\grid@style}{\relax} % \end{macrocode} % \end{macro}\end{macro} % % \begin{macro}{\coordgrid} % The "\coordgrid" command chooses between the starred version, % "\coordgrid@ii", with solid lines and the un-starred version, % "\coordgrid@i", with dotted lines. % \begin{macrocode} \newcommand{\coordgrid}{% \@ifstar{\def\coordsys@c{\coordgrid@ii}\coordsys@args@i} {\def\coordsys@c{\coordgrid@i}\coordsys@args@i}} % \end{macrocode} % \begin{macro}{\coordgrid@i} % The "\coordgrid@i" command calls "\coordgrid@calc" to calculate % the size, "\coordsys@w", of the box containing each dot of the dotted % lines based on the values of "\@hticksep" and "\@vticksep". Then % set the dotted lines with "\@set@ticks". % \begin{macrocode} \def\coordgrid@i#1#2(#3,#4){{\color@begingroup \coordgrid@calc \grid@style \@set@ticks{\hthickratio}{\@hticksep}{#1}{#3}{\z@}{% \multiput(\coordsys@a,0)(\coordsys@c,0)\coordsys@b {\vgridfromto{#2}{#4}}}% \@set@ticks{\vthickratio}{\@vticksep}{#2}{#4}{\z@}{% \multiput(0,\coordsys@a)(0,\coordsys@c)\coordsys@b {\hgridfromto{#1}{#3}}}% \color@endgroup}} % \end{macrocode} % \end{macro} % \begin{macro}{\coordgrid@ii} % The "\coordgrid@ii" command is similar to "\fcoordsys@i" above. % \begin{macrocode} \def\coordgrid@ii#1#2(#3,#4){{\color@begingroup \grid@style \@tempcnta=#3\relax \advance\@tempcnta -#1\relax \edef\coordsys@w{\the\@tempcnta}% \@tempcnta=#4\relax \advance\@tempcnta -#2\relax \edef\coordsys@h{\the\@tempcnta}% \@set@ticks{\hthickratio}{\@hticksep}{#1}{#3}{\z@}{% \multiput(\coordsys@a,#2)(\coordsys@c,0)\coordsys@b {\vgridlength{\coordsys@h}}}% \@set@ticks{\vthickratio}{\@vticksep}{#2}{#4}{\z@}{% \multiput(#1,\coordsys@a)(0,\coordsys@c)\coordsys@b {\hgridlength{\coordsys@w}}}% \color@endgroup}} % \end{macrocode} % \end{macro}\end{macro} % % \begin{macro}{\coordgrid@calc} % To typeset pretty grids of dots the number of dots between lines must be an % integer. Thus, the number of dots must be a factor of the greatest common % divisor of "\@vticksep" and "\@hticksep". The "\@EuclidGCD" % command returns the $\gcd$ in the counter "\@tempcnta" % \begin{macrocode} \newcommand{\coordgrid@calc}{% \@EuclidGCD{\@vticksep}{\@hticksep}% \@tempdima=\unitlength \multiply\@tempdima\@tempcnta % \end{macrocode} % Now "\@tempdima" is the longest length that fits an integer number of % times between lines. The dots should not be closer than 2\,pt. % \begin{macrocode} \@tempdimb=2\p@\relax \ifdim\@tempdima<\@tempdimb \PackageWarning{coordsys}{The tick marks are too close\MessageBreak for a pretty grid}% \else % \end{macrocode} % However, "\@tempdima" may be able to contain multiple dots. % \begin{macrocode} \divide\@tempdima \@tempdimb\relax \@tempdimb=\unitlength \multiply\@tempdimb\@tempcnta \divide\@tempdimb\@tempdima \fi % \end{macrocode} % In either case store the box size in "\coordsys@w". % \begin{macrocode} \edef\coordsys@w{\the\@tempdimb}% } % \end{macrocode} % \end{macro} % % \begin{macro}{\interval} % We use "\newcommand" to check that "\interval" is not already defined; % then we need plain \TeX's "\def" because "\interval" picks up its % arguments in a non-standard way. % \begin{macrocode} \newcommand{\interval}{} \def\interval#1#2,{% \def\coordsys@a{#1}% \def\coordsys@b{#2}% \def\coordsys@c{}% % \end{macrocode} % Now "\coordsys@a" is the \meta{L-delim} and "\coordsys@b" is whatever follows % up to the first comma, that is \meta{from}. % Then define "\coordsys@a" to be the correct symbol suitably aligned % in a box. Note that the characters in \LaTeX's circle font are placed % rather peculiarly inside their bounding box. % \begin{macrocode} \if\coordsys@a]\def\coordsys@a{(}\fi \if\coordsys@a[% \def\coordsys@a{% \makebox[0.5\width][l]{\@circlefnt\char'163}}% \else\if\coordsys@a(% \def\coordsys@a{% \makebox[0.5\width][l]{\@circlefnt\char'143}}% \else\if\coordsys@a<% \def\coordsys@a{% \raisebox{-\fontdimen22\textfont2}{% \makebox[\z@]{$<$}}}% \else \PackageError{coordsys} {Bad delimiter} {\string\interval\space expects [, (, <, or ] % but got \coordsys@a}% \def\coordsys@a{}% \fi\fi\fi % \end{macrocode} % Picking up the \meta{from} was easy because we know the % number ends at the comma. But we do not know where the \meta{to} number ends. % \TeX\ knows how to read an integer, so do that and proceed with "\interv@l" % which picks up either the right-hand delimiter or a decimal point as its % first argument. % \begin{macrocode} \afterassignment\interv@l\count@=} % \end{macrocode} % \end{macro} % \begin{macro}{\interv@l} % If we got a decimal point, store the integer part of the number in % "\coordsys@c" and try again. % \begin{macrocode} \newcommand{\interv@l}[1]{% \if#1.% \edef\coordsys@c{\the\count@.}% \def\next{\afterassignment\interv@l\count@=}% % \end{macrocode} % Otherwise, append the number we just read to "\coordsys@c". % Now "\coordsys@c" contains \meta{to}. So calculate the % length (in~pt) of the interval. % \begin{macrocode} \else \edef\coordsys@c{\coordsys@c\the\count@}% \setlength{\@tempdima}{\coordsys@b\unitlength}% \setlength{\@tempdima}{-\@tempdima}% \addtolength{\@tempdima}{\coordsys@c\unitlength}% % \end{macrocode} % Define "\coordsys@c" to be the correct symbol for the \meta{R-delim}. % \begin{macrocode} \def\coordsys@c{#1}% \if\coordsys@c[\def\coordsys@c{)}\fi \if\coordsys@c]% \def\coordsys@c{\mbox{% \@circlefnt \settowidth{\@tempdima}{\char'163}% \hskip 0.5\@tempdima \char'163% \hskip -\@tempdima}% }% \else\if\coordsys@c)% \def\coordsys@c{\mbox{% \@circlefnt \settowidth{\@tempdima}{\char'143}% \hskip 0.5\@tempdima \char'143% \hskip -\@tempdima}% }% \else\if\coordsys@c>% \def\coordsys@c{% \raisebox{-\fontdimen22\textfont2}{% \makebox[\z@]{$>$}}}% \else \PackageError{coordsys} {Bad delimiter} {\string\interval\space expects ], ), <, or [ % but got \coordsys@c}% \def\coordsys@c{}% \fi\fi\fi % \end{macrocode} % \begin{macro}{\coordsys@w}\begin{macro}{\coordsys@h} % Finally, "\put" the pieces down. Here "\coordsys@w" is the vertical % coordinate of the last typeset horizontal axis (usually~$0$), % and "\interval@line" is defined by "\intervalthickness" below. % \begin{macrocode} \put(\coordsys@b,\coordsys@w){\makebox[\@tempdima][s]{% \coordsys@a \interval@line \coordsys@c }}% \let\next=\ignorespaces \fi \next} % \end{macrocode} % \end{macro}\end{macro}\end{macro} % % \begin{macro}{\vinterval} % \begin{macro}{\vinterv@l} % The "\vinterval" and "\vinterv@l" commands work as their horizontal cousins. % \begin{macrocode} \newcommand{\vinterval}{} \def\vinterval#1#2,{% \def\coordsys@a{#1}% \def\coordsys@b{#2}% \def\coordsys@c{}% \if\coordsys@a]\def\coordsys@a{(}\fi \if\coordsys@a[% \def\coordsys@a{\hbox to\z@{% \@circlefnt \settowidth{\@tempdima}{\char'163}% \hskip 0.5\@tempdima minus 1fil \char'163% \hskip -0.5\@tempdima minus 1fil \vrule width \z@ depth \z@ height 0.5\@tempdima }}% \else\if\coordsys@a(% \def\coordsys@a{\hbox to\z@{% \@circlefnt \settowidth{\@tempdima}{\char'143}% \hskip 0.5\@tempdima minus 1fil \char'143% \hskip -0.5\@tempdima minus 1fil \vrule width \z@ depth \z@ height 0.5\@tempdima }}% \else\if\coordsys@a<% \def\coordsys@a{\hbox to\z@{\hss \raisebox{-\fontdimen22\textfont2}[\z@][\z@]{% $\vee$}\hss}}% \else \PackageError{coordsys} {Bad delimiter} {\string\vinterval\space expects [, (, <, or ] % but got \coordsys@a}% \def\coordsys@a{}% \fi\fi\fi \afterassignment\vinterv@l\count@=} \newcommand{\vinterv@l}[1]{% \if#1.% \edef\coordsys@c{\the\count@.}% \def\next{\afterassignment\interv@l\count@=}% \else \edef\coordsys@c{\coordsys@c\the\count@}% \setlength{\@tempdima}{\coordsys@b\unitlength}% \setlength{\@tempdima}{-\@tempdima}% \addtolength{\@tempdima}{\coordsys@c\unitlength}% \def\coordsys@c{#1}% \if\coordsys@c[\def\coordsys@c{)}\fi \if\coordsys@c]% \def\coordsys@c{\hbox to\z@{% \@circlefnt \settowidth{\@tempdima}{\char'163}% \hskip 0.5\@tempdima minus 1fil \char'163% \hskip -0.5\@tempdima minus 1fil \vrule width \z@ depth 0.5\@tempdima height \z@ }}% \else\if\coordsys@c)% \def\coordsys@c{\hbox to\z@{% \@circlefnt \settowidth{\@tempdima}{\char'143}% \hskip 0.5\@tempdima minus 1fil \char'143% \hskip -0.5\@tempdima minus 1fil \vrule width \z@ depth 0.5\@tempdima height \z@ }}% \else\if\coordsys@c>% \def\coordsys@c{\hbox to\z@{\hss% \raisebox{-\fontdimen22\textfont2}[\z@][\z@]{% $\wedge$}\hss}}% \else \PackageError{coordsys} {Bad delimiter} {\string\vinterval\space expects ], ), <, or [ % but got \coordsys@c}% \def\coordsys@c{}% \fi\fi\fi \put(\coordsys@h,\coordsys@b){\vbox{% \setlength{\baselineskip}{\z@}% \setlength{\lineskip}{\z@}% \settoheight{\@tempdimb}{\coordsys@a}% \addtolength{\@tempdima}{-\@tempdimb}% \settodepth {\@tempdimb}{\coordsys@c}% \addtolength{\@tempdima}{-\@tempdimb}% \coordsys@c \vinterval@line \coordsys@a }}% \let\next=\ignorespaces \fi \next} % \end{macrocode} % \end{macro}\end{macro} % % \begin{macro}{\intervalthickness} % \begin{macro}{interval@line}\begin{macro}{\vinterval@line} % The "\intervalthickness" command defines the two commands "\interval@line" % and "\vinterval@line" that draw the thick line indicating the interval. % \begin{macrocode} \newcommand{\intervalthickness}[2][\z@]{% \setlength{\@tempdima}{#2}% \setlength{\@tempdima}{0.5\@tempdima}% \setlength{\@tempdimb}{-\@tempdima}% \addtolength{\@tempdima}{#1}% \addtolength{\@tempdimb}{#1}% \edef\coordsys@a{\the\@tempdima}% \edef\coordsys@b{-\the\@tempdimb}% \edef\interval@line{% \leaders\hrule depth \coordsys@b height \coordsys@a\hss}% \setlength{\@tempdima}{#2}% \setlength{\@tempdima}{-0.5\@tempdima}% \addtolength{\@tempdima}{#1}% \edef\coordsys@a{\the\@tempdima}% \edef\vinterval@line{% \hbox to\z@{% \hskip \coordsys@a \vrule height\@tempdima width #2% \hss }% }% } % \end{macrocode} % \end{macro}\end{macro}\end{macro} % % Then a few defaults for "\interval" and "\vinterval". % \begin{macrocode} \intervalthickness{1.6\p@} \def\coordsys@w{0} \def\coordsys@h{0} % % \end{macrocode} % % \iffalse Don't document this fragment of code. % \begin{macrocode} %<*euclid> \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{euclidgcd}[2006/02/03 version 1.4] \newcommand{\EuclidGCD}[2]{% \@EuclidGCD{#1}{#2}% \the\@tempcnta} % % \end{macrocode} % \fi % % \begin{macro}{\@EuclidGCD} % The "\@EuclidGCD" command calculates the greatest common divisor % of two positive integers using Euclid's algorithm.\footnote{Euclid's % algorithm uses the fact that $\gcd(n, d) = \gcd(d, r)$, where $r$ is % the remainder after dividing $n$ by $d$. Since $r \newcommand{\@EuclidGCD}[2]{% \@tempcnta=#1\relax \@tempcntb=#2\relax \loop \count@=\@tempcntb \divide\count@\@tempcnta \multiply\count@\@tempcnta \advance\count@ -\@tempcntb % \end{macrocode} % Now "\count@" is $-r$, where $r$ is the remainder after dividing % "\@tempcntb" by "\@tempcnta". % \begin{macrocode} \ifnum\count@<0\relax \@tempcntb=\@tempcnta \@tempcnta=-\count@ \repeat } % % \end{macrocode} % \end{macro} % % % \subsection{The \textsf{logsys} Package} % \subsubsection{Identification} % First we must declare ourselves. % \begin{macrocode} %<*logsys> \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{logsys}[2006/02/03 version 1.4] % \end{macrocode} % % \subsubsection{Options} % Pass all options to \textsf{coordsys}. % \begin{macrocode} \DeclareOption{centred}{\PassOptionsToPackage{centred}{coordsys}} \DeclareOption{outside}{\PassOptionsToPackage{outside}{coordsys}} \DeclareOption{inside}{\PassOptionsToPackage{inside}{coordsys}} \ProcessOptions % \end{macrocode} % % \subsubsection{Package Loading} % The \textsf{logsys} package extends the \textsf{coordsys} package. % \begin{macrocode} \RequirePackage{coordsys}[2006/02/03] % \end{macrocode} % % \subsubsection{Main Code} % \begin{macro}{\loglabel} % The "\loglabel" command typesets logarithmic labels. % \begin{macrocode} \newcommand{\loglabel}[1]{% \ifnum #1=-2\relax \frac{1}{100}% \else\ifnum #1=-1\relax \frac{1}{10}% \else\ifnum #1= 0\relax 1% \else\ifnum #1= 1\relax 10% \else\ifnum #1= 2\relax 100% \else 10^{#1}% \fi\fi\fi\fi\fi} % \end{macrocode} % \end{macro} % % \begin{macro}{\v@logbox} % \begin{macro}{\h@logbox} % The "\v@logbox" and "\h@logbox" commands each typeset one block % of logarithmic tick marks. Each take two arguments: the size of a block and % the tick mark to typeset. % The glue in the boxes is (10000 times) $\log10-\log9$, $\log9-\log8$, % $\log8-\log7$, \dots, and $\log2-\log1$. % \begin{macrocode} \newcommand{\v@logbox}[2]{% \vbox to #1\unitlength{% \offinterlineskip \vskip \z@ plus 458fil\relax \vbox to \z@{\vss\hbox{#2}\vss}% 9 \vskip \z@ plus 512fil\relax \vbox to \z@{\vss\hbox{#2}\vss}% 8 \vskip \z@ plus 580fil\relax \vbox to \z@{\vss\hbox{#2}\vss}% 7 \vskip \z@ plus 669fil\relax \vbox to \z@{\vss\hbox{#2}\vss}% 6 \vskip \z@ plus 792fil\relax \vbox to \z@{\vss\hbox{#2}\vss}% 5 \vskip \z@ plus 969fil\relax \vbox to \z@{\vss\hbox{#2}\vss}% 4 \vskip \z@ plus 1249fil\relax \vbox to \z@{\vss\hbox{#2}\vss}% 3 \vskip \z@ plus 1761fil\relax \vbox to \z@{\vss\hbox{#2}\vss}% 2 \vskip \z@ plus 3010fil\relax }} \newcommand{\h@logbox}[2]{% \hbox to #1\unitlength{% \hskip \z@ plus 3010fill\relax \hbox to \z@{\hss #2\hss}% 2 \hskip \z@ plus 1761fill\relax \hbox to \z@{\hss #2\hss}% 3 \hskip \z@ plus 1249fill\relax \hbox to \z@{\hss #2\hss}% 4 \hskip \z@ plus 969fill\relax \hbox to \z@{\hss #2\hss}% 5 \hskip \z@ plus 792fill\relax \hbox to \z@{\hss #2\hss}% 6 \hskip \z@ plus 669fill\relax \hbox to \z@{\hss #2\hss}% 7 \hskip \z@ plus 580fill\relax \hbox to \z@{\hss #2\hss}% 8 \hskip \z@ plus 512fill\relax \hbox to \z@{\hss #2\hss}% 9 \hskip \z@ plus 458fill\relax }} % \end{macrocode} % \end{macro}\end{macro} % % \begin{macro}{\@sethlogticks} % In the linear case we got away with using one command, "\@set@ticks", % to calculate the positions of the tick marks on both horizontal and vertical % axes. The logarithmic case is more complicated, so we create separate % command for the horizontal and vertical case. This split then allows the % logarithmic commands to do more than just calculate the positions of the % ticks: % \begin{quote} % "\@sethlogticks"\marg{spacing}\marg{from}\marg{to}^^A % \marg{y0}\marg{tick} % \end{quote} % \emph{typesets} the logarithmic tick marks on a horizontal axis at % $y$-coordinate \meta{y0}. Moreover, it typesets the labels. % % The calculation is much like the calculation for thin tick marks in the % linear case; compare with code % lines~\ref{cl:BeginTickCalc}--\ref{cl:EndTickCalc}. % \begin{macrocode} \newcommand{\@sethlogticks}[5]{% \thin@ticks \@tempcnta=#2\relax \ifnum\@tempcnta>0\advance\@tempcnta -1\relax\fi \divide\@tempcnta #1\relax \ifnum #2>0\advance\@tempcnta 1\relax\fi \multiply\@tempcnta #1\relax \edef\coordsys@a{\the\@tempcnta}% \@tempcntb=#3\relax \ifnum\@tempcnta<\@tempcntb\relax \advance\@tempcntb -\@tempcnta\relax \divide\@tempcntb #1\relax \edef\coordsys@b{\the\@tempcntb}% \multiput(\coordsys@a,#4)(#1,0)\coordsys@b {\h@logbox{#1}{#5}}% % \end{macrocode} % In the linear case we took some measure against colliding tick marks and % arrow heads; in % the logarithmic case we leave that worry to the user\footnote{Because % calculating the position of individual logarithmic tick mark is difficult; % this code works by setting blocks of tick marks.}. Therefore we can (and % should) set one more thick tick mark than we have blocks. % \begin{macrocode} \thick@ticks \@tempcntb=\coordsys@b\relax \advance\@tempcntb 1\relax \edef\coordsys@b{\the\@tempcntb}% \multiput(\coordsys@a,#4)(#1,0)\coordsys@b {#5}% % \end{macrocode} % Then set the labels: First set the counter "@coord" to\footnote{The % calculation uses a horrible mixture of \LaTeX\ syntax and plain \TeX\ since % \LaTeX\ does not provide a division command. Maybe I should avoid the % \LaTeX\ style counter and just use plain \TeX. See the note to code % line~\ref{cl:@coord}.} % $\frac{\meta{from}}{\meta{spacing}}$, then step that counter by one. % \begin{macrocode} \if@numbline \setcounter{@coord}{\coordsys@a}% \divide\c@@coord #1\relax \multiput(\coordsys@a,#4)(#1,0)\coordsys@b{% \sethlabel{\loglabel{\arabic{@coord}}}% \stepcounter{@coord}}% \fi \fi } % \end{macrocode} % \end{macro} % \begin{macro}{\@setvlogticks} % The vertical version works in much the same way. % \begin{macrocode} \newcommand{\@setvlogticks}[5]{% \thin@ticks \@tempcnta=#2\relax \ifnum\@tempcnta>0\advance\@tempcnta -1\relax\fi \divide\@tempcnta #1\relax \ifnum #2>0\advance\@tempcnta 1\relax\fi \multiply\@tempcnta #1\relax \edef\coordsys@a{\the\@tempcnta}% \@tempcntb=#3\relax \ifnum\@tempcnta<\@tempcntb\relax \advance\@tempcntb -\@tempcnta\relax \divide\@tempcntb #1\relax \edef\coordsys@b{\the\@tempcntb}% \multiput(#4,\coordsys@a)(0,#1)\coordsys@b {\v@logbox{#1}{#5}}% \thick@ticks \@tempcntb=\coordsys@b\relax \advance\@tempcntb 1\relax \edef\coordsys@b{\the\@tempcntb}% \multiput(#4,\coordsys@a)(0,#1)\coordsys@b {#5}% \if@numbline \setcounter{@coord}{\coordsys@a}% \divide\c@@coord #1\relax \multiput(#4,\coordsys@a)(0,#1)\coordsys@b{% \setvlabel{\loglabel{\arabic{@coord}}}% \stepcounter{@coord}}% \fi \fi } % \end{macrocode} % \end{macro} % % \begin{macro}{\logline} % The "\logline" command checks for a star, % \begin{macrocode} \newcommand{\logline}{% \@ifstar{\@numblinefalse\hlogline@i} {\@numblinetrue \hlogline@i}} % \end{macrocode} % \begin{macro}{\hlogline@i} % then "\hlogline@i" picks up the optional argument, % \begin{macrocode} \newcommand{\hlogline@i}[1][50]{\leavevmode\hlogline@ii{#1}} % \end{macrocode} % \begin{macro}{\hlogline@ii} % and "\hlogline@ii" does the work---which isn't much since % "\@sethlogticks" does almost everything. % \begin{macrocode} \newcommand{\hlogline@ii}[3]{{\color@begingroup \thinlines \@tempcnta=#3\relax \advance\@tempcnta -#2\relax \edef\coordsys@w{\the\@tempcnta}% \put(#2,0){\vector(1,0){\coordsys@w}}% \@sethlogticks{#1}{#2}{#3}{0}{\vtickmark} \color@endgroup}% \def\coordsys@w{0}% } % \end{macrocode} % \end{macro}\end{macro}\end{macro} % % \begin{macro}{\vlogline} % \begin{macro}{\vlogline@i} % \begin{macro}{\vlogline@ii} % The "\vlogline" command and friends work in much the same way. % \begin{macrocode} \newcommand{\vlogline}{% \@ifstar{\@numblinefalse\vlogline@i} {\@numblinetrue \vlogline@i}} \newcommand{\vlogline@i}[1][50]{\leavevmode\vlogline@ii{#1}} \newcommand{\vlogline@ii}[3]{{\color@begingroup \thinlines \@tempcnta=#3\relax \advance\@tempcnta -#2\relax \edef\coordsys@h{\the\@tempcnta}% \put(0,#2){\vector(0,1){\coordsys@h}}% \@setvlogticks{#1}{#2}{#3}{0}{\htickmark} \color@endgroup}% \def\coordsys@h{0}% } % \end{macrocode} % \end{macro}\end{macro}\end{macro} % % \begin{macro}{\logsys} % The logarithmic coordinate system commands have different default values for % the optional arguments than their linear cousins. We therefore need a new % approach for picking up optional arguments. % % The "\logsys" command defines "\coordsys@c" to be the command that % eventually sets the coordinate system. Then "\logsys" define % "\@hticksep" and "\@vticksep" to be the default values for the % optional arguments. (Each logarithmic coordinate system type has a different % set of default values.) Then "\logsys" checks for a star and calls % "\logsys@args@i". % \begin{macrocode} \newcommand{\logsys}{% \def\coordsys@c{\logsys@i}% \def\@hticksep{10}% \def\@vticksep{50}% \@ifstar{\@numblinefalse\logsys@args@i} {\@numblinetrue \logsys@args@i}} % \end{macrocode} % \begin{macro}{\logsys@args@i} % The "\logsys@args@i" command picks up the first optional argument % storing it in "\@hticksep" for later processing. % \begin{macrocode} \newcommand{\logsys@args@i}[1][\@hticksep]{\leavevmode \edef\@hticksep{#1}% \logsys@args@ii} % \end{macrocode} % \end{macro} % \begin{macro}{\logsys@args@ii} % Then "\logsys@args@ii" picks up the second optional argument and calls % the good old "\coordsys@args@iii" command to pick up (some of) the % remaining arguments. % \begin{macrocode} \newcommand{\logsys@args@ii}[1][\@vticksep]{% \edef\@vticksep{#1}% \coordsys@args@iii} % \end{macrocode} % \end{macro} % \begin{macro}{\logsys@i} % Finally "\logsys@i" sets the coordinate system: % First calculate the width and height of the system, then set the axes % and the tick marks and labels on the linear (horizontal) axis---all of it % much like "\fcoordsys@i" above. % \begin{macrocode} \def\logsys@i#1#2(#3,#4){{\color@begingroup \thinlines \@tempcnta=#3\relax \advance\@tempcnta -#1\relax \edef\coordsys@w{\the\@tempcnta}% \put(#1,#2){\vector(1,0){\coordsys@w}}% \@tempcnta=#4\relax \advance\@tempcnta -#2\relax \edef\coordsys@h{\the\@tempcnta}% \put(#1,#2){\vector(0,1){\coordsys@h}}% \@set@ticks{\hthickratio}{\@hticksep}{#1}{#3}{6\p@}{% \multiput(\coordsys@a,#2)(\coordsys@c,0)\coordsys@b\vtickmark}% \if@numbline \setcounter{@coord}{\coordsys@a}% \multiput(\coordsys@a,#2)(\coordsys@c,0)\coordsys@b{% \edef\coordsys@a{\arabic{@coord}}% \sethlabel{\hlabel{\coordsys@a}}% \addtocounter{@coord}{\coordsys@c}}% \fi % \end{macrocode} % Finally call "\@setvlogticks" to set the tick marks and labels on the % logarithmic (vertical) axis. % \begin{macrocode} \@setvlogticks{\@vticksep}{#2}{#4}{#1}{\htickmark}% \color@endgroup}% \def\coordsys@h{#1}% \def\coordsys@w{#2}% } % \end{macrocode} % \end{macro}\end{macro} % % \begin{macro}{\semilogsys} % \begin{macro}{\semilogsys@i} % The "\semilogsys" and "\semilogsys@i" commands work in much the % same manner. % \begin{macrocode} \newcommand{\semilogsys}{% \def\coordsys@c{\semilogsys@i}% \def\@hticksep{50}% \def\@vticksep{10}% \@ifstar{\@numblinefalse\logsys@args@i} {\@numblinetrue \logsys@args@i}} \def\semilogsys@i#1#2(#3,#4){{\color@begingroup \thinlines \@tempcnta=#3\relax \advance\@tempcnta -#1\relax \edef\coordsys@w{\the\@tempcnta}% \put(#1,#2){\vector(1,0){\coordsys@w}}% \@tempcnta=#4\relax \advance\@tempcnta -#2\relax \edef\coordsys@h{\the\@tempcnta}% \put(#1,#2){\vector(0,1){\coordsys@h}}% \@sethlogticks{\@hticksep}{#1}{#3}{#2}{\vtickmark}% \@set@ticks{\vthickratio}{\@vticksep}{#2}{#4}{6\p@}{% \multiput(#1,\coordsys@a)(0,\coordsys@c)\coordsys@b\htickmark}% \if@numbline \setcounter{@coord}{\coordsys@a}% \multiput(#1,\coordsys@a)(0,\coordsys@c)\coordsys@b{% \edef\coordsys@a{\arabic{@coord}}% \setvlabel{\vlabel{\coordsys@a}}% \addtocounter{@coord}{\coordsys@c}}% \fi \color@endgroup}% \def\coordsys@h{#1}% \def\coordsys@w{#2}% } % \end{macrocode} % \end{macro}\end{macro} % % \begin{macro}{\loglogsys} % \begin{macro}{\loglogsys@i} % The "\loglogsys" and "\loglogsys@i" commands work in much the % same manner. % \begin{macrocode} \newcommand{\loglogsys}{% \def\coordsys@c{\loglogsys@i}% \def\@hticksep{50}% \def\@vticksep{50}% \@ifstar{\@numblinefalse\logsys@args@i} {\@numblinetrue \logsys@args@i}} \def\loglogsys@i#1#2(#3,#4){{\color@begingroup \thinlines \@tempcnta=#3\relax \advance\@tempcnta -#1\relax \edef\coordsys@w{\the\@tempcnta}% \put(#1,#2){\vector(1,0){\coordsys@w}}% \@tempcnta=#4\relax \advance\@tempcnta -#2\relax \edef\coordsys@h{\the\@tempcnta}% \put(#1,#2){\vector(0,1){\coordsys@h}}% \@sethlogticks{\@hticksep}{#1}{#3}{#2}{\vtickmark}% \@setvlogticks{\@vticksep}{#2}{#4}{#1}{\htickmark}% \color@endgroup}% \def\coordsys@h{#1}% \def\coordsys@w{#2}% } % \end{macrocode} % \end{macro}\end{macro} % % \begin{macro}{\loggrid} % The "\loggrid" command is the obvious cross between "\logsys" and % "\coordgrid". % \begin{macrocode} \newcommand{\loggrid}{% \def\@hticksep{10}% \def\@vticksep{50}% \@numblinefalse \@ifstar{\def\coordsys@c{\loggrid@ii}\logsys@args@i} {\def\coordsys@c{\loggrid@i}\logsys@args@i}} % \end{macrocode} % \begin{macro}{\loggrid@i} % Similarly, "\loggrid@i" is a cross between "\logsys@i" and % "\coordgrid@i", % \begin{macrocode} \def\loggrid@i#1#2(#3,#4){{\color@begingroup \coordgrid@calc \grid@style \@set@ticks{\hthickratio}{\@hticksep}{#1}{#3}{\z@}{% \multiput(\coordsys@a,0)(\coordsys@c,0)\coordsys@b {\vgridfromto{#2}{#4}}}% \@setvlogticks{\@vticksep}{#2}{#4}{0}{\hgridfromto{#1}{#3}}% \color@endgroup}} % \end{macrocode} % \end{macro} % \begin{macro}{\loggrid@ii} % and "\loggrid@ii" is a cross between "\logsys@i" and % "\coordgrid@ii". % \begin{macrocode} \def\loggrid@ii#1#2(#3,#4){{\color@begingroup \grid@style \@tempcnta=#3\relax \advance\@tempcnta -#1\relax \edef\coordsys@w{\the\@tempcnta}% \@tempcnta=#4\relax \advance\@tempcnta -#2\relax \edef\coordsys@h{\the\@tempcnta}% \@set@ticks{\hthickratio}{\@hticksep}{#1}{#3}{\z@}{% \multiput(\coordsys@a,#2)(\coordsys@c,0)\coordsys@b {\vgridlength{\coordsys@h}}}% \@setvlogticks{\@vticksep}{#2}{#4}{#1}{\hgridlength{\coordsys@w}}% \color@endgroup}} % \end{macrocode} % \end{macro}\end{macro} % % \begin{macro}{\semiloggrid} % \begin{macro}{\semiloggrid@i} % \begin{macro}{\semiloggrid@ii} % Semi-logarithmic grids provide no surprises, % \begin{macrocode} \newcommand{\semiloggrid}{% \def\@hticksep{50}% \def\@vticksep{10}% \@numblinefalse \@ifstar{\def\coordsys@c{\semiloggrid@ii}\logsys@args@i} {\def\coordsys@c{\semiloggrid@i}\logsys@args@i}} \def\semiloggrid@i#1#2(#3,#4){{\color@begingroup \coordgrid@calc \grid@style \@sethlogticks{\@hticksep}{#1}{#3}{0}{\vgridfromto{#2}{#4}}% \@set@ticks{\vthickratio}{\@vticksep}{#2}{#4}{\z@}{% \multiput(0,\coordsys@a)(0,\coordsys@c)\coordsys@b {\hgridfromto{#1}{#3}}}% \color@endgroup}} \def\semiloggrid@ii#1#2(#3,#4){{\color@begingroup \grid@style \@tempcnta=#3\relax \advance\@tempcnta -#1\relax \edef\coordsys@w{\the\@tempcnta}% \@tempcnta=#4\relax \advance\@tempcnta -#2\relax \edef\coordsys@h{\the\@tempcnta}% \@sethlogticks{\@hticksep}{#1}{#3}{#2}{\vgridlength{\coordsys@h}}% \@set@ticks{\vthickratio}{\@vticksep}{#2}{#4}{\z@}{% \multiput(#1,\coordsys@a)(0,\coordsys@c)\coordsys@b {\hgridlength{\coordsys@w}}}% \color@endgroup}} % \end{macrocode} % \end{macro}\end{macro}\end{macro} % \begin{macro}{\logloggrid} % \begin{macro}{\logloggrid@i} % \begin{macro}{\logloggrid@ii} % and nor do double-logarithmic grids. % \begin{macrocode} \newcommand{\logloggrid}{% \def\@hticksep{50}% \def\@vticksep{50}% \@numblinefalse \@ifstar{\def\coordsys@c{\logloggrid@ii}\logsys@args@i} {\def\coordsys@c{\logloggrid@i}\logsys@args@i}} \def\logloggrid@i#1#2(#3,#4){{\color@begingroup \coordgrid@calc \grid@style \@sethlogticks{\@hticksep}{#1}{#3}{0}{\vgridfromto{#2}{#4}}% \@setvlogticks{\@vticksep}{#2}{#4}{0}{\hgridfromto{#1}{#3}}% \color@endgroup}} \def\logloggrid@ii#1#2(#3,#4){{\color@begingroup \grid@style \@tempcnta=#3\relax \advance\@tempcnta -#1\relax \edef\coordsys@w{\the\@tempcnta}% \@tempcnta=#4\relax \advance\@tempcnta -#2\relax \edef\coordsys@h{\the\@tempcnta}% \@sethlogticks{\@hticksep}{#1}{#3}{#2}{\vgridlength{\coordsys@h}}% \@setvlogticks{\@vticksep}{#2}{#4}{#1}{\hgridlength{\coordsys@w}}% \color@endgroup}} % % \end{macrocode} % \end{macro}\end{macro}\end{macro} % % % \subsection{The \texttt{putfile} Maple Code} % \begin{macrocode} %<*putfile> putfile := proc(fn::{string, list(string), set(string)}, P::specfunc(anything, PLOT) ) option `Copyright 2000-06 by Mogens Lemvig Hansen`; description "version 1.1"; local L, fns, i, V, scl, FH, ttl, pt, path, ext; global StringTools; % \end{macrocode} % Process the options. % \begin{macrocode} L := [args[3..-1]]; if hasoption(L, 'scale', scl, 'L') then scl := evalf(scl); if not type(scl, ['numeric', 'numeric']) then error "the scale option must be [numeric, numeric] but got %1", scl; fi; else scl := [1,1]; fi; if L <> [] then error "unknown options: %1", L; fi; % \end{macrocode} % Pull the "CURVES" from the "PLOT" structure. % \begin{macrocode} L := map( `putfile/grabcurves`, [op(P)] ); % \end{macrocode} % If a single filename is given, we can construct a suitable list of filenames: % The path ends with the last backslash, slash, or colon in "fn"; % the extension begins with the last period after that. % \begin{macrocode} if type(fn, 'string') then path := map(StringTools:-FirstFromRight, ["\\", "/", ":"], fn); path := max(op(path)); ext := StringTools:-FirstFromRight(".", fn[path+1..-1]); % \end{macrocode} % If there is not extension, prepare to append % ".tex";\footnote{The extension \texttt{.tex} for these data files % may not be logical, but it is what \TeX\ assumes in the % \texttt{\bslash putfile} command, so at least we have consistent % assumptions.} % otherwise save and strip the extension. % \begin{macrocode} if ext = 0 then ext := ".tex"; fns := fn; else ext := fn[path+ext..-1]; fns := fn[1..-length(ext)-1] fi; % \end{macrocode} % Multiply the filename if necessary, and append the extension. % \begin{macrocode} if nops(L) = 1 then fns := [fns]; else fns := [ seq(cat(fns, i), i=1..nops(L)) ]; fi; fns := map(cat, fns, ext); % \end{macrocode} % If we have a set or list or filenames, their number must match the number of % "CURVES". % \begin{macrocode} else fns := fn; if nops(fns) <> nops(L) then error "the number of filenames must match " "the number of curves, " "received %1 names but %2 curves.", nops(fns), nops(L); fi; fi; % \end{macrocode} % Extract the view-port from the "PLOT" structure. % \begin{macrocode} V := select(type, [op(P)], 'specfunc'('anything', 'VIEW')); if nops(V) <> 1 then V := ['DEFAULT', 'DEFAULT']; else V := [ op([1,1], V), op([1,2], V) ]; fi; V := subs('DEFAULT'=Float(-infinity)..Float(infinity), V); % \end{macrocode} % Finally, extract the title, if any. % The title will be included as a comment. % Since the title could be a multi-line string, we must insert "%" characters % after any new-lines. % \begin{macrocode} ttl := select(type, [op(P)], 'specfunc'('anything', 'TITLE')); if nops(ttl) = 1 then ttl := op([1,1], ttl); ttl := StringTools:-SubstituteAll(ttl, "\n", "\n%% "); fi; % \end{macrocode} % Fit the curves to the view-port, and scale as requested. % \begin{macrocode} L := map( `putfile/cleancurve`, L, V); L := map2( map, u->[scl[1]*u[1], scl[2]*u[2]], L ); % \end{macrocode} % For each curve, write the title (if any), the view-port, and all the points to % the file. % \begin{macrocode} for i from 1 to nops(L) do try FH := fopen(fns[i], 'WRITE', 'TEXT'); if type(ttl, 'string') then fprintf(FH, "%%%% %s\n", ttl) fi; if scl <> [1,1] then fprintf(FH, "%% scaled %a\n", scl) fi; V := [ map2(op, 1, L[i]), map2(op, 2, L[i]) ]; V := map( u-> min(op(u))..max(op(u)), V ); fprintf(FH, "%% horizontal range: %f .. %f\n", op(V[1])); fprintf(FH, "%% vertical range: %f .. %f\n", op(V[2])); for pt in L[i] do fprintf(FH, "%f \t%f\n", op(pt)); od; finally fclose(FH); end try end do; end; % \end{macrocode} % % The sub-routines that follow use Maple's naming convention for such. % % We are interested in "CURVES" objects in a "PLOT" structure. % A "CURVES" object contains options (which we ignore) and lists of % \meta{curve}s, where a \meta{curve} is a list of \meta{point}s and a % \meta{point} is a list of length two usually containing two numeric values. % If "x" is not a "CURVES", return nothing. If "x" is a % "CURVES", extract the list of \meta{curve}s and return the % corresponding sequence of \meta{curve}s. If the "PLOT" structure % contains more than one "CURVES" object, the sequences returned by % "putfile/grabcurves" will flatten to one sequence of \meta{curve}s % \begin{macrocode} `putfile/grabcurves` := proc(x) option `Copyright 2000-06 by Mogens Lemvig Hansen`; description "version 1.1"; local L; if op(0, x) = 'CURVES' then L := [ op(x) ]; L := select(type, L, 'list'); RETURN(op(L)); else RETURN(NULL); fi; end; % \end{macrocode} % Each curve has to be fitted inside the view-port. % The curve, "CC", is a list of points. % The view-port, "V", is a list of the form % \texttt{[numeric..numeric, numeric..numeric]}. % \begin{macrocode} `putfile/cleancurve` := proc(CC::list, V::list) local C, B, pts, pt, m, i; option `Copyright 2004-06 by Mogens Lemvig Hansen`; description "version 1.1"; % \end{macrocode} % Remove any non-numeric points. % \begin{macrocode} C := select(type, CC, ['numeric', 'numeric']); if nops(C) < 1 then error "no numeric points in %1", C fi; % \end{macrocode} % Then build a new list of point: each time a consecutive pair of points in % "C" straddles a boundary of the view-port, add the point of intersection % between the line through the two points and the view-port. % \begin{macrocode} B := C[1]; for i from 2 to nops(C) do if C[i] = C[i-1] then next fi; pts := NULL; if ( C[i-1][1] < lhs(V[1]) and C[i][1] > lhs(V[1]) ) or ( C[i-1][1] > lhs(V[1]) and C[i][1] < lhs(V[1]) ) then m := ( C[i-1][2] - C[i][2] ) / ( C[i-1][1] - C[i][1] ); pt := lhs(V[1]); pt := [ pt, m*(pt-C[i][1]) + C[i][2] ]; pts := pts, pt; fi; if ( C[i-1][1] < rhs(V[1]) and C[i][1] > rhs(V[1]) ) or ( C[i-1][1] > rhs(V[1]) and C[i][1] < rhs(V[1]) ) then m := ( C[i-1][2] - C[i][2] ) / ( C[i-1][1] - C[i][1] ); pt := rhs(V[1]); pt := [ pt, m*(pt-C[i][1]) + C[i][2] ]; pts := pts, pt; fi; if ( C[i-1][2] < lhs(V[2]) and C[i][2] > lhs(V[2]) ) or ( C[i-1][2] > lhs(V[2]) and C[i][2] < lhs(V[2]) ) then m := ( C[i-1][1] - C[i][1] ) / ( C[i-1][2] - C[i][2] ); pt := lhs(V[2]); pt := [ m*(pt-C[i][2]) + C[i][1], pt ]; pts := pts, pt; fi; if ( C[i-1][2] < rhs(V[2]) and C[i][2] > rhs(V[2]) ) or ( C[i-1][2] > rhs(V[2]) and C[i][2] < rhs(V[2]) ) then m := ( C[i-1][1] - C[i][1] ) / ( C[i-1][2] - C[i][2] ); pt := rhs(V[2]); pt := [ m*(pt-C[i][2]) + C[i][1], pt ]; pts := pts, pt; fi; % \end{macrocode} % If the two points straddle more than one view-port boundary, we add one point % for each boundary. The order of the added points must be in the direction % of the curve. % \begin{macrocode} pts := [pts]; if C[i-1][1] < C[i][1] then pts := sort(pts, (u,v)->evalb(u[1] C[i][1] then pts := sort(pts, (u,v)->evalb(u[1]>v[1])); elif C[i-1][2] < C[i][2] then pts := sort(pts, (u,v)->evalb(u[2] C[i][2] then pts := sort(pts, (u,v)->evalb(u[2]>v[2])); else error "cannot happen"; fi; B := B, op(pts), C[i]; od; C := [B]; % \end{macrocode} % Finally remove the point outside the view-port. % \begin{macrocode} C := select( u->evalb(lhs(V[1])<=u[1] and u[1] <= rhs(V[1])), C); C := select( u->evalb(lhs(V[2])<=u[2] and u[2] <= rhs(V[2])), C); C; end; % % \end{macrocode} % % \Finale %