diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /usergrps/uktug/baskervi/6_4/pstrix4.tex |
Initial commit
Diffstat (limited to 'usergrps/uktug/baskervi/6_4/pstrix4.tex')
-rw-r--r-- | usergrps/uktug/baskervi/6_4/pstrix4.tex | 491 |
1 files changed, 491 insertions, 0 deletions
diff --git a/usergrps/uktug/baskervi/6_4/pstrix4.tex b/usergrps/uktug/baskervi/6_4/pstrix4.tex new file mode 100644 index 0000000000..f042e802bf --- /dev/null +++ b/usergrps/uktug/baskervi/6_4/pstrix4.tex @@ -0,0 +1,491 @@ +\author[Sebastian Rahtz]{Sebastian Rahtz\\ +Elsevier Science Ltd\\The Boulevard, Langford +Lane\\Kidlington\\ +Oxford, UK\\\texttt{s.rahtz@elsevier.co.uk}}\title{An introduction to PSTricks, part 4} +\begin{Article} +This article concludes my look at \PST{}. I hope you have +enjoyed the show! The material has been drawn from a forthcoming book, +entitled \emph{The \LaTeX{} Graphics Companion}, by Michel Goossens, +Sebastian Rahtz and Frank Mittelbach, to be published by Addison +Wesley in 1997. If you have enjoyed \BV{} articles in the last +couple of years on Seminar, colour in \LaTeX, and \PST, you may find +the book of interest. + +In this final part, we look briefly at data plotting, and then +conclude with some finished examples of \PST, which are designed +to show the power of the macros in unusual ways. + +\section{Data plotting} +\PST\ has a set of high-level tools for common data-plotting +functions; these can read data from external files, in a variety of +formats. We will not tabulate the extra commands or graphical parameters +this time, as they can be easily found in the \PST{} documentation. +The simplest form of data is a set of comma or white-space delimited +numbers, but values can also be enclosed in braces (\verb|{}|) or +round brackets (\verb|()|). If the data is enclosed in a single +set of \emph{square} brackets (\verb|[]|), and the opening \verb=[= is at the +start of a line, it will be read much faster; however, it will run +\TeX\ out of memory sooner. Data can also be read once, and then +re-used, with the \Lcs{readdata} and \Lcs{savedata} commands. There is +an important distinction between \Lcs{fileplot} or \Lcs{dataplot} +which parse and validate the data in \TeX, and \Lcs{listplot}, which +simply passes the data on to \PS; the latter approach means that there +is no check on \PS\ memory requirements, but has the advantage that +raw \PS\ can be provided to generate or manipulate the data. +Just to complicate matters, use of the \Lcs{PSTtoEPS} command with the +plotting commands can allow for even bigger datasets. An example of +this is given below, in section~\ref{PSTprog}. + +It is important to realize that it is up to the user to check the +data extents and scaling; \PST\ does not make the data fit a +predefined plot area, unlike many other packages. Normally, judicious +setting of \PKey{xunit} and \PKey{yunit} will quickly produce nice +results. Axes are generated separately, and there is no provision for +supplying specific labels for axis tick points. It is, on the other +hand, easy to superimpose multiple plots, and use the \PS\ language to +calculate functions, as the following example shows, overlaying +$\sin(x)$, $\sin(x)\cos(x)$ and $\cos(x)$. + +\begin{example*} +\begin{pspicture}(-1,-2.5)(9,2.5) +\psset{xunit=.20mm,yunit=1.75cm} +\psset{plotpoints=50} +\psplot[linestyle=dashed,linecolor=blue] + {0}{360}{x sin} +\psplot[plotstyle=dots,dotstyle=triangle] + {0}{360}{x cos} +\psset{plotpoints=200} +\psplot[linecolor=red]{0}{360} + {x dup sin exch cos mul} +\end{pspicture} +\end{example*} + +The next example shows how the \Lcs{psaxes} command can +be used to create graph frames; in this mode, it obeys the graphical +fill and colour parameters. This picture (showing +word length ($x$ axis) against occurrences ($y$ axis) in a passage of +Dickens) also shows how the axis labels can be manipulated. + +\begin{example*} +\readdata{\foo}{words.dat} +\psset{yunit=.2mm,xunit=4mm} +\begin{pspicture}(-2,-50)(20,250) +\psaxes[axesstyle=frame,dy=50\psyunit, + Dy=50,tickstyle=bottom, + fillcolor=gray,fillstyle=solid](1,1)(18,229) +\dataplot[plotstyle=line,linecolor=white]{\foo} +\end{pspicture} +\end{example*} + +\PST\ is not designed to be a fully-fledged business graphics package; +its plotting functions are really for simple scientific plots +only. However, it should be clear that the lower-level \PST\ macros, +and \TeX's programmability, make it a good basis for whatever +graphing is needed. +We conclude this section with a crude pie chart, with the macros and +some of the data used to create it; note that only +segments above a certain size are labelled --- providing a sensible +label for all elements would involve considerably more care. +\mbox{Denis} \mbox{Girou} has written a generalised pie-chart and bar +chart creation package for \PST\ (under +revision at the time of writing), which can produce very professional +results. + +\newcommand\lang[4]{% name, value, percentage, color + \setcounter{thisval}{\value{lastval}} + \addtocounter{thisval}{#3} + \pswedge[fillcolor=#4]{1}{\thelastval}{\thethisval}% + \setcounter{thishalf}{((\value{thisval}-\value{lastval})/2)+\value{lastval}} + \ifnum#3>200\rput(1.3;\thethishalf){#1}\fi + \setcounter{lastval}{\value{thisval}} +} +\bgroup\psset{unit=2.5} +\centerline{\begin{pspicture}(-1.3,-1.3)(1.3,1.3) +\psset{fillstyle=solid} +\degrees[10000] +\SpecialCoor +\setcounter{lastval}{0} +\lang{Romanian}{1}{3}{green} +\lang{Czech}{2}{6}{blue} +\lang{Bulgarian}{4}{11}{green} +\lang{Japanese}{4}{11}{palegreen} +\lang{Dutch}{7}{20}{black} +\lang{Norwegian}{20}{56}{cyan} +\lang{Greek}{26}{73}{magenta} +\lang{Swedish}{34}{95}{lightgray} +\lang{Danish}{46}{129}{white} +\lang{French}{83}{232}{pink} +\lang{Latin}{146}{409}{wheat} +\lang{Russian}{243}{680}{white} +\lang{Italian}{391}{1093}{gray} +\lang{German}{508}{1421}{lightblue} +\lang{unknown}{599}{1676}{red} +\lang{English}{1462}{4085}{yellow} +\end{pspicture}} +\egroup +\begin{sverbatim} +\usepackage{calc,pstcol} +\newcommand{\lang}[4]{% name, value, proportion of + % 10000, colour + \setcounter{thisval}{\value{lastval}} + \addtocounter{thisval}{#3} + \pswedge[fillcolor=#4]{1}{\thelastval}{\thethisval}% + \setcounter{thishalf}{((\value{thisval}- + \value{lastval})/2)+ + \value{lastval}} + \ifnum#3>200\rput(1.3;\thethishalf){#1}\fi + \setcounter{lastval}{\value{thisval}} +} +\psset{fillstyle=solid} +\degrees[10000] +\SpecialCoor +\setcounter{lastval}{0} +\lang{Romanian}{1}{3}{green} +\lang{Czech}{2}{6}{blue} +... +\lang{German}{508}{1421}{lightblue} +\lang{unknown}{599}{1676}{red} +\lang{English}{1462}{4085}{yellow} +\end{sverbatim} + +\section{\protect\PST\ programming examples}\label{PSTprog} +In the following pictures, we attempt to show some of the range of +\PST\ possibilities, demonstrate the advantages of using a programming +language for drawing pictures, and explore the various tools for +simplifying and modularizing the code to make it more readable. We +are especially glad to acknowledge Denis Girou for his input to this +section, both in personal exchanges and in published examples. + +In the first picture, a kite drawing from a child's book of colours and +shapes, notice how the tail is drawn as a curved node connection +between two points, and the bunting is added as labels on that +connection. Use of the node feature means that the calculation of the +line and positions along it are left entirely to +\PST. It is also worth recalling the basic \PS\ premise that objects +are opaque unless otherwise stated; this means that we can draw a blue +background to the whole picture, and then overlay solid blocks of +colour for the shapes. Some parts of the picture have a regular, +repeating, feature, and we take advantage of this to +draw the rays of sun using the \Lcs{multido} macro; note that we use a +\TeX\ group to localize the effect of the \Lcs{psset} which changes colour +and style. +\verbfile{kite.tex} +%\end{multicols} +\begin{center} +\vspace*{1.5ex} + \input kite.tex +\vspace*{1.5ex} +\end{center} +%\begin{multicols}{2} +In the next child's picture, we again take advantage of the strikeout +nature of \PS\ blocks of solid colour to draw the cat head as a whole +circle, and superimpose the wall (and on top of that the bricks) so +that we do not worry about creating a precise wedge of just +over a semicircle. \Lcs{rput} is used extensively to place objects at an +angle. The writing on the bricks demonstrates the importance of +understanding the reference point of objects that are placed. Since +the bricks and their legends are drawn \emph{after} the graffito, they +partly obscure it. We group objects of similar characteristics +together, and use \TeX's standard grouping to set \PST\ values for the +items in that group. We also break the picture into different +elements, describe each in a separate macro, and group them into +high-level objects. This technique allows us to built up a library of +objects, and serves to make the final picture description considerably +more readable. The cat sitting on its portion of wall sets its size +according to a parameter, allowing us to reproduce it several times at +different sizes; note how the \Lcs{rput} command resets the coordinate +system, so that the cat is drawn relative to the position of the \Lcs{rput}. + +\verbfile{cat.tex} +%\end{multicols} +\vspace*{1.5ex} +\begin{center} + \input cat.tex +\end{center} +\vspace*{1.5ex} +%\begin{multicols}{2} +The third complete picture is more complex, a +circuit diagram. We have +chosen to make this by programming a small language +for circuit diagrams, which implements the actions +\Lcs{Battery}, +\Lcs{Resistor}, \Lcs{Switch} and +\Lcs{Inductor}, with the movement commands +\Lcs{Up}, +\Lcs{Down} +\Lcs{Left}, and +\Lcs{Right} in the spirit of \textsf{pic}. +Thus the final part of the input is quite simple, +apart from the node connection and label commands which are used +in their normal way (some care is needed to consider the angles +at which connection lines leave and join each node). + +\begin{sverbatim} +\Up{1} +\Battery{A} +\Up{1} +\Right{2} +\Resistor{B} +\Right{1} +\Down{.3} +\Inductor{C} +\Down{.5} +\Left{1} +\Switch{D} +\ncangle[angleA=90,angleB=180,armB=0]{A}{B} +\ncangle[angleA=0,angleB=90,armB=0]{B}{C} +\ncput[ref=l]{~~~$i=i_{\mbox{max}}(1-w^{-t/3})$} +\ncangle[angleA=-90,armB=0,angleB=0]{C}{D} +\ncangle[angleA=180,armB=0,angleB=-90]{D}{A} +\nput{180}{A}{10V} +\nput{90}{B}{R} +\nput{0}{C}{3mH} +\nput{270}{D}{S} +\end{sverbatim} + +\makeatletter +\newdimen\CurX +\newdimen\CurY \newdimen\Cir@temp +\newcount\Cir@direction % 0 right, 1 left, 2 up, 3 down +\Cir@direction0 +\def\SetX#1{\CurX=#1pt} +\def\SetY#1{\CurY=#1pt} +\def\ShowDirection{\typeout{Direction: + \ifcase\Cir@direction right\or left\or up\or down\fi, + now at (\strip@pt\CurX,\strip@pt\CurY)}% +} +\def\ShowXY{\message{(\strip@pt\CurX,\strip@pt\CurY)}} + +\def\Down#1{\advance\CurY by -#1\p@\Cir@direction3\ShowDirection} +\def\Up#1{\advance\CurY by #1\p@\Cir@direction2\ShowDirection} +\def\Left#1{\advance\CurX by -#1\p@\Cir@direction1\ShowDirection} +\def\Right#1{\advance\CurX by #1\p@\Cir@direction0\ShowDirection} +\def\MyBox#1#2{% width,height + \pssetlength{\Cir@temp}{#1}% + \rule{\Cir@temp}{\z@}% + \pssetlength{\Cir@temp}{#2}% + \rule{\z@}{\Cir@temp}% +} +\def\Point#1{% +\rput(\strip@pt\CurX,\strip@pt\CurY){\pnode{#1}}% +} +\def\Switch#1{% +\message{[Switch] #1}\ShowXY +\relax +\ifcase\Cir@direction % right + \rput[b](\strip@pt\CurX,\strip@pt\CurY){\rnode[b]{#1}{% + \psline(.5,.4)% + \psarc{<-}{.4}{-10}{70}% + \MyBox{.5}{.4}% + }}% + \advance\CurX by .5\p@ +\or % left + \advance\CurX by -.5\p@ + \rput[b](\strip@pt\CurX,\strip@pt\CurY){\rnode[b]{#1}{% + \psline(0,0)(.5,.4)% + \psarc{<-}{.4}{-10}{70}% + \MyBox{.5}{.4}% + }}% +\fi +} + +\def\Battery#1{% +\message{[Battery] #1}\ShowXY +\relax +\ifcase\Cir@direction % right + \rput[r](\strip@pt\CurX,\strip@pt\CurY){\rnode{#1}{% + \psline(0,-.4)(0,.4)% + \psline(.2,-.2)(.2,.2)% + \MyBox{.2}{.8}% + }}% + \advance\CurX by .2\p@ +\or % left + \advance\CurX by -.2\p@ + \rput[r](\strip@pt\CurX,\strip@pt\CurY){\rnode{#1}{% + \psline(0,-.4)(0,.4)% + \psline(.2,-.2)(.2,.2)% + \MyBox{.2}{.8}% + }}% +\or % up + \advance\CurY by .2\p@ + \rput[b](\strip@pt\CurX,\strip@pt\CurY){\rnode{#1}{% + \psline(.1,.2)(.9,.2)% + \psline(0.3,0)(0.7,0)% + \MyBox{1}{.2}% + }}% +\or % down + \rput[b](\strip@pt\CurX,\strip@pt\CurY){\rnode{#1}{% + \psline(-.4,0)(.4,0)% + \psline(-.2,-.2)(.2,-.2)% + \MyBox{1}{.2}% + }}% + \advance\CurY by -.2\p@ +\fi +} + +\def\Resistor{\message{[Resistor]}\ShowXY + \@ifnextchar[{\@ResInd}{\@ResInd[1]{pszigzag}}} +\def\Inductor{\message{[Inductor]}\ShowXY + \@ifnextchar[{\@ResInd}{\@ResInd[1]{pscoil}}} + +\def\@ResInd[#1]#2#3{% + \ifcase\Cir@direction % right + \rput[l](\strip@pt\CurX,\strip@pt\CurY){\rnode{#3}{% + \csname #2\endcsname[coilarm=.01,coilwidth=.3](0,.15)(#1,.15)% + \MyBox{#1}{.3}% + }}% + \advance\CurX by #1\p@ + \or % left + \advance\CurX by -#1\p@ + \rput[l](\strip@pt\CurX,\strip@pt\CurY){\rnode{#3}{% + \csname #2\endcsname[coilarm=.01,coilwidth=.3](0,.15)(#1,.15)% + \MyBox{#1}{.3}% + }}% + \or % up + \rput[b](\strip@pt\CurX,\strip@pt\CurY){\rnode{#3}{% + \csname #2\endcsname[coilarm=.01,coilwidth=.3](.15,0)(.15,#1)% + \MyBox{.3}{#1}% + }}% + \advance\CurY by #1\p@ + \or % down + \advance\CurY by -#1\p@ + \rput[b](\strip@pt\CurX,\strip@pt\CurY){\rnode{#3}{% + \csname #2\endcsname[coilarm=.01,coilwidth=.3](.15,0)(.15,#1)% + \MyBox{.3}{#1}% + }}% + \fi +} +\makeatother + +\begin{pspicture}(5,5) +\SetX{1} +\Up{1} +\Battery{A} +\Up{1} +\Right{2} +\Resistor{B} +\Right{1} +\Down{.3} +\Inductor{C} +\Down{.5} +\Left{1} +\Switch{D} +\ncangle[angleA=90,angleB=180,armB=0]{A}{B} +\ncangle[angleA=0,angleB=90,armB=0]{B}{C} +\ncput[ref=l]{~~~$i=i_{\mbox{max}}(1-w^{-t/3})$} +\ncangle[angleA=-90,armB=0,angleB=0]{C}{D} +\ncangle[angleA=180,armB=0,angleB=-90]{D}{A} +\nput{180}{A}{10V} +\nput{90}{B}{R} +\nput{0}{C}{3mH} +\nput{270}{D}{S} +\end{pspicture} + +The new commands are implemented in terms of a current $x$ and $y$ +coordinate, which is changed by the movement commands. Thus \Lcs{Down} is +defined (simplified) in the following code: + +\begin{sverbatim} +\newcommand{\Down}[1]{% + \setcounter{CurY}}{-#1}% + \def{Cirdirection}{3}% + } +\end{sverbatim} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\begin{figure*}[t!] +\centerline{\includegraphics{map.eps}} +\caption{Autocad picture converted to \protect\PST\ macros} +\label{PSTacad} +\end{figure*} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +After each movement the current direction of movement is recorded, +since this affects how we draw the new objects. These have a switch +(which we have simplified in the following code example\footnote{since +we possibly want sizes to be real numbers, \Lcs{CurX} and \Lcs{CurY} +are in fact \TeX\ dimensions, which we convert back to numbers before +use.}) to check direction. The plain \TeX{} \Lcs{ifcase} command is +used to perform a 4-way switch between directions. The definition of +the resistor is: + +\begin{sverbatim} +\newcommand{\Resistor}[1]{% + \ifcase\Cirdirection % right + \rput[l](\CurX,\CurY){\rnode{#1}{% + \pszigzag[coilarm=.01,coilwidth=.3](0,.15)(1,.15)% + \MyBox{1}{.3}}}% + \addtocounter{CurX}{1}% + \or % left + \addtocounter{CurX}{-1}% + \rput[l](\CurX,\CurY){\rnode{#1}{% + \pszigzag[coilarm=.01,coilwidth=.3](0,.15)(1,.15)% + \MyBox{1}{.3}}}% + \or % up + \rput[b](\CurX,\CurY){\rnode{#1}{% + \pszigzag[coilarm=.01,coilwidth=.3](.15,0)(.15,1)% + \MyBox{.3}{1}}}% + \addtocounter{CurY}{1}% + \or % down + \addtocounter{CurY}{-1}% + \rput[b](\CurX,\CurY){\rnode{#1}{% + \pszigzag[coilarm=.01,coilwidth=.3](.15,0)(.15,1)% + \MyBox{.3}{1}}}% + \fi +} +\end{sverbatim} + +The macro \Lcs{MyBox} is very important; since by itself \Lcs{pszigzag} takes +no space, it will create a node with no width or height, and +connectors will go right to the middle. Therefore we put in some +\LaTeX\ struts with the \Lcs{rule} command, to create an invisible box +around the zigzag. The \PST\ units are converted to normal \TeX\ +lengths using \Lcs{pssetlength}. + +\begin{sverbatim} +\newlength{\Cirtemp} +\newcommand{\MyBox}[2]{% width,height + \pssetlength{\Cirtemp}{#1}% + \rule{\Cirtemp}{0pt}% + \pssetlength{\Cirtemp}{#2}% + \rule{0pt}{\Cirtemp}% +} +\end{sverbatim} + + +Our final example takes \PST\ into another subject area, that of +cartography. The map in Figure~\ref{PSTacad} is created from +an Autocad DXF file; this time the 36 +polygons, comprising 9619 separate line segments, were converted +(using a simple \emph{ad hoc} conversion program) to a separate +coordinate data file for each polygon. The overall map description +consists simply of 36 lines of the form: +\begin{sverbatim} +\ProcessVector{moh174} +\ProcessVector{moh170} +\end{sverbatim} +Since the number of coordinates is so large, many of the \PST\ tools +which can read the files (like \Lcs{fileplot}) run out of \TeX\ memory; +however, for purely graphical objects like polygons, we have the +more efficient and less memory-intensive option of writing +Encapsulated \PS\ files on the fly, so we instantiate the +\Lcs{ProcessVector} lines with the definition: +\begin{sverbatim} +\newcommand{\ProcessVector}[1]{% + \PSTtoEPS{#1.eps}{\fileplot{#1.dat}} + \rput(0,0){\includegraphics{#1.eps}}% +} +\end{sverbatim} +The command \Lcs{PSTtoEPS} takes two arguments, a filename, and any +pure \PST\ commands (\ie not text). Instead of embedding the necessary +\PS\ as \Lcs{special}s in the \TeX\ output, a \PS\ file is written +directly. + +Using the very simple top level \Lcs{ProcessVector} command means that the +master file is easily hand-edited; since the Autocad file identifies +the polygons by their `layer' (the map is a set of contour lines), we +are able to set the fill colour separately for each layer, and so +produce the more traditional map. +\end{Article} |