%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %% GasTeX : Graphs and Automata Simplified in TeX %% %% Macros for drawing easily graphs and automata under the picture %% environment of LaTeX. %% See the README file. %% %% Paul Gastin %% LMF %% ENS Paris-Saclay %% 4, Avenue des Sciences %% F-91190 Gif-sur-Yvette %% FRANCE %% mail: paul.gastin@ens-paris-saclay.fr %% http://www.lsv.fr/~gastin/ %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{gastex}[2024/02/12 v3.1] \RequirePackage{iftex} \RequirePackage{xkeyval} \RequirePackage{xifthen} \RequirePackage{calc} \RequirePackage{trig} \RequirePackage{environ} \RequirePackage{xcolor} \RequirePackage{graphicx} \newif\ifgastexslide\gastexslidefalse \DeclareOptionX{slide}{\global\gastexslidetrue} \DeclareOptionX{paper}{\global\gastexslidefalse} % \define@boolkey{gastex.sty}[gastex@]{pdflatex}[true]{} \PassOptionsToPackage{final}{pst-pdf} % \newif\ifgastex@autopstpdf\gastex@autopstpdffalse \newif\ifgastex@mdfive\gastex@mdfivefalse \define@choicekey*{gastex.sty}{recompilepics}[\g@val\g@nr]{auto,true,false}[auto]{% \ifcase\g@nr\relax % During the latex+dvips+ps2pdf run, the md5 computations and checks should not % be executed. Hence, we check whether pdftex is running in pdf mode. \ifpdf\gastex@mdfivetrue\else\gastex@mdfivefalse\fi \gastex@autopstpdftrue \PassOptionsToPackage{off}{auto-pst-pdf} \or \ifpdf\gastex@mdfivetrue\else\gastex@mdfivefalse\fi \gastex@autopstpdftrue \PassOptionsToPackage{on}{auto-pst-pdf} \or \gastex@mdfivefalse \gastex@autopstpdffalse \PassOptionsToPackage{off}{auto-pst-pdf} \fi } \ExecuteOptionsX{recompilepics=false} % if not set when loading gastex.sty, this option is off % \define@choicekey*{gastex.sty}{pst-pdf}[\g@val\g@nr]{md5,auto,final,draft,off}[md5]{% \PackageWarning{gastex}{Option pst-pdf is depreciated. Use options pdflatex and recompilepics instead.}{} } % \ExecuteOptionsX{pst-pdf=off} % if not set when loading gastex.sty, this option is off % \DeclareOptionX*{\PassOptionsToPackage{\CurrentOption}{auto-pst-pdf}} \ProcessOptionsX % if it exists, the md5 file should be read now to set the option of % auto-pst-pdf to on if some pictures have changed \def\g@hashfilename{\jobname-md5.txt}% \def\g@extract@mdfive:#1:#2:#3:{\expandafter\edef\csname g@oldmdfive@#2\endcsname{#3}}% \def\g@changed@mdfive!#1!{\PassOptionsToPackage{on}{auto-pst-pdf}}% \def\g@read@mdfive#1{\@ifnextchar:{\g@extract@mdfive}{\g@changed@mdfive}#1}% \def\g@process@mdfivefile{% \newif\ifnot@eof\not@eoffalse \IfFileExists{\g@hashfilename}{% \openin2 = "\g@hashfilename"% \loop% \read 2 to \g@md% \ifeof 2 \not@eoffalse\else\not@eoftrue\fi% \ifnot@eof% \expandafter\g@read@mdfive\expandafter{\g@md}% \repeat% \closein2}{}}% \ifgastex@mdfive\g@process@mdfivefile\fi % \ifgastex@pdflatex \ifgastex@autopstpdf \PassOptionsToPackage{pspdf=-dALLOWPSTRANSPARENCY}{auto-pst-pdf} \RequirePackage{auto-pst-pdf} % \RequirePackage[pspdf=-dALLOWPSTRANSPARENCY]{auto-pst-pdf} \else \RequirePackage{pst-pdf} \fi \else \special{header=gastex.pro} \fi % \input gastex.ps %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % History since version 2.0 % % 3.0 % Many changes in this release. % - Compatibility with pdflatex using auto-pst-pdf. % - New gpicture environment and new gusepicture command. % - New command to draw an arc of circle or a pie (See ex-gastex.tex) % \drawarc[linecolor=black](0,10,20,0,45) % \drawarc[arcPie=y,linecolor=blue](0,10,20,-50,-15) % - New command to draw a snaky line (See ex-gastex.tex) % \drawsnake[linecolor=red,snakeh=.8,snakew=.8](20,15.5)(20,8.5) % \drawsnake[linecolor=red,snakeh=.8,snakew=.8](0,7.5)(0,0.5) % % 2.9: % - added the parameters loopwidth and loopheight to be able to set % independently the width and height of loops. loopdiam still exists and set % both loopwidth and loopheight to the same value. % - added the example "ex-gastex-pdflatex.tex" which contains instructions how % to use gastex directly with pdflatex using the package auto-pst-pdf % % 2.8: % - packaged for CTAN % % 2.7: % - gastex is now compatible with the xcolor package which allows very % useful color expressions such as red!50!blue!60!white. % % 2.6: % - improved precision of some computations % % 2.5: % The horizontal shifts that one gets sometimes (e.g. with overlays in % presentations) should no more occur provided \nullfont is used inside the % picture environment: % \begin{picture}(100,35)(-50,0)\nullfont % ... % \end{picture} % \selectfont is automatically used by gastex for node or edge labels. % I found this solution looking in the package pgf (portable graphics % format) by Till Tantau. I also recommend his excellent beamer package % for laptop presentations. % % 2.4: % - added the macro \rpnode to allow nodes whose shape is a regular polygon % defined by its radius, its number of sides and an angle for the first point. % - added the possibility to have arrows at the tail of edges and lines. % For this, the following new parameters are provided: % ATnb, ATdist, ATangle, ATlength, ATLength % - added the macro \drawpolygon to draw a polygon defined by a list of points. % - added the macro \drawrpolygon to draw a regular polygon defined by % its radius, its number of sides and an angle for the first point. % - added the macro \drawline to draw a broken line defined by n points. % - added the parameter "arcradius" in order to have arcs instead of sharp angles % for polygons and broken lines. The default is arcradius=0 for sharp angles. % - added the macro \drawcurve to draw a continuous curve going through n points. % - added the macro \drawccurve to draw a continuous closed curve going through n points. % All these macros use gasset parameters and in particular: % Nframe, Nfill, linecolor, fillcolor, dash, ... % % Uncompatibility: The macro \drawline was introduced in version 2.1 to % draw a line between two points. The new version allows to draw a line % defined by an arbitrary number of points but the syntax is different. % It was \drawline(x1,y1,x2,y2) and it is now \drawline(x1,y1)(x2,y2). % % 2.3: % - added the parameter ELdistC (y or n) allowing to specify whether % the distance (ELdist) is between the center (y) of the label and the edge % or between the side (n) of the label and the edge. % The behaviour of previous gastex versions corresponds to the setting % (n) which is therefore the default. % - added the macro \drawqbpedge allowing to specify the auxiliary % point of a quadratic Bezier curve with two angles instead of the % absolute coordinates required by \drawqbedge. % - added parameters sxo, syo, exo, eyo (offsets in \unitlength). % They define offsets for the virtual starting and ending points of an % edge with respect to the centers of the starting and ending nodes. % - improved drawing for arrowheads (in gastex.pro). % First, the direction of the arrowhead is better for curved edges. % Second, when several arrowheads are drawn they follow the curve. % Previously, they followed the tangent at the ending point of the % edge which was bad for curved edges. % % 2.2: % - added the options slide and paper to the package. % In order to get the default settings for slides, use % \usepackage[slide]{gastex} % The default settings for papers is obtained with % \usepackage[paper]{gastex} % or % \usepackage{gastex} % - added new option loopCW to define whether loops are in % clockwise direction or not. % - Fix a TeX error (Arithmetic overflow) that occurred when using % \drawedge(A,B){} with two nodes A and B having the same coordinates. % Now, in this case, an error message is issued in the log % and the macro \drawedge(A,B){} is ignored. % % 2.1: % - New macros to draw directly circles, rectanges, ovals, % lines and bezier curves. % \drawcircle, \drawrect, \drawoval, % \drawline, \drawqbezier, \drawcbezier % All these macros use gasset options and in particular: % Nframe, Nfill, linecolor, fillcolor, dash, AHnb, etc... % - Compatibility mode for pspictpg up to v0.6 % - Fix the bug which occured sometimes when using Nw=0,Nh=0. % % 2.01: % - Fix an error that occured in v2.0 when using Nfill=y without % defining previously fillgray or fillcolor. % The following default setting has been added. % \gasset{fillgray=0,Nfill=n} % Not filled but black if filled % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % A lot of changes has been made since gastex 1.0 and as a result, % these new macros are no longer compatible with the previous ones. % To be able to use old pictures, a compatible mode is provided % (see \compatiblegastexun at the end of the file). The compatibility % is almost 100% and should be sufficient in most cases. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Known problems and (hopefully) solutions. % % 21/10/99: Frank Goertzen (frank.goertzen@unibw-muenchen.de) has % reported that when using gastex together with german an error may % occur when running dvips if the german package is loaded first. The % solution is to load gastex before german: % \usepackage{gastex} % \usepackage{german} % I have no idea concerning the cause of this error. % % 07/03/00: A postscript error may occur when using Nw=0,Nh=0. % Solution: Use a small value instead of 0, e.g. Nw=0.1,Nh=0.1 % Fixed in version 2.1. % % 27/10/00: Using gasset inside a tabular or an array produces an error. % The reason is that I'm using the "&" symbol as a marker in order to % process gasset options. % Solution: Include the whole picture inside an mbox. % \begin{tabular}{c} % \mbox{\begin{picture}(10,20)(-5,-5) % \gasset{ELdist=0} % \node(A)(0,0){1}\drawloop(A){$a$} % \end{picture}} % \end{tabular} % % pdflatex: gastex does not work with pdflatex since it produces % postscript code and pdflatex does not know what to do with it. % Solution: Use latex and then ps2pdf. % I don't know whether it is possible to translate my postscript code % into pdf code. The problem is that I'm using postscript to make some % computations and not only to draw the picture. % I would appreciate the help of a pdf guru on this. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Internal variables and macros %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \newcounter{cnt@a}\newcounter{cnt@b}\newcounter{cnt@c} \newdimen\dim@x \newdimen\dim@y \newbox\temp@box \newdimen\d@my@unit \d@my@unit=0.01mm % \d@my@unit is the unit used for all drawings with gastex. % All values given in \unitlength are converted in \d@my@unit. % The aim is to improve the precision of the drawings. {\catcode`t=12\catcode`p=12\gdef\no@PT#1pt{#1}} \def\strip@PT#1{\expandafter\no@PT\the#1\space} \def\gas@initps{!BP \gas@dash \line@width setlinewidth\space} \def\gas@AHparam{\AH@nb\AH@d\AH@angle\AH@L\AH@l} \def\gas@ATparam{\AT@nb\AT@d\AT@angle\AT@L\AT@l} \def\gas@ATnul{0 \AT@d\AT@angle\AT@L\AT@l} \def\gas@gobble#1{}% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Settings %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %----------------------------------------------------------------------- % Set values for gastex parameters. % % \gasset{parameter=value,parameter=value,...} % optional spaces are only allowed after commas % % Nw=number % widht in \unitlength of oval nodes % Nh=number % height in \unitlength of oval nodes % Nmr=number % maximal radius in \unitlength of oval nodes % The actual radius will be min(Nw/2,Nh/2,Nmr) % Nmr=0 yields a rectangle node % % Nadjust=any combination of the letters w,h,n % w : the node width is adjusted to the node label width + Nadjustdist % h : the node height is adjusted to the node label height + Nadjustdist % n : no adjustment % Nadjustdist=number % distance in \unitlength between the label box and the node frame % when using Nadjust % % Nframe=y or n % boolean flag defining whether nodes are framed or not. % Nfill=y or n % boolean flag defining whether nodes are filled or not. % Automatically set to true by the parameters fillgray and fillcolor % % ExtNL=y or n % boolean flag defining whether node labels are external or not. % NLangle=number % direction in degree of node labels % NLdist=number % The meaning depends on the ExtNL flag. % If the flag is set to "n" then NLdist defines the distance % in \unitlength between the node center and the label center. % If the flag is set to "y" then NLdist defines the distance % in \unitlength between the node frame and the label box. % % Nmarks=any combination of the letters i,f,r,n % i : initial mark on nodes % f : final mark on nodes % r : repeated mark on nodes % n : no mark on nodes % ilength=number % length in \unitlength of arrows marking initial nodes % iangle=number % direction in degree of arrows marking initial nodes % flength=number % length in \unitlength of arrows marking final nodes % fangle=number % direction in degree of arrows marking final nodes % rdist=number % distance in \unitlength between the lines of repeated nodes % a positive value draw the second line inside the normal one % a negative value draw the second line outside the normal one % but the edges are still connected to the normal line. % % An edge virtually starts from the center of the starting node and % ends at the center of the ending node (indeed they are only drawn % outside of the nodes). It is possible to change the virtual starting % and ending points of an edge using offsets with respect to the center % of the starting and ending node. This is the purpose of the following % parameters. % sxo=number (starting x offset) % horizontal offset in \unitlength of the starting point of an edge % with respect to the center of the starting node. % syo=number (starting y offset) % vertical offset in \unitlength of the starting point of an edge % with respect to the center of the starting node. % exo=number (ending x offset) % horizontal offset in \unitlength of the ending point of an edge % with respect to the center of the ending node. % eyo=number (ending y offset) % vertical offset in \unitlength of the ending point of an edge % with respect to the center of the ending node. % % curvedepth=number % depth in \unitlength of curved edges between two nodes % The absolute value of curvedepth defines the distance between the % middle of the curved edge and the center of the line joining the two nodes % With a positive/negative value the curved edge is on the left/right % of the line joining the two nodes. % % loopwidth=number % width in \unitlength of (vertical) loops % loopheight=number % height in \unitlength of (vertical) loops % loopdiam=number % width and height in \unitlength of (vertical) loops % loopangle=number % direction in degree of loops % loopCW=y or n % boolean flag defining whether loops are in clockwise direction or not. % % AHnb=number % number of arrow(s) at the head of edges. % 0 for no arrowhead. % AHdist=number % distance in \unitlength between two arrowheads % AHangle=angle % angle in degree between the edge and the arrowhead side % AHLength=number % Length in \unitlegth of the arrowhead side % AHlength=number % length in \unitlegth defining the shape of the arrowhead % 0 for an arrowhead formed with just two lines % Length*cos(angle) for a triangular arrowhead % See examples. % % ATnb=number % number of arrow(s) at the tail of edges. % 0 for no arrowhead. % ATdist=number % distance in \unitlength between two arrowtails % ATangle=angle % angle in degree between the edge and the arrowtail side % ATLength=number % Length in \unitlegth of the arrowtail side % ATlength=number % length in \unitlegth defining the shape of the arrowtail % 0 for an arrowtail formed with just two lines % Length*cos(angle) for a triangular arrowtail % See examples. % % ELside=l or r % label on the (l)eft or (r)ight side of the edge % ELpos=0..100 % position of the label along the edge. % 0 : starting node % 50 : middle of the edge % 100 : ending node % ELdist=number % distance in \unitlength between the label and the edge % ELdistC=y or n % y : The distance is between the center of the label and the edge. % With ELdist=0 the center of the label is on the edge. % n : The distance is between the side of the label and the edge. % This is the default. % The distance is actually between the side of the label and % the tangent of the edge which is usually a good approximation. % It may not work very well if the label is large and the edge is % strongly curved because then the tangent is far from the edge at the % point that achieve the distance between the tangent and the label. % % linegray=decimal number between 0 and 1 % gray level used to draw lines. 0=black, 1=white. % fillgray=decimal number between 0 and 1 % gray level used to fill nodes. 0=black, 1=white. % linecolor=ColorName % color used to draw lines. % The color name should be defined in dvipsnam.def and one should % include \usepackage[usenames]{color}. % This is to avoid the trouble of defining our own colors. % The drawback is that it is not possible to define and use other colors. % It should not be very restrictive since plenty of colours are % defined in dvipsnam.def. % It should not be difficult to add the possibility of using new % colors if needed. % fillcolor=ColorName % color used to fill nodes. See remarks above. % linewidth=number % width in \unitlegth of lines % dash={list of numbers}{offset} % Set the dash pattern used for drawing postscript paths. % The numbers in the list indicate alternately lengths % in \unitlength of dashes and lengths in \unitlength of spaces. % The list of lenghts is used circularly. % offset allows to start the pattern at some distance from its beginning. % Here are some examples: % dash={}{0} % continuous path % dash={1.5}0 % dashs of length 1.5 and empty spaces of length 1.5 % dash={0.2 0.5}0 % looks like a sequence of dots % dash={4 1 1 1}0 % alternation of long and short dashs % dash={1.5}{1.5} % we start with the empty space and not the dash % dash={4}{2} % we start in the middle of the first dash % % arcradius=number % radius in \unitlength of the arcs used at the vertices % of polygons and broken lines. 0 for sharp angles. % polyangle=angle % angle in degrees with respect to the x axis of the first vertex % of the regular polygon. % \def\gasset#1{\setkeys*[]{gastex}{#1}}% \define@key[]{gastex}{Nw}{% \setcounter{cnt@a}{1*\ratio{#1\unitlength}{\d@my@unit}} \edef\N@w{\thecnt@a}}% \define@key[]{gastex}{Nh}{% \setcounter{cnt@a}{1*\ratio{#1\unitlength}{\d@my@unit}} \edef\N@h{\thecnt@a}}% \define@key[]{gastex}{Nmr}{% \setcounter{cnt@a}{1*\ratio{#1\unitlength}{\d@my@unit}} \edef\N@mr{\thecnt@a}}% \newif\if@wadjust \newif\if@hadjust \newif\if@nadjust \define@key[]{gastex}{Nadjust}{% \@wadjustfalse \@hadjustfalse \gasset@@Nadjust #1&} \def\gasset@@Nadjust#1{% \@ifundefined{if@#1adjust} {\PackageWarning{gastex}{Node adjust #1 undefined}{}} {\csname @#1adjusttrue\endcsname}% \@ifnextchar&{\gas@gobble}{\gasset@@Nadjust}} \define@key[]{gastex}{Nadjustdist}{% \setcounter{cnt@a}{2*\ratio{#1\unitlength}{\d@my@unit}} \edef\N@adjustdist{\thecnt@a}}% \newif\if@frame \newif\if@fill \newif\if@ExtNL \newif\if@arcPie \def\flag@y{\relax}\def\flag@n{\relax} \define@key[]{gastex}{Nframe}{% \@ifundefined{flag@#1} {\PackageWarning{gastex}{Nframe value should be y or n}{}} {\if#1y \@frametrue \else \@framefalse \fi}} \define@key[]{gastex}{Nfill}{% \@ifundefined{flag@#1} {\PackageWarning{gastex}{Nfill value should be y or n}{}} {\if#1y \@filltrue \else \@fillfalse \fi}} \define@key[]{gastex}{ExtNL}{% \@ifundefined{flag@#1} {\PackageWarning{gastex}{ExtNL value should be y or n}{}} {\if#1y \@ExtNLtrue \else \@ExtNLfalse \fi}} \define@key[]{gastex}{arcPie}{% \@ifundefined{flag@#1} {\PackageWarning{gastex}{arcPie value should be y or n}{}} {\if#1y \@arcPietrue \else \@arcPiefalse \fi}} \define@key[]{gastex}{NLangle}{\edef\NL@angle{#1}}% \define@key[]{gastex}{NLdist}{% \setcounter{cnt@a}{1*\ratio{#1\unitlength}{\d@my@unit}} \edef\NL@dist{\thecnt@a}}% \newif\if@imark \newif\if@fmark \newif\if@rmark \newif\if@nmark \define@key[]{gastex}{Nmarks}{% \@imarkfalse \@fmarkfalse \@rmarkfalse \gasset@@Nmarks #1&} \def\gasset@@Nmarks#1{% \@ifundefined{if@#1mark} {\PackageWarning{gastex}{Node mark #1 undefined}{}} {\csname @#1marktrue\endcsname}% \@ifnextchar&{\gas@gobble}{\gasset@@Nmarks}} \define@key[]{gastex}{ilength}{% \setcounter{cnt@a}{1*\ratio{#1\unitlength}{\d@my@unit}} \edef\i@length{\thecnt@a}}% \define@key[]{gastex}{iangle}{\edef\i@angle{#1}}% \define@key[]{gastex}{flength}{% \setcounter{cnt@a}{1*\ratio{#1\unitlength}{\d@my@unit}} \edef\f@length{\thecnt@a}}% \define@key[]{gastex}{fangle}{\edef\f@angle{#1}}% \define@key[]{gastex}{rdist}{% \setcounter{cnt@a}{1*\ratio{#1\unitlength}{\d@my@unit}} \edef\rep@dist{\thecnt@a}}% \define@key[]{gastex}{sxo}{% \setcounter{cnt@a}{1*\ratio{#1\unitlength}{\d@my@unit}} \edef\E@sxo{\thecnt@a}}% \define@key[]{gastex}{syo}{% \setcounter{cnt@a}{1*\ratio{#1\unitlength}{\d@my@unit}} \edef\E@syo{\thecnt@a}}% \define@key[]{gastex}{exo}{% \setcounter{cnt@a}{1*\ratio{#1\unitlength}{\d@my@unit}} \edef\E@exo{\thecnt@a}}% \define@key[]{gastex}{eyo}{% \setcounter{cnt@a}{1*\ratio{#1\unitlength}{\d@my@unit}} \edef\E@eyo{\thecnt@a}}% \define@key[]{gastex}{curvedepth}{% \setcounter{cnt@a}{1*\ratio{#1\unitlength}{\d@my@unit}} \edef\curve@depth{\thecnt@a}}% \define@key[]{gastex}{loopwidth}{% \setcounter{cnt@a}{1*\ratio{#1\unitlength}{\d@my@unit}} \edef\loop@width{\thecnt@a}}% \define@key[]{gastex}{loopheight}{% \setcounter{cnt@a}{1*\ratio{#1\unitlength}{\d@my@unit}} \edef\loop@height{\thecnt@a}}% \define@key[]{gastex}{loopdiam}{% \setcounter{cnt@a}{1*\ratio{#1\unitlength}{\d@my@unit}} \edef\loop@width{\thecnt@a}% \edef\loop@height{\thecnt@a}}% \define@key[]{gastex}{loopangle}{\edef\loop@angle{#1}}% \newif\if@loopCW \define@key[]{gastex}{loopCW}{% \@ifundefined{flag@#1} {\PackageWarning{gastex}{loopCW value should be y or n}{}} {\if#1y \@loopCWtrue \else \@loopCWfalse \fi}} \define@key[]{gastex}{AHnb}{\edef\AH@nb{#1\space}}% \define@key[]{gastex}{AHdist}{% \dim@x=#1\unitlength \edef\AH@d{\strip@PT\dim@x}}% \define@key[]{gastex}{AHangle}{\edef\AH@angle{#1\space}}% \define@key[]{gastex}{AHLength}{% \dim@x=#1\unitlength \edef\AH@L{\strip@PT\dim@x}}% \define@key[]{gastex}{AHlength}{% \dim@x=#1\unitlength \edef\AH@l{\strip@PT\dim@x}}% \define@key[]{gastex}{ATnb}{\edef\AT@nb{#1\space}}% \define@key[]{gastex}{ATdist}{% \dim@x=#1\unitlength \edef\AT@d{\strip@PT\dim@x}}% \define@key[]{gastex}{ATangle}{\edef\AT@angle{#1\space}}% \define@key[]{gastex}{ATLength}{% \dim@x=#1\unitlength \edef\AT@L{\strip@PT\dim@x}}% \define@key[]{gastex}{ATlength}{% \dim@x=#1\unitlength \edef\AT@l{\strip@PT\dim@x}}% \def\ELside@l{\relax}\def\ELside@r{\relax} \define@key[]{gastex}{ELside}{% \@ifundefined{ELside@#1} {\PackageWarning{gastex}{ELside value should be l or r}{}} {\edef\EL@s{#1}}}% \define@key[]{gastex}{ELpos}{ \ifnum#1>100 \PackageWarning{gastex}{ELpos value should be between 0 and 100}{} \else\ifnum#1<0 \PackageWarning{gastex}{ELpos value should be between 0 and 100}{} \else\edef\EL@p{#1}\fi\fi}% \define@key[]{gastex}{ELdist}{% \setcounter{cnt@a}{1*\ratio{#1\unitlength}{\d@my@unit}} \edef\EL@dist{\thecnt@a}}% \newif\if@ELdistC \define@key[]{gastex}{ELdistC}{% \@ifundefined{flag@#1} {\PackageWarning{gastex}{ELdistC value should be y or n}{}} {\if#1y \@ELdistCtrue \else \@ELdistCfalse \fi}} \def\gas@rgb@model{setrgbcolor}% \def\gas@cmyk@model{setcmykcolor}% \def\gas@gray@model{setgray}% \def\gas@color#1#2{\@ifundefined{gas@#1@model}% {\PackageWarning{gastex}{Color model '#1' not supported}{}} {\def\gas@tmp@col{}\gas@recode #2,&}% \edef\gas@tmp@col{\gas@tmp@col\csname gas@#1@model\endcsname}}% \def\gas@recode#1,{\edef\gas@tmp@col{\gas@tmp@col #1 }% \@ifnextchar&{\gas@gobble}{\gas@recode}} \define@key[]{gastex}{linegray}{\edef\line@color{#1 setgray\space}}% \define@key[]{gastex}{linecolor}{\@ifundefined{extractcolorspec}% {\@ifundefined{\string\color @#1} {\PackageWarning{gastex}{Color #1 undefined}{}} {\edef\line@color{#1\space}}}% {\extractcolorspec{#1}{\gas@tmp@color}% \expandafter\gas@color\gas@tmp@color% \edef\line@color{\gas@tmp@col\space}}}% \define@key[]{gastex}{fillgray}{\@filltrue\edef\fill@color{#1 setgray\space}}% \define@key[]{gastex}{fillcolor}{\@ifundefined{extractcolorspec}% {\@ifundefined{\string\color @#1} {\PackageWarning{gastex}{Color #1 undefined}{}} {\@filltrue\edef\fill@color{#1\space}}}% {\extractcolorspec{#1}{\gas@tmp@color}% \expandafter\gas@color\gas@tmp@color% \@filltrue\edef\fill@color{\gas@tmp@col\space}}}% \define@key[]{gastex}{linewidth}{% \dim@x=#1\unitlength \edef\line@width{\strip@PT\dim@x}}% \define@key[]{gastex}{dash}{\gasset@@dash #1}% \def\gasset@@dash#1#2{% \def\gas@dash{[}% \gas@convert 0 #1 & \dim@x=#2\unitlength \edef\gas@dash{\gas@dash] \strip@PT\dim@x setdash\space}}% \def\gas@convert#1 {% \dim@x=#1\unitlength \ifdim\dim@x=0pt\else\edef\gas@dash{\gas@dash\strip@PT\dim@x}\fi% \@ifnextchar&{\gas@gobble}{\gas@convert}} \define@key[]{gastex}{arcradius}{% \dim@x=#1\unitlength \edef\arc@radius{\strip@PT\dim@x}}% \define@key[]{gastex}{polyangle}{\edef\poly@angle{#1}}% \define@key[]{gastex}{snakew}{% \setcounter{cnt@a}{1*\ratio{#1\unitlength}{\d@my@unit}} \edef\snake@w{\thecnt@a}}% \define@key[]{gastex}{snakeh}{% \setcounter{cnt@a}{1*\ratio{#1\unitlength}{\d@my@unit}} \edef\snake@h{\thecnt@a}}% %----------------------------------------------------------------------- % Default settings \unitlength=1mm \gasset{Nw=8,Nh=8,Nmr=4} % circle \gasset{Nframe=y,arcPie=n} \gasset{fillgray=0,Nfill=n} % Not filled but black if filled \gasset{ExtNL=n,NLangle=90,NLdist=0} \gasset{iangle=180,ilength=5} \gasset{fangle=0,flength=5} \gasset{rdist=0.7} \gasset{Nmarks=n} % no mark \gasset{Nadjustdist=1,Nadjust=n} % no adjust \gasset{sxo=0,syo=0,exo=0,eyo=0} \gasset{curvedepth=0} \gasset{loopdiam=8,loopangle=90,loopCW=y} % One triangular small arrowhead \gasset{AHnb=1,AHdist=1.41,AHangle=20,AHLength=1.5,AHlength=1.41} \gasset{ATnb=0,ATdist=1.41,ATangle=20,ATLength=1.5,ATlength=1.41} \gasset{ELside=l,ELpos=50,ELdist=1} \gasset{linegray=0} % black lines \gasset{linewidth=0.14,dash={}0} % continuous path \gasset{arcradius=0,polyangle=0} % sharp angles \gasset{snakew=2,snakeh=1} % width and height of snake waves % Settings for slides \ifgastexslide \gasset{Nw=12,Nh=12,Nmr=6,ilength=8,flength=8,rdist=1,loopdiam=12} \gasset{linewidth=0.21,AHdist=2.1,AHLength=2.25,AHlength=2.1} \gasset{ATdist=2.1,ATLength=2.25,ATlength=2.1} \fi %%%%%%%%%%% NEW FOR MD5 %%%%%%%%%%%%%%%%%%%%%%%%%%% \newif\if@picthavechanged\@picthavechangedfalse \def\g@cstocheckmdfive#1{\expandafter\def\csname cs@#1\endcsname{\relax}}% \def\g@check@mdfive#1#2{% #1 is the pict number, #2 is the new md5 \@ifundefined{g@oldmdfive@#1}{\global\@picthavechangedtrue% \immediate\write 2 {!pict #1 has changed!}}{% % This is my way of testing whether the old and new md5 are equal \g@cstocheckmdfive{\csname g@oldmdfive@#1\endcsname}% \@ifundefined{cs@#2}{\global\@picthavechangedtrue% \immediate\write 2 {!pict #1 has changed!}}{}}% } \def\g@mdfivemsg{\if@picthavechanged% \PackageWarning{gastex}{Pictures have changed. Compile once more}% \fi} \ifgastex@mdfive \AtBeginDocument{\immediate\openout2 = "\g@hashfilename"}% \AtEndDocument{\immediate\closeout2 \g@mdfivemsg}% \fi %%%%%%%%%%% NEW FOR AUTO-PST-PDF %%%%%%%%%%%%%%%%%%%%%%%%%%% \newcounter{g@cnt@pict}\setcounter{g@cnt@pict}{0}% \define@cmdkeys[]{gastex}{name} \define@boolkey[]{gastex}{frame}[true]{\ifgastex@pdflatex\setkeys*{Gin}{frame=#1}\fi} % \long\def\g@normalpicture(#1)(#2)#3&g@stex&{% \begin{picture}(#1)(#2)\nullfont% \ifgastex@frame\put(#2){{\unitlength=1mm\gasset{linewidth=0.05}}\drawrect[Nfill=n](0,0,#1)}\fi #3 \end{picture}}% % \long\def\g@pdfpicture(#1,#2)(#3,#4)#5&g@stex&{{% \begin{postscript}\special{header=gastex.pro}% \begin{picture}(#1,#2)(#3,#4)\nullfont% #5 \end{picture}% \end{postscript}% }}% % \long\def\g@picture#1{\@ifnextchar({\g@@picture}{\g@@picture(10,10)}#1&g@stex&}% % \long\def\g@@picture(#1)#2&g@stex&{% \ifgastex@pdflatex% \@ifnextchar({\g@pdfpicture(#1)}{\g@pdfpicture(#1)(0,0)}#2&g@stex&% \else% \@ifnextchar({\g@normalpicture(#1)}{\g@normalpicture(#1)(0,0)}#2&g@stex&% \fi% }% % \NewEnviron{gpicture}[1][]{{% \gasset{#1}% % \let\g@opt@Gin=\XKV@rm% \setrmkeys*{Gin}% \expandafter\g@picture\expandafter{\BODY}% \refstepcounter{g@cnt@pict}% \ifgastex@mdfive% \xdef\g@lastmdfive{\pdfmdfivesum{\meaning\BODY}}% \gsavepicture{\g@lastmdfive}% \immediate\write 2 {:md5 of pict:\theg@cnt@pict:\g@lastmdfive:}% \g@check@mdfive{\theg@cnt@pict}{\g@lastmdfive}% \fi% \@ifundefined{cmdgastex@name}{}{\gsavepicture{\cmdgastex@name}}% % \ifGin@ignore\else\gusepicture[\g@opt@Gin]{\g@lastmdfive}\fi% }} % [\gusepicture[\g@opt@Gin]{\g@lastmdfive}\ignorespacesafterend] % % I define alternate versions of \savepicture and \usepicture since the ones % from pst-pdf do not work properly (at least not as I expect). \def\gsavepicture#1{\expandafter\xdef\csname ppf@@@#1\endcsname{\theg@cnt@pict}}% % \newcommand\gusepicture[2][]{% \ifgastex@pdflatex% \@ifundefined{ppf@@@#2}{\usepicture[#1]{#2}}{% \usepicture[#1]{\csname ppf@@@#2\endcsname}}% \else% \PackageWarning{gastex}{gusepicture is not available when pdflatex option of gastex.sty is not set (to true)}\relax% \fi} % \tracingonline=1 % \tracingmacros=1 % \tracingcommands=1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Nodes %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %----------------------------------------------------------------------- % Define and draw a node whose shape is a regular polygon. % % \rpnode(NodeName)(x,y)(n,r){NodeLabel} % \rpnode[parameter=value,...](NodeName)(x,y)(n,r){NodeLabel} % % Required arguments: % NodeName : name of the node % x,y : coordinates in \unitlengh of the node (center of the polygon). % n : number of sides of the polygon. % r : radius in \unitlengh of the circle containing the polygon. % NodeLabel : label of the node. Empty if no label. % Optional argument: (in particular, polyangle and arcradius) % [parameter=value,...] % One may just define a node without drawing it using an empty label % and the parameters Nframe=n,Nfill=n \def\rpnode#1(#2)(#3)(#4)#5{{% \@ifnextchar[{\process@rpnodeopt}{\rp@node}#1(#2)(#3)(#4){#5}}} \def\process@rpnodeopt[#1]{\gasset{#1}\rp@node}% \def\rp@node(#1)(#2,#3)(#4,#5)#6{{% % The value -1 assigned to node@#1@w characterizes polygonal nodes \global\expandafter\edef\csname node@#1@w\endcsname{-1}% \setcounter{cnt@a}{1*\ratio{#2\unitlength}{\d@my@unit}} \global\expandafter\edef\csname node@#1@x\endcsname{\thecnt@a}% \setcounter{cnt@a}{1*\ratio{#3\unitlength}{\d@my@unit}} \global\expandafter\edef\csname node@#1@y\endcsname{\thecnt@a}% \global\expandafter\edef\csname node@#1@n\endcsname{#4}% \setcounter{cnt@a}{1*\ratio{#5\unitlength}{\d@my@unit}} \global\expandafter\edef\csname node@#1@rad\endcsname{\thecnt@a}% \global\expandafter\edef\csname node@#1@a\endcsname{\poly@angle}% % Definition of the polygonal path for the node \dim@x=\csname node@#1@x\endcsname\d@my@unit \dim@y=\csname node@#1@y\endcsname\d@my@unit \edef\ps@path{\strip@PT\dim@x\strip@PT\dim@y\csname node@#1@n\endcsname\space}% \dim@x=\csname node@#1@rad\endcsname\d@my@unit \edef\ps@path{\ps@path \strip@PT\dim@x \csname node@#1@a\endcsname\space}% \edef\ps@path{\ps@path \arc@radius 0 !psrpolygonpath\space}% \global\expandafter\edef\csname node@#1@path\endcsname{\ps@path}% \put(0,0){\special{" \gas@initps \if@fill \fill@color \csname node@#1@path\endcsname fill \fi \if@frame \line@color \csname node@#1@path\endcsname stroke \fi }} \if@imark \imark(#1) \fi \if@fmark \fmark(#1) \fi \if@rmark \rmark(#1) \fi % \@ExtNLfalse \nodelabel(#1){#6} }} %----------------------------------------------------------------------- % Define and draw a node. % % \node(NodeName)(x,y){NodeLabel} % \node[parameter=value,...](NodeName)(x,y){NodeLabel} % % Required arguments: % NodeName : name of the node % (x,y) : coordinates of the node in \unitlengh. % NodeLabel : label of the node. Empty if no label. % Optional argument: % [parameter=value,...] % One may just define a node without drawing it using an empty label % and the parameters Nframe=n,Nfill=n \def\node#1(#2)(#3,#4)#5{{% \@ifnextchar[{\process@nodeopt}{\i@node}#1(#2)(#3,#4){#5}}} \def\process@nodeopt[#1]{\gasset{#1}\i@node}% \def\i@node(#1)(#2,#3)#4{% \let@node(#1)(#2,#3){#4}\draw@node(#1){#4}} %----------------------------------------------------------------------- % Define a node without drawing it. % Internal macro also used in \compatiblegastexun. % % \let@node(NodeName)(x,y){NodeLabel} % % Required arguments: % NodeName : name of the node % x,y : coordinates of the node in \unitlengh. % NodeLabel : label of the node. Empty if no label. \def\let@node(#1)(#2,#3)#4{{% % width and height of the box containing #4 \setbox\temp@box\hbox{\selectfont #4} \if@wadjust \setcounter{cnt@a}{\N@adjustdist + \wd\temp@box / \d@my@unit} \edef\N@w{\thecnt@a}% \fi \if@hadjust \setcounter{cnt@a}{\N@adjustdist + (\ht\temp@box+\dp\temp@box) / \d@my@unit} \edef\N@h{\thecnt@a}% \fi \global\expandafter\edef\csname node@#1@w\endcsname{\N@w}% \global\expandafter\edef\csname node@#1@h\endcsname{\N@h}% \ifnum\N@h<\N@w \setcounter{cnt@a}{\N@h/2} \else \setcounter{cnt@a}{\N@w/2} \fi \ifnum\N@mr<\thecnt@a\setcounter{cnt@a}{\N@mr}\fi \global\expandafter\edef\csname node@#1@r\endcsname{\thecnt@a}% \setcounter{cnt@a}{1*\ratio{#2\unitlength}{\d@my@unit}} \global\expandafter\edef\csname node@#1@x\endcsname{\thecnt@a}% \setcounter{cnt@a}{1*\ratio{#3\unitlength}{\d@my@unit}} \global\expandafter\edef\csname node@#1@y\endcsname{\thecnt@a}% % Definition of the oval path for the node \dim@x=#2\unitlength \edef\ps@path{\strip@PT\dim@x}% \dim@x=#3\unitlength \edef\ps@path{\ps@path \strip@PT\dim@x}% \dim@x=\N@w\d@my@unit \edef\ps@path{\ps@path \strip@PT\dim@x}% \dim@x=\N@h\d@my@unit \edef\ps@path{\ps@path \strip@PT\dim@x}% \dim@x=\N@mr\d@my@unit \edef\ps@path{\ps@path \strip@PT\dim@x}% \edef\ps@path{\ps@path !psovalpath\space}% \global\expandafter\edef\csname node@#1@path\endcsname{\ps@path}% }} %----------------------------------------------------------------------- % Draw a node which is already defined. Internal macro. % % \draw@node(NodeName){NodeLabel} % % Required arguments: % NodeName : name of the node % NodeLabel : label of the node. Empty if no label. \def\draw@node(#1)#2{{% \put(0,0){\special{" \gas@initps \if@fill \fill@color \csname node@#1@path\endcsname fill \fi \if@frame \line@color \csname node@#1@path\endcsname stroke \fi }} \if@imark \imark(#1) \fi \if@fmark \fmark(#1) \fi \if@rmark \rmark(#1) \fi \nodelabel(#1){#2} }} %----------------------------------------------------------------------- % Add an ingoing arrow to mark an initial node. % This arrow is usually drawn by \node using Nmarks=i. % This separate macro can be used to draw several arrows % or arrows with different colors, thickness, dash, ... % % \imark(NodeName) % \imark[parameter=value,...](NodeName) % % Required arguments: % NodeName : name of the node % Optional argument: % [parameter=value,...] \def\imark#1(#2){{% \@ifnextchar[{\process@imarkopt}{\i@mark}#1(#2)}} \def\process@imarkopt[#1]{\gasset{#1}\i@mark}% \def\i@mark(#1){{% \dim@x=\csname node@#1@x\endcsname\d@my@unit \edef\ps@par{\strip@PT\dim@x}% \dim@x=\csname node@#1@y\endcsname\d@my@unit \edef\ps@par{\ps@par \strip@PT\dim@x}% \dim@x=\i@length\d@my@unit \edef\ps@par{\ps@par \strip@PT\dim@x \i@angle\space}% \put(0,0){\special{" \gas@initps \line@color % Path around the node \csname node@#1@path\endcsname /path!a false upath cvlit def \gas@ATnul \gas@AHparam \ps@par !node_mark}} }} %----------------------------------------------------------------------- % Add an outgoing arrow to mark a final node. % This arrow is usually drawn by \node using Nmarks=f. % This separate macro can be used to draw several arrows % or arrows with different colors, thickness, dash, ... % % \fmark(NodeName) % \fmark[parameter=value,...](NodeName) % % Required arguments: % NodeName : name of the node % Optional argument: % [parameter=value,...] \def\fmark#1(#2){{% \@ifnextchar[{\process@fmarkopt}{\f@mark}#1(#2)}} \def\process@fmarkopt[#1]{\gasset{#1}\f@mark}% \def\f@mark(#1){{% \dim@x=\csname node@#1@x\endcsname\d@my@unit \edef\ps@par{\strip@PT\dim@x}% \dim@x=\csname node@#1@y\endcsname\d@my@unit \edef\ps@par{\ps@par \strip@PT\dim@x}% \dim@x=\f@length\d@my@unit \edef\ps@par{\ps@par \strip@PT\dim@x \f@angle\space}% \put(0,0){\special{" \gas@initps \line@color % Path around the node \csname node@#1@path\endcsname /path!a false upath cvlit def \gas@AHparam \gas@ATnul \ps@par !node_mark}} }} %----------------------------------------------------------------------- % Add a second line to mark a repeated node. % This line is usually drawn by \node using Nmarks=r. % This separate macro can be used to draw several lines around the % node or lines with different colors, thickness, dash, ... % % \rmark(NodeName) % \rmark[parameter=value,...](NodeName) % % Required arguments: % NodeName : name of the node % Optional argument: % [parameter=value,...] \def\rmark#1(#2){{% \@ifnextchar[{\process@rmarkopt}{\r@mark}#1(#2)}} \def\process@rmarkopt[#1]{\gasset{#1}\r@mark}% \def\r@mark(#1){{% \ifnum\csname node@#1@w\endcsname=-1 % then it's a polygonal node \dim@x=\csname node@#1@x\endcsname\d@my@unit \edef\ps@path{\strip@PT\dim@x}% \dim@x=\csname node@#1@y\endcsname\d@my@unit \edef\ps@path{\ps@path \strip@PT\dim@x}% \edef\ps@path{\ps@path \csname node@#1@n\endcsname\space}% \dim@x=\csname node@#1@rad\endcsname\d@my@unit \edef\ps@path{\ps@path \strip@PT\dim@x}% \edef\ps@path{\ps@path \csname node@#1@a\endcsname\space}% \dim@y=\rep@dist\d@my@unit \edef\ps@path{\ps@path \arc@radius \strip@PT\dim@y !psrpolygonpath\space}% \put(0,0){\special{" \gas@initps \line@color \ps@path stroke}} \else % it's an oval node \dim@x=\csname node@#1@x\endcsname\d@my@unit \edef\ps@path{\strip@PT\dim@x}% \dim@x=\csname node@#1@y\endcsname\d@my@unit \edef\ps@path{\ps@path \strip@PT\dim@x}% \dim@y=-\rep@dist\d@my@unit \dim@x=\csname node@#1@w\endcsname\d@my@unit \advance\dim@x\dim@y\advance\dim@x\dim@y \edef\ps@path{\ps@path \strip@PT\dim@x}% \dim@x=\csname node@#1@h\endcsname\d@my@unit \advance\dim@x\dim@y\advance\dim@x\dim@y \edef\ps@path{\ps@path \strip@PT\dim@x}% \dim@x=\csname node@#1@r\endcsname\d@my@unit \advance\dim@x\dim@y \edef\ps@path{\ps@path \strip@PT\dim@x}% \put(0,0){\special{" \gas@initps \line@color \ps@path !psovalpath stroke}} \fi }} %----------------------------------------------------------------------- % Add a label to the node. % The position of the label is determined by the ExtNL flag % and the parameters NLangle and NLdist. % The label is usually drawn by \node. % This separate macro can be used to add several labels % % \nodelabel(NodeName){NodeLabel} % \nodelabel[parameter=value,...](NodeName){NodeLabel} % % Required arguments: % NodeName : name of the node % NodeLabel : label of the node. % Optional argument: % [parameter=value,...] \newif\if@cosneg \newif\if@sinneg \def\nodelabel#1(#2)#3{{% \@ifnextchar[{\process@nodelabelopt}{\node@label}#1(#2){#3}}} \def\process@nodelabelopt[#1]{\gasset{#1}\node@label}% \def\node@label(#1)#2{{% \unitlength=\d@my@unit \edef\cs@x{\csname node@#1@x\endcsname}% \edef\cs@y{\csname node@#1@y\endcsname}% \if@ExtNL \node@diam(#1,\NL@angle) \setcounter{cnt@a}{\cs@nd/2}\edef\cs@nr{\thecnt@a}% % width and height of the box containing #2 \setbox\temp@box\hbox{\selectfont #2} \setcounter{cnt@a}{\wd\temp@box / \d@my@unit} \edef\cs@bw{\thecnt@a}% \setcounter{cnt@a}{(\ht\temp@box+\dp\temp@box) / \d@my@unit} \edef\cs@bh{\thecnt@a}% % \@cosnegfalse \@sinnegfalse \dim@x=\cs@cos pt \ifnum \dim@x<0 \@cosnegtrue \dim@x=-\dim@x \fi \edef\cs@abscos{\strip@PT\dim@x}% \dim@x=\cs@sin pt \ifnum \dim@x<0 \@sinnegtrue \dim@x=-\dim@x \fi \edef\cs@abssin{\strip@PT\dim@x}% % \ifnum\csname node@#1@w\endcsname=-1 % then it's a polygonal node \setcounter{cnt@c}{\cs@nr+\NL@dist+% (\cs@bw*\real{\cs@abscos}+\cs@bh*\real{\cs@abssin})/2} \setcounter{cnt@a}{\cs@x+\thecnt@c*\real{\cs@cos}} \setcounter{cnt@b}{\cs@y+\thecnt@c*\real{\cs@sin}} \put(\thecnt@a,\thecnt@b){\makebox(0,0){\selectfont #2}} \else % it's an oval node \setcounter{cnt@a}{((\cs@h+\cs@bh)/2+\NL@dist)*\real{\cs@abscos}} \setcounter{cnt@b}{((\cs@w+\cs@bw)/2-\cs@r)*\real{\cs@abssin}} \ifnum\thecnt@a<\thecnt@b \setcounter{cnt@c}{(\cs@h+\cs@bh)/2+\NL@dist} \if@sinneg \setcounter{cnt@c}{-\thecnt@c} \fi \setcounter{cnt@a}{\cs@x+\thecnt@c*\real{\cs@cos}/\real{\cs@sin}} \setcounter{cnt@b}{\cs@y+\thecnt@c} \put(\thecnt@a,\thecnt@b){\makebox(0,0){\selectfont #2}} \else \setcounter{cnt@a}{((\cs@w+\cs@bw)/2+\NL@dist)*\real{\cs@abssin}} \setcounter{cnt@b}{((\cs@h+\cs@bh)/2-\cs@r)*\real{\cs@abscos}} \ifnum\thecnt@a<\thecnt@b \setcounter{cnt@c}{(\cs@w+\cs@bw)/2+\NL@dist} \if@cosneg \setcounter{cnt@c}{-\thecnt@c} \fi \setcounter{cnt@a}{\cs@x+\thecnt@c} \setcounter{cnt@b}{\cs@y+\thecnt@c*\real{\cs@sin}/\real{\cs@cos}} \put(\thecnt@a,\thecnt@b){\makebox(0,0){\selectfont #2}} \else % auxiliary parameters \setcounter{cnt@a}{\cs@r-(\cs@w+\cs@bw)/2} \edef\cs@xx{\thecnt@a}% \setcounter{cnt@a}{\cs@r-(\cs@h+\cs@bh)/2} \edef\cs@yy{\thecnt@a}% \setcounter{cnt@a}{(\cs@r+\NL@dist)*(\cs@r+\NL@dist)} \edef\cs@lim{\thecnt@a}% \def\cs@tmin{0}% \setcounter{cnt@a}{\NL@dist+(\cs@bw+\cs@bh)/2} \edef\cs@tmax{\thecnt@a}% % computation of the center of the label \setcounter{cnt@c}{10} \@whilenum\thecnt@c>0\do{ \setcounter{cnt@a}{(\cs@tmin+\cs@tmax)/2} \edef\cs@t{\thecnt@a}% \setcounter{cnt@a}{(\cs@nr+\cs@t)*\real{\cs@abscos}+\cs@xx} \setcounter{cnt@b}{(\cs@nr+\cs@t)*\real{\cs@abssin}+\cs@yy} \setcounter{cnt@a}{\thecnt@a*\thecnt@a + \thecnt@b*\thecnt@b} \ifnum\thecnt@a<\cs@lim \edef\cs@tmin{\cs@t}% \else \edef\cs@tmax{\cs@t}% \fi \addtocounter{cnt@c}{-1}} \setcounter{cnt@a}{\cs@x+(\cs@nr+\cs@t)*\real{\cs@cos}} \setcounter{cnt@b}{\cs@y+(\cs@nr+\cs@t)*\real{\cs@sin}} \put(\thecnt@a,\thecnt@b){\makebox(0,0){\selectfont #2}} \fi \fi \fi \else % regular node label \CalculateCos{\NL@angle} \edef\cs@cos{\UseCos{\NL@angle}}% \CalculateSin{\NL@angle} \edef\cs@sin{\UseSin{\NL@angle}}% \setcounter{cnt@a}{\cs@x+\NL@dist*\real{\cs@cos}} \setcounter{cnt@b}{\cs@y+\NL@dist*\real{\cs@sin}} \put(\thecnt@a,\thecnt@b){\makebox(0,0){\selectfont #2}} \fi }} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Edges %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %----------------------------------------------------------------------- % Edge between two nodes. % % \drawedge(startingNode,endingNode){label} % \drawedge[parameter=value,...](startingNode,endingNode){label} % % Required arguments: % startingNode : name of the starting node, % endingNode : name of the ending node, % label : label of the edge. {} for no label. % Optional argument: % [parameter=value,...] \def\drawedge#1(#2)#3{{% \@ifnextchar[{\process@edgeopt}{\draw@edge}#1(#2){#3}}} \def\process@edgeopt[#1]{\gasset{#1}\draw@edge}% \def\draw@edge(#1,#2)#3{% % Control points of the cubic Bezier curve \setcounter{cnt@a}{\csname node@#1@x\endcsname + \E@sxo}% \edef\cs@xa{\thecnt@a}% \setcounter{cnt@a}{\csname node@#1@y\endcsname + \E@syo}% \edef\cs@ya{\thecnt@a}% \setcounter{cnt@a}{\csname node@#2@x\endcsname + \E@exo}% \edef\cs@xd{\thecnt@a}% \setcounter{cnt@a}{\csname node@#2@y\endcsname + \E@eyo}% \edef\cs@yd{\thecnt@a}% \setcounter{cnt@a}{\cs@xd-\cs@xa} \setcounter{cnt@b}{\cs@yd-\cs@ya} \setcounter{cnt@c}{\thecnt@a*\thecnt@a+\thecnt@b*\thecnt@b} \ifnum\thecnt@c=0 \PackageError{gastex}{drawedge(#1,#2)}{} \typeout{The starting and ending nodes should not have the same coordinates.} \else \gas@sqrt{\thecnt@c} \setcounter{cnt@b}{\cs@xa+\cs@xd-4*\curve@depth*(\cs@yd-\cs@ya)/\the@sqrt} \setcounter{cnt@a}{(\thecnt@b+\cs@xa)/3}\edef\cs@xb{\thecnt@a}% \setcounter{cnt@a}{(\thecnt@b+\cs@xd)/3}\edef\cs@xc{\thecnt@a}% \setcounter{cnt@b}{\cs@ya+\cs@yd+4*\curve@depth*(\cs@xd-\cs@xa)/\the@sqrt} \setcounter{cnt@a}{(\thecnt@b+\cs@ya)/3}\edef\cs@yb{\thecnt@a}% \setcounter{cnt@a}{(\thecnt@b+\cs@yd)/3}\edef\cs@yc{\thecnt@a}% \unitlength=\d@my@unit \draw@b@edge(#1,#2){#3} \fi } %----------------------------------------------------------------------- % Edge between two nodes following a quadratic Bezier curve. % The first and last control points are the centers of the starting % and ending nodes resp, modified with the starting and ending offsets. % The middle control point is given by its absolute cartesian coordinates % % \drawqbedge(startingNode,x,y,endingNode){label} % \drawqbedge[parameter=value,...](startingNode,x,y,endingNode){label} % % Required arguments: % startingNode : name of the starting node, % x,y : coordinates in \unitlength of the intermediary control point % endingNode : name of the ending node, % label : label of the edge. {} for no label. % Optional argument: % [parameter=value,...] \def\drawqbedge#1(#2)#3{{% \@ifnextchar[{\process@qbedgeopt}{\draw@qbedge}#1(#2){#3}}} \def\process@qbedgeopt[#1]{\gasset{#1}\draw@qbedge}% \def\draw@qbedge(#1,#2,#3,#4)#5{% % Control points of the cubic Bezier curve \setcounter{cnt@a}{\csname node@#1@x\endcsname + \E@sxo}% \edef\cs@xa{\thecnt@a}% \setcounter{cnt@a}{\csname node@#1@y\endcsname + \E@syo}% \edef\cs@ya{\thecnt@a}% \setcounter{cnt@a}{\csname node@#4@x\endcsname + \E@exo}% \edef\cs@xd{\thecnt@a}% \setcounter{cnt@a}{\csname node@#4@y\endcsname + \E@eyo}% \edef\cs@yd{\thecnt@a}% \setcounter{cnt@b}{2*\ratio{#2\unitlength}{\d@my@unit}} \setcounter{cnt@a}{(\cs@xa+\thecnt@b)/3}\edef\cs@xb{\thecnt@a}% \setcounter{cnt@a}{(\cs@xd+\thecnt@b)/3}\edef\cs@xc{\thecnt@a}% \setcounter{cnt@b}{2*\ratio{#3\unitlength}{\d@my@unit}} \setcounter{cnt@a}{(\cs@ya+\thecnt@b)/3}\edef\cs@yb{\thecnt@a}% \setcounter{cnt@a}{(\cs@yd+\thecnt@b)/3}\edef\cs@yc{\thecnt@a}% \unitlength=\d@my@unit \draw@b@edge(#1,#4){#5} } %----------------------------------------------------------------------- % Edge between two nodes following a quadratic Bezier curve. % The first and last control points are the centers of the starting % and ending nodes resp, modified with the starting and ending offsets. % The middle control point is defined by two angles. % % \drawqbpedge(startingNode,sa,endingNode,ea){label} % \drawqbpedge[parameter=value,...](startingNode,sa,endingNode,ea){label} % % Required arguments: % startingNode : name of the starting node, % endingNode : name of the ending node, % sa,ea : angles in degree at the starting and ending nodes, % these angles define intermediary control point % label : label of the edge. {} for no label. % Optional argument: % [parameter=value,...] \def\drawqbpedge#1(#2)#3{{% \@ifnextchar[{\process@qbpedgeopt}{\draw@qbpedge}#1(#2){#3}}} \def\process@qbpedgeopt[#1]{\gasset{#1}\draw@qbpedge}% \def\draw@qbpedge(#1,#2,#3,#4)#5{% % Control points of the cubic Bezier curve \setcounter{cnt@a}{\csname node@#1@x\endcsname + \E@sxo}% \edef\cs@xa{\thecnt@a}% \setcounter{cnt@a}{\csname node@#1@y\endcsname + \E@syo}% \edef\cs@ya{\thecnt@a}% \setcounter{cnt@a}{\csname node@#3@x\endcsname + \E@exo}% \edef\cs@xd{\thecnt@a}% \setcounter{cnt@a}{\csname node@#3@y\endcsname + \E@eyo}% \edef\cs@yd{\thecnt@a}% \edef\cs@sangle{#2}% \CalculateCos\cs@sangle \CalculateSin\cs@sangle \edef\cs@eangle{#4}% \CalculateCos\cs@eangle \CalculateSin\cs@eangle \setcounter{cnt@a}{1000*\real{\UseCos\cs@sangle}*\real{\UseSin\cs@eangle} -1000*\real{\UseSin\cs@sangle}*\real{\UseCos\cs@eangle}} \ifnum\thecnt@a=0 \PackageError{gastex}{drawqbpedge(#1,#2,#3,#4)}{} \typeout{The angles do not allow to compute the intersection point.} \else \setcounter{cnt@c}{((\cs@xd-\cs@xa)*1000*\real{\UseSin\cs@eangle} -(\cs@yd-\cs@ya)*1000*\real{\UseCos\cs@eangle}) /\thecnt@a} \setcounter{cnt@b}{2*(\cs@xa+\thecnt@c*\real{\UseCos\cs@sangle})} \setcounter{cnt@a}{(\cs@xa+\thecnt@b)/3}\edef\cs@xb{\thecnt@a}% \setcounter{cnt@a}{(\cs@xd+\thecnt@b)/3}\edef\cs@xc{\thecnt@a}% \setcounter{cnt@b}{2*(\cs@ya+\thecnt@c*\real{\UseSin\cs@sangle})} \setcounter{cnt@a}{(\cs@ya+\thecnt@b)/3}\edef\cs@yb{\thecnt@a}% \setcounter{cnt@a}{(\cs@yd+\thecnt@b)/3}\edef\cs@yc{\thecnt@a}% \unitlength=\d@my@unit \draw@b@edge(#1,#3){#5} \fi } %----------------------------------------------------------------------- % Edge between two nodes following a cubic Bezier curve. % The first and last control points are the centers of the starting % and ending nodes resp, modified with the starting and ending offsets. % The second and third control points are given by their polar coordinates % relative to the first and last control points resp. % % \drawbpedge(startingNode,sa,sr,endingNode,ea,er){label} % \drawbpedge[parameter=value,...](startingNode,sa,sr,endingNode,ea,er){label} % % Required arguments: % startingNode : name of the starting node, % sa,sr : polar coordinates of the second control point relative to the % first control point (angle in degree and radius in \unitlength) % endingNode : name of the ending node, % ea,er : polar coordinates of the third control point relative to the % last control point (angle in degree and radius in \unitlength) % label : label of the edge. {} for no label. % Optional argument: % [parameter=value,...] \def\drawbpedge#1(#2)#3{{% \@ifnextchar[{\process@bpedgeopt}{\draw@bpedge}#1(#2){#3}}} \let\drawcbpedge\drawbpedge \def\process@bpedgeopt[#1]{\gasset{#1}\draw@bpedge}% \def\draw@bpedge(#1,#2,#3,#4,#5,#6)#7{% % Control points of the cubic Bezier curve \setcounter{cnt@a}{\csname node@#1@x\endcsname + \E@sxo}% \edef\cs@xa{\thecnt@a}% \setcounter{cnt@a}{\csname node@#1@y\endcsname + \E@syo}% \edef\cs@ya{\thecnt@a}% \setcounter{cnt@a}{\csname node@#4@x\endcsname + \E@exo}% \edef\cs@xd{\thecnt@a}% \setcounter{cnt@a}{\csname node@#4@y\endcsname + \E@eyo}% \edef\cs@yd{\thecnt@a}% \setcounter{cnt@b}{1*\ratio{#3\unitlength}{\d@my@unit}} \edef\cs@angle{#2}% \CalculateCos\cs@angle \CalculateSin\cs@angle \setcounter{cnt@a}{\cs@xa+\thecnt@b*\real{\UseCos\cs@angle}} \edef\cs@xb{\thecnt@a}% \setcounter{cnt@a}{\cs@ya+\thecnt@b*\real{\UseSin\cs@angle}} \edef\cs@yb{\thecnt@a}% \setcounter{cnt@b}{1*\ratio{#6\unitlength}{\d@my@unit}} \edef\cs@angle{#5}% \CalculateCos\cs@angle \CalculateSin\cs@angle \setcounter{cnt@a}{\cs@xd+\thecnt@b*\real{\UseCos\cs@angle}} \edef\cs@xc{\thecnt@a}% \setcounter{cnt@a}{\cs@yd+\thecnt@b*\real{\UseSin\cs@angle}} \edef\cs@yc{\thecnt@a}% \unitlength=\d@my@unit \draw@b@edge(#1,#4){#7} } %----------------------------------------------------------------------- % Edge between two nodes following a cubic Bezier curve. % The first and last control points are the centers of the starting % and ending nodes resp, modified with the starting and ending offsets. % The second and third control points are given by their absolute % cartesian coordinates. % % \drawbcedge(startingNode,xs,ys,endingNode,xe,ye){label} % \drawbcedge[parameter=value,...](startingNode,xs,ys,endingNode,xe,ye){label} % % Required arguments: % startingNode : name of the starting node, % xs,ys : coordinates in \unitlength of the control point defining % the tangent at the starting node % endingNode : name of the ending node, % xe,ye : coordinates in \unitlength of the control point defining % the tangent at the ending node % label : label of the edge. {} for no label. % Optional argument: % [parameter=value,...] \def\drawbcedge#1(#2)#3{{% \@ifnextchar[{\process@bcedgeopt}{\draw@bcedge}#1(#2){#3}}} \let\drawcbedge\drawbcedge \def\process@bcedgeopt[#1]{\gasset{#1}\draw@bcedge}% \def\draw@bcedge(#1,#2,#3,#4,#5,#6)#7{% % Control points of the cubic Bezier curve \setcounter{cnt@a}{\csname node@#1@x\endcsname + \E@sxo}% \edef\cs@xa{\thecnt@a}% \setcounter{cnt@a}{\csname node@#1@y\endcsname + \E@syo}% \edef\cs@ya{\thecnt@a}% \setcounter{cnt@a}{\csname node@#4@x\endcsname + \E@exo}% \edef\cs@xd{\thecnt@a}% \setcounter{cnt@a}{\csname node@#4@y\endcsname + \E@eyo}% \edef\cs@yd{\thecnt@a}% \setcounter{cnt@a}{1*\ratio{#2\unitlength}{\d@my@unit}} \edef\cs@xb{\thecnt@a}% \setcounter{cnt@a}{1*\ratio{#3\unitlength}{\d@my@unit}} \edef\cs@yb{\thecnt@a}% \setcounter{cnt@a}{1*\ratio{#5\unitlength}{\d@my@unit}} \edef\cs@xc{\thecnt@a}% \setcounter{cnt@a}{1*\ratio{#6\unitlength}{\d@my@unit}} \edef\cs@yc{\thecnt@a}% \unitlength=\d@my@unit \draw@b@edge(#1,#4){#7} } %----------------------------------------------------------------------- % Loop on a node following a cubic Bezier curve. % Only the starting offsets sxo and syo are used. % % \drawloop(Node){label} % \drawloop[parameter=value,...](Node){label} % % Required arguments: % Node : name of the node, % label : label of the edge. {} for no label. % Optional argument: % [parameter=value,...] \def\drawloop#1(#2)#3{{% \@ifnextchar[{\process@loopopt}{\draw@loop}#1(#2){#3}}} \def\process@loopopt[#1]{\gasset{#1}\draw@loop}% \def\draw@loop(#1)#2{% % Control points of the cubic Bezier curve \unitlength=\d@my@unit \setcounter{cnt@a}{\csname node@#1@x\endcsname + \E@sxo}% \edef\cs@xa{\thecnt@a}% \setcounter{cnt@a}{\csname node@#1@y\endcsname + \E@syo}% \edef\cs@ya{\thecnt@a}% \edef\cs@xd{\cs@xa}% \edef\cs@yd{\cs@ya}% \node@diam(#1,\loop@angle) \setcounter{cnt@a}{2*(\cs@nd+2*\loop@height)/3} \setcounter{cnt@b}{\loop@width*1732/1000} % approx of sqrt(3) % Rotation \setcounter{cnt@c} {\cs@xa+\thecnt@a*\real{\cs@cos}-\thecnt@b*\real{\cs@sin}} \if@loopCW \edef\cs@xb{\thecnt@c}% \else \edef\cs@xc{\thecnt@c}% \fi \setcounter{cnt@c} {\cs@xa+\thecnt@a*\real{\cs@cos}+\thecnt@b*\real{\cs@sin}} \if@loopCW \edef\cs@xc{\thecnt@c}% \else \edef\cs@xb{\thecnt@c}% \fi \setcounter{cnt@c} {\cs@ya+\thecnt@a*\real{\cs@sin}+\thecnt@b*\real{\cs@cos}} \if@loopCW \edef\cs@yb{\thecnt@c}% \else \edef\cs@yc{\thecnt@c}% \fi \setcounter{cnt@c} {\cs@ya+\thecnt@a*\real{\cs@sin}-\thecnt@b*\real{\cs@cos}} \if@loopCW \edef\cs@yc{\thecnt@c}% \else \edef\cs@yb{\thecnt@c}% \fi \draw@b@edge(#1,#1){#2} } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Other macros %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %----------------------------------------------------------------------- % Draw a broken line defined by n points (n>1). % The line may have arrowhead(s), arrowtail(s), color, ... % depending of the current settings % % \drawline(x1,y1)...(xn,yn) % \drawline[parameter=value,...](x1,y1)...(xn,yn) % % Required arguments in \unitlengh: % (x1,y1)...(xn,yn) : coordinates of the points. % Optional argument: % [parameter=value,...] \def\drawline#1(#2){\begingroup% \setcounter{cnt@a}{0} \edef\ps@param{}% \@ifnextchar[{\process@drawlineopt}{\draw@line}#1(#2)} \def\process@drawlineopt[#1]{\gasset{#1}\draw@line}% \def\draw@line(#1,#2){% \setcounter{cnt@a}{\thecnt@a+1} \dim@x=#1\unitlength \edef\ps@param{\ps@param \strip@PT\dim@x}% \dim@x=#2\unitlength \edef\ps@param{\ps@param \strip@PT\dim@x}% \@ifnextchar({\draw@line}{ \put(0,0){\special{" \gas@initps \line@color \gas@ATparam \gas@AHparam \ps@param \thecnt@a\space \arc@radius !pslines}} \endgroup } } %----------------------------------------------------------------------- % Draw a line with snake waves between two points. % width and height of the waves are controlled by parameters snakeh and snakeh % The line may have arrowhead(s), arrowtail(s), color, ... % depending of the current settings % % \drawsnake(x1,y1)(x2,y2) % \drawsnake[parameter=value,...](x1,y1)(x2,y2) % % Required arguments in \unitlengh: % (x1,y1)(x2,y2) : coordinates of the points. % Optional argument: % [parameter=value,...] \def\drawsnake#1(#2)(#3){{% \@ifnextchar[{\process@drawsnakeopt}{\draw@snake}#1(#2)(#3)}} \def\process@drawsnakeopt[#1]{\gasset{#1}\draw@snake}% \def\draw@snake(#1,#2)(#3,#4){% \setcounter{cnt@a}{1*\ratio{#1\unitlength}{\d@my@unit}} % x1 \edef\snake@x{\thecnt@a} \setcounter{cnt@a}{1*\ratio{#2\unitlength}{\d@my@unit}} % x1 \edef\snake@y{\thecnt@a} \setcounter{cnt@a}{1*\ratio{#3\unitlength}{\d@my@unit}} % x1 \edef\snake@X{\thecnt@a} \setcounter{cnt@a}{1*\ratio{#4\unitlength}{\d@my@unit}} % x1 \edef\snake@Y{\thecnt@a} % \edef\ps@param{} \dim@x=\snake@x\d@my@unit \edef\ps@param{\ps@param \strip@PT\dim@x}% \dim@x=\snake@y\d@my@unit \edef\ps@param{\ps@param \strip@PT\dim@x}% % \setcounter{cnt@a}{\snake@X-\snake@x} \edef\snake@A{\thecnt@a} \setcounter{cnt@a}{\snake@Y-\snake@y} \edef\snake@B{\thecnt@a} \setcounter{cnt@a}{\snake@A*\snake@A+\snake@B*\snake@B} \gas@sqrt{\thecnt@a} \edef\snake@L{\the@sqrt} % \setcounter{cnt@@a}{\snake@w/2} \setcounter{cnt@a}{\snake@x+\snake@A*\thecnt@@a/\snake@L} \setcounter{cnt@b}{\snake@y+\snake@B*\thecnt@@a/\snake@L} \dim@x=\thecnt@a\d@my@unit \edef\ps@param{\ps@param \strip@PT\dim@x}% \dim@x=\thecnt@b\d@my@unit \edef\ps@param{\ps@param \strip@PT\dim@x}% \setcounter{cnt@@a}{\thecnt@@a+3*\snake@w/4} \setcounter{cnt@@c}{1} % \setcounter{cnt@c}{(\snake@L-5*\snake@w/2)/\snake@w} % nb iteration \@whilenum\thecnt@c>0\do{% \setcounter{cnt@@b}{\thecnt@@c*\snake@h} \setcounter{cnt@a}{\snake@x+(\snake@A*\thecnt@@a-\snake@B*\thecnt@@b)/\snake@L} \setcounter{cnt@b}{\snake@y+(\snake@B*\thecnt@@a+\snake@A*\thecnt@@b)/\snake@L} \dim@x=\thecnt@a\d@my@unit \edef\ps@param{\ps@param \strip@PT\dim@x}% \dim@x=\thecnt@b\d@my@unit \edef\ps@param{\ps@param \strip@PT\dim@x}% \setcounter{cnt@@a}{\thecnt@@a+\snake@w} \setcounter{cnt@@c}{-\thecnt@@c} \setcounter{cnt@c}{\thecnt@c-1} } \setcounter{cnt@@a}{\thecnt@@a-\snake@w/4} \setcounter{cnt@a}{\snake@x+\snake@A*\thecnt@@a/\snake@L} \setcounter{cnt@b}{\snake@y+\snake@B*\thecnt@@a/\snake@L} \dim@x=\thecnt@a\d@my@unit \edef\ps@param{\ps@param \strip@PT\dim@x}% \dim@x=\thecnt@b\d@my@unit \edef\ps@param{\ps@param \strip@PT\dim@x}% \dim@x=\snake@X\d@my@unit \edef\ps@param{\ps@param \strip@PT\dim@x}% \dim@x=\snake@Y\d@my@unit \edef\ps@param{\ps@param \strip@PT\dim@x}% % \setcounter{cnt@c}{4+(\snake@L-5*\snake@w/2)/\snake@w} % nb iteration \put(0,0){\special{" \gas@initps \line@color \gas@ATparam \gas@AHparam \ps@param \thecnt@c\space !pscurve}} } %----------------------------------------------------------------------- % Draw an arc of a circle. % % \drawarc(x,y,r,a,b) % \drawarc[parameter=value,...](x,y,r,a,b) % % Required arguments: % x,y : coordinates of the circle center (in \unitlengh). % r : radius of the circle (in \unitlengh). % a : starting angle of the arc (in degree) % b : ending angle of the arc (in degree) % Optional argument: % [parameter=value,...] \def\drawarc#1(#2){{% \@ifnextchar[{\process@arcopt}{\draw@arc}#1(#2)}} \def\process@arcopt[#1]{\gasset{#1}\draw@arc}% \def\draw@arc(#1,#2,#3,#4,#5){{% \dim@x=#1\unitlength \edef\ps@x{\strip@PT\dim@x}% \dim@x=#2\unitlength \edef\ps@y{\strip@PT\dim@x}% \dim@x=#3\unitlength \edef\ps@r{\strip@PT\dim@x}% \put(0,0){\special{" \gas@initps \if@fill \fill@color newpath \if@arcPie \ps@x \ps@y moveto \fi \ps@x \ps@y \ps@r #4 #5 arc \if@arcPie closepath \fi fill \fi \if@frame \line@color newpath \if@arcPie \ps@x \ps@y moveto \fi \ps@x \ps@y \ps@r #4 #5 arc \if@arcPie closepath \fi stroke \fi }} }} %----------------------------------------------------------------------- % Draw a circle. % % \drawcircle(x,y,d) % \drawcircle[parameter=value,...](x,y,d) % % Required arguments in \unitlengh: % x,y : coordinates of the circle center. % d : diameter of the circle. % Optional argument: % [parameter=value,...] \def\drawcircle#1(#2){{% \@ifnextchar[{\process@circleopt}{\draw@circle}#1(#2)}} \def\process@circleopt[#1]{\gasset{#1}\draw@circle}% \def\draw@circle(#1,#2,#3){{% \dim@x=#1\unitlength \edef\ps@x{\strip@PT\dim@x}% \dim@x=#2\unitlength \edef\ps@y{\strip@PT\dim@x}% \dim@x=#3\unitlength \edef\ps@d{\strip@PT\dim@x}% \put(0,0){\special{" \gas@initps \if@fill \fill@color \ps@x \ps@y \ps@d 2 div !pscirclepath fill \fi \if@frame \line@color \ps@x \ps@y \ps@d 2 div !pscirclepath stroke \fi }} }} %----------------------------------------------------------------------- % Draw a rectangle. % % \drawrect(x0,y0,x1,y1) % \drawrect[parameter=value,...](x0,y0,x1,y1) % % Required arguments in \unitlengh: % x0,y0 : coordinates of the lower left corner of the rectangle. % x1,y1 : coordinates of the upper right corner of the rectangle. % Optional argument: % [parameter=value,...] \def\drawrect#1(#2,#3,#4,#5){\drawpolygon#1(#2,#3)(#4,#3)(#4,#5)(#2,#5)}% % \def\drawrect#1(#2){{% % \@ifnextchar[{\process@rectopt}{\draw@rect}#1(#2)}} % \def\process@rectopt[#1]{\gasset{#1}\draw@rect}% % \def\draw@rect(#1,#2,#3,#4){{% % \dim@x=#1\unitlength \edef\ps@x{\strip@PT\dim@x}% % \dim@x=#2\unitlength \edef\ps@y{\strip@PT\dim@x}% % \dim@x=#3\unitlength \edef\ps@a{\strip@PT\dim@x}% % \dim@x=#4\unitlength \edef\ps@b{\strip@PT\dim@x}% % \put(0,0){\special{" \gas@initps % \if@fill % \fill@color % \ps@x \ps@y \ps@a \ps@b !psrectpath fill % \fi % \if@frame % \line@color % \ps@x \ps@y \ps@a \ps@b !psrectpath stroke % \fi % }} % }} %----------------------------------------------------------------------- % Draw an oval. % % \drawoval(x,y,w,h,mr) % \drawoval[parameter=value,...](x,y,w,h,mr) % % Required arguments in \unitlengh: % x,y : coordinates of the oval center. % w,h : width and height of the oval. % rm : defines the maximal radius for the corners. % Optional argument: % [parameter=value,...] \def\drawoval#1(#2){{% \@ifnextchar[{\process@ovalopt}{\draw@oval}#1(#2)}} \def\process@ovalopt[#1]{\gasset{#1}\draw@oval}% \def\draw@oval(#1,#2,#3,#4,#5){{% \dim@x=#1\unitlength \edef\ps@path{\strip@PT\dim@x}% \dim@x=#2\unitlength \edef\ps@path{\ps@path \strip@PT\dim@x}% \dim@x=#3\unitlength \edef\ps@path{\ps@path \strip@PT\dim@x}% \dim@x=#4\unitlength \edef\ps@path{\ps@path \strip@PT\dim@x}% \dim@x=#5\unitlength \edef\ps@path{\ps@path \strip@PT\dim@x}% \edef\ps@path{\ps@path !psovalpath\space}% \put(0,0){\special{" \gas@initps \if@fill \fill@color \ps@path fill \fi \if@frame \line@color \ps@path stroke \fi }} }} %----------------------------------------------------------------------- % Draw a polygon defined by n points (n>1). % The polygon may be framed and/or filled depending on the current parameters. % % \drawpolygon(x1,y1)...(xn,yn) % \drawpolygon[parameter=value,...](x1,y1)...(xn,yn) % % Required arguments in \unitlengh: % (x1,y1)...(xn,yn) : coordinates of the points. % Optional argument: % [parameter=value,...] \def\drawpolygon#1(#2){\begingroup% \setcounter{cnt@a}{0} \edef\ps@param{}% \@ifnextchar[{\process@polygonopt}{\draw@polygon}#1(#2)} \def\process@polygonopt[#1]{\gasset{#1}\draw@polygon}% \def\draw@polygon(#1,#2){% \setcounter{cnt@a}{\thecnt@a+1} \dim@x=#1\unitlength \edef\ps@param{\ps@param \strip@PT\dim@x}% \dim@x=#2\unitlength \edef\ps@param{\ps@param \strip@PT\dim@x}% \@ifnextchar({\draw@polygon}{ \put(0,0){\special{" \gas@initps \if@fill \fill@color \ps@param \thecnt@a\space \arc@radius !pspolygonpath fill \fi \if@frame \line@color \ps@param \thecnt@a\space \arc@radius !pspolygonpath stroke \fi }} \endgroup }} %----------------------------------------------------------------------- % Draw a regular polygon % The polygon may be framed and/or filled depending on the current parameters. % % \drawrpolygon(x,y)(n,r) % \drawrpolygon[parameter=value,...](x,y)(n,r) % % Required arguments: % x,y : coordinates in \unitlengh of the center of the polygon. % n : number of sides of the polygon. % r : radius in \unitlengh of the polygon. % Optional argument: (in particular, polyangle and arcradius) % [parameter=value,...] \def\drawrpolygon#1(#2)(#3){\begingroup% \@ifnextchar[{\process@rpolygonopt}{\draw@rpolygon}#1(#2)(#3)} \def\process@rpolygonopt[#1]{\gasset{#1}\draw@rpolygon}% \def\draw@rpolygon(#1,#2)(#3,#4){% \dim@x=#1\unitlength \dim@y=#2\unitlength \edef\ps@path{\strip@PT\dim@x \strip@PT\dim@y #3\space}% \dim@x=#4\unitlength \edef\ps@path{\ps@path \strip@PT\dim@x}% \edef\ps@path{\ps@path \poly@angle\space \arc@radius 0 !psrpolygonpath\space}% \put(0,0){\special{" \gas@initps \if@fill \fill@color \ps@path fill \fi \if@frame \line@color \ps@path stroke \fi }} \endgroup} %----------------------------------------------------------------------- % Draw closed curve defined by n points (n>1). % Between each pair of consecutive points, we use a cubic Bezier curve. % The control points of the cubic Bezier curves are determined so that % the whole curve is C^1 and the tangent at each point is orthogonal to % the bisector at this point. % The closed curve may be framed and/or filled depending on % the current parameters. % % \drawccurve(x1,y1)...(xn,yn) % \drawccurve[parameter=value,...](x1,y1)...(xn,yn) % % Required arguments in \unitlengh: % (x1,y1)...(xn,yn) : coordinates of the points. % Optional argument: % [parameter=value,...] \def\drawccurve#1(#2){\begingroup% \setcounter{cnt@a}{0} \edef\ps@param{}% \@ifnextchar[{\process@drawccurveopt}{\draw@c@curve}#1(#2)} \def\process@drawccurveopt[#1]{\gasset{#1}\draw@c@curve}% \def\draw@c@curve(#1,#2){% \setcounter{cnt@a}{\thecnt@a+1} \dim@x=#1\unitlength \edef\ps@param{\ps@param \strip@PT\dim@x}% \dim@x=#2\unitlength \edef\ps@param{\ps@param \strip@PT\dim@x}% \@ifnextchar({\draw@c@curve}{ \put(0,0){\special{" \gas@initps \if@fill \fill@color \ps@param \thecnt@a\space !psccurvepath fill \fi \if@frame \line@color \ps@param \thecnt@a\space !psccurvepath stroke \fi }} \endgroup }} %----------------------------------------------------------------------- % Draw curve defined by n points (n>1). % Between each pair of consecutive points, we use a cubic Bezier curve. % The control points of the cubic Bezier curves are determined so that % the whole curve is C^1 and the tangent at each point is orthogonal to % the bisector at this point. % % \drawcurve(x1,y1)...(xn,yn) % \drawcurve[parameter=value,...](x1,y1)...(xn,yn) % % Required arguments in \unitlengh: % (x1,y1)...(xn,yn) : coordinates of the points. % Optional argument: % [parameter=value,...] \def\drawcurve#1(#2){\begingroup% \setcounter{cnt@a}{0} \edef\ps@param{}% \@ifnextchar[{\process@drawcurveopt}{\draw@curve}#1(#2)} \def\process@drawcurveopt[#1]{\gasset{#1}\draw@curve}% \def\draw@curve(#1,#2){% \setcounter{cnt@a}{\thecnt@a+1} \dim@x=#1\unitlength \edef\ps@param{\ps@param \strip@PT\dim@x}% \dim@x=#2\unitlength \edef\ps@param{\ps@param \strip@PT\dim@x}% \@ifnextchar({\draw@curve}{ \put(0,0){\special{" \gas@initps \line@color \gas@ATparam \gas@AHparam \ps@param \thecnt@a\space !pscurve}} \endgroup }} %----------------------------------------------------------------------- % Draw a quadratic Bezier curve. % The line may have arrowhead(s), ... depending of the current settings % % \drawqbezier(x0,y0,x1,y1,x2,y2) % \drawqbezier[parameter=value,...](x0,y0,x1,y1,x2,y2) % % \drawqbezier arguments: % x0,y0,x1,y1,x2,y2 : coordinates in \unitlength of the control points % Optional argument: % [parameter=value,...] \def\drawqbezier#1(#2){{% \@ifnextchar[{\process@drawqbezieropt}{\draw@q@bezier}#1(#2)}} \def\process@drawqbezieropt[#1]{\gasset{#1}\draw@q@bezier}% \def\draw@q@bezier(#1,#2,#3,#4,#5,#6){{% \dim@x=#1\unitlength \edef\ps@xa{\strip@PT\dim@x}% \dim@x=#2\unitlength \edef\ps@ya{\strip@PT\dim@x}% \dim@x=#3\unitlength \edef\ps@xb{\strip@PT\dim@x}% \dim@x=#4\unitlength \edef\ps@yb{\strip@PT\dim@x}% \dim@x=#5\unitlength \edef\ps@xc{\strip@PT\dim@x}% \dim@x=#6\unitlength \edef\ps@yc{\strip@PT\dim@x}% \put(0,0){\special{" \gas@initps \line@color \gas@ATparam \gas@AHparam \ps@xa \ps@ya \ps@xb \ps@yb \ps@xc \ps@yc !ps_qbezier}} }} %----------------------------------------------------------------------- % Draw a cubic Bezier curve. % The line may have arrowhead(s), ... depending of the current settings % % \drawcbezier(x0,y0,x1,y1,x2,y2,x3,y3) % \drawcbezier[parameter=value,...](x0,y0,x1,y1,x2,y2,x3,y3) % % \drawcbezier arguments: % x0,y0,x1,y1,x2,y2,x3,y3 : coordinates in \unitlength of the control points % Optional argument: % [parameter=value,...] \def\drawcbezier#1(#2){{% \@ifnextchar[{\process@drawcbezieropt}{\draw@c@bezier}#1(#2)}} \def\process@drawcbezieropt[#1]{\gasset{#1}\draw@c@bezier}% \def\draw@c@bezier(#1,#2,#3,#4,#5,#6,#7,#8){{% \dim@x=#1\unitlength \edef\ps@xa{\strip@PT\dim@x}% \dim@x=#2\unitlength \edef\ps@ya{\strip@PT\dim@x}% \dim@x=#3\unitlength \edef\ps@xb{\strip@PT\dim@x}% \dim@x=#4\unitlength \edef\ps@yb{\strip@PT\dim@x}% \dim@x=#5\unitlength \edef\ps@xc{\strip@PT\dim@x}% \dim@x=#6\unitlength \edef\ps@yc{\strip@PT\dim@x}% \dim@x=#7\unitlength \edef\ps@xd{\strip@PT\dim@x}% \dim@x=#8\unitlength \edef\ps@yd{\strip@PT\dim@x}% \put(0,0){\special{" \gas@initps \line@color \gas@ATparam \gas@AHparam \ps@xa \ps@ya \ps@xb \ps@yb \ps@xc \ps@yc \ps@xd \ps@yd !ps_cbezier}} }} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Internal macros %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %----------------------------------------------------------------------- % Compute the diameter of a node in some direction % % \node@diam(Node,angle) % % Result in \cs@nd. % Byproduct: \cs@cos=cos(angle), \cs@sin=sin(angle) are also defined. % % There are 3 cases depending on whether the direction intersects the node % on a vertical line, an horizontal line or a rounded corner. \def\node@diam(#1,#2){% \CalculateCos{#2} \edef\cs@cos{\UseCos{#2}}% \CalculateSin{#2} \edef\cs@sin{\UseSin{#2}}% \ifnum\csname node@#1@w\endcsname=-1 % then it's a polygonal node \edef\cs@rad{\csname node@#1@rad\endcsname}% \edef\cs@n{\csname node@#1@n\endcsname}% \edef\cs@a{\csname node@#1@a\endcsname}% \setcounter{cnt@b}{360/\cs@n}\edef\cs@b{\thecnt@b}% \setcounter{cnt@a}{#2-\cs@a} \@whilenum\thecnt@a>\thecnt@b\do{\setcounter{cnt@a}{\thecnt@a-\thecnt@b}} \@whilenum\thecnt@a<0\do{\setcounter{cnt@a}{\thecnt@a+\thecnt@b}} \setcounter{cnt@b}{\thecnt@b/2} \setcounter{cnt@a}{\thecnt@a-\thecnt@b} \ifnum\thecnt@a<0 \setcounter{cnt@a}{-\thecnt@a} \fi \CalculateCos{\thecnt@a} \CalculateCos{\thecnt@b}% \setcounter{cnt@c}{2*\cs@rad*\real{\UseCos{\thecnt@b}}/\real{\UseCos{\thecnt@a}}} \edef\cs@nd{\thecnt@c}% \else % it's an oval node \edef\cs@w{\csname node@#1@w\endcsname}% \edef\cs@h{\csname node@#1@h\endcsname}% \edef\cs@r{\csname node@#1@r\endcsname}% \setcounter{cnt@a}{\cs@r+\cs@r}\edef\cs@rr{\thecnt@a}% \setcounter{cnt@a}{(\cs@h-\cs@rr)*\real{\cs@cos}} \ifnum\thecnt@a<0\edef\cs@A{-\thecnt@a}\else\edef\cs@A{\thecnt@a}\fi% \setcounter{cnt@a}{(\cs@w-\cs@rr)*\real{\cs@sin}} \ifnum\thecnt@a<0\edef\cs@B{-\thecnt@a}\else\edef\cs@B{\thecnt@a}\fi% \setcounter{cnt@a}{\cs@w*\real{\cs@sin}} \ifnum\thecnt@a<0\setcounter{cnt@a}{-\thecnt@a}\fi \ifnum\thecnt@a<\cs@A \setcounter{cnt@c}{\cs@w/\real{\cs@cos}} \ifnum\thecnt@c<0\edef\cs@nd{-\thecnt@c}\else\edef\cs@nd{\thecnt@c}\fi% \else \setcounter{cnt@a}{\cs@h*\real{\cs@cos}} \ifnum\thecnt@a<0\setcounter{cnt@a}{-\thecnt@a}\fi \ifnum\thecnt@a<\cs@B \setcounter{cnt@c}{\cs@h/\real{\cs@sin}} \ifnum\thecnt@c<0\edef\cs@nd{-\thecnt@c}\else\edef\cs@nd{\thecnt@c}\fi% \else \setcounter{cnt@a}{\cs@rr*\cs@rr-(\cs@B-\cs@A)*(\cs@B-\cs@A)} \gas@sqrt{\thecnt@a} \setcounter{cnt@a}{(\cs@w-\cs@rr)*\real{\cs@cos}} \ifnum\thecnt@a<0\edef\cs@E{-\thecnt@a}\else\edef\cs@E{\thecnt@a}\fi% \setcounter{cnt@a}{(\cs@h-\cs@rr)*\real{\cs@sin}} \ifnum\thecnt@a<0\edef\cs@F{-\thecnt@a}\else\edef\cs@F{\thecnt@a}\fi% \setcounter{cnt@a}{\the@sqrt+\cs@E+\cs@F}\edef\cs@nd{\thecnt@a}% \fi \fi \fi % \typeout{w=\cs@w,h=\cs@h,r=\cs@r,angle=#2,\cs@nd} } %----------------------------------------------------------------------- % Draw the cubic Bezier curve. % The control points % (\cs@xa,\cs@ya)(\cs@xb,\cs@yb)(\cs@xc,\cs@yc)(\cs@xd,\cs@yd) % should already be defined. % % #1 : name of the starting node % #2 : name of the ending node % #3 : label of the edge \def\draw@b@edge(#1,#2)#3{{% % Parameters for the Bezier curve. \dim@x=\cs@xa\unitlength \edef\ps@xa{\strip@PT\dim@x}% \dim@x=\cs@ya\unitlength \edef\ps@ya{\strip@PT\dim@x}% \dim@x=\cs@xb\unitlength \edef\ps@xb{\strip@PT\dim@x}% \dim@x=\cs@yb\unitlength \edef\ps@yb{\strip@PT\dim@x}% \dim@x=\cs@xc\unitlength \edef\ps@xc{\strip@PT\dim@x}% \dim@x=\cs@yc\unitlength \edef\ps@yc{\strip@PT\dim@x}% \dim@x=\cs@xd\unitlength \edef\ps@xd{\strip@PT\dim@x}% \dim@x=\cs@yd\unitlength \edef\ps@yd{\strip@PT\dim@x}% \put(0,0){\special{" \gas@initps \line@color % Path around starting node \csname node@#1@path\endcsname /path!a false upath cvlit def % Path around ending node \csname node@#2@path\endcsname /path!b false upath cvlit def % The curve \gas@ATparam \gas@AHparam \ps@xa \ps@ya \ps@xb \ps@yb \ps@xc \ps@yc \ps@xd \ps@yd !ps_r_cbezier }} % Coordinates (\cs@x,\cs@y) and slope (\cs@deltax,\cs@deltay) at the % point of the curve defined by the parameter label@pos. \def\@N{100}% % coefficients of the polynomial x(t) \setcounter{cnt@a}{\cs@xd-\cs@xa+3*(\cs@xb-\cs@xc)}\edef\@A{\thecnt@a}% \setcounter{cnt@a}{3*(\cs@xa+\cs@xc-2*\cs@xb)}\edef\@B{\thecnt@a}% \setcounter{cnt@a}{3*(\cs@xb-\cs@xa)}\edef\@C{\thecnt@a}% % computation of \cs@x and \cs@deltax \setcounter{cnt@a}{((\@A*\EL@p/\@N+\@B)*\EL@p/\@N+\@C)*\EL@p/\@N+\cs@xa} \edef\cs@x{\thecnt@a}% \setcounter{cnt@a}{(3*\@A*\EL@p/\@N+2*\@B)*\EL@p/\@N+\@C} \edef\cs@deltax{\thecnt@a}% % coefficients of the polynomial y(t) \setcounter{cnt@a}{\cs@yd-\cs@ya+3*(\cs@yb-\cs@yc)}\edef\@A{\thecnt@a}% \setcounter{cnt@a}{3*(\cs@ya+\cs@yc-2*\cs@yb)}\edef\@B{\thecnt@a}% \setcounter{cnt@a}{3*(\cs@yb-\cs@ya)}\edef\@C{\thecnt@a}% % computation of \cs@y and \cs@deltay \setcounter{cnt@a}{((\@A*\EL@p/\@N+\@B)*\EL@p/\@N+\@C)*\EL@p/\@N+\cs@ya} \edef\cs@y{\thecnt@a}% \setcounter{cnt@a}{(3*\@A*\EL@p/\@N+2*\@B)*\EL@p/\@N+\@C} \edef\cs@deltay{\thecnt@a}% % Computation of sqrt(\cs@deltax^2+\cs@deltay^2). \setcounter{cnt@c}{\cs@deltax*\cs@deltax+\cs@deltay*\cs@deltay} \gas@sqrt{\thecnt@c} \ifnum\the@sqrt=0\def\the@sqrt{1}\fi % Label of the edge. % Computation of the shift from C to the center of the label. \if@ELdistC \setcounter{cnt@c}{\EL@dist} \else \setbox\temp@box\hbox{\selectfont #3} \setcounter{cnt@a}{\wd\temp@box / \d@my@unit * \cs@deltay} \ifnum\thecnt@a<0 \setcounter{cnt@a}{-\thecnt@a} \fi \setcounter{cnt@c}{(\ht\temp@box+\dp\temp@box) / \d@my@unit * \cs@deltax} \ifnum\thecnt@c<0 \setcounter{cnt@c}{-\thecnt@c} \fi \setcounter{cnt@c}{(\thecnt@c+\thecnt@a) / \the@sqrt / 2 + \EL@dist} \fi \if r\EL@s \setcounter{cnt@a}{\cs@x + \cs@deltay * \thecnt@c / \the@sqrt} \setcounter{cnt@b}{\cs@y - \cs@deltax * \thecnt@c / \the@sqrt} \else \setcounter{cnt@a}{\cs@x - \cs@deltay * \thecnt@c / \the@sqrt} \setcounter{cnt@b}{\cs@y + \cs@deltax * \thecnt@c / \the@sqrt} \fi % Shifting point C and drawing the label. \put(\thecnt@a,\thecnt@b){\makebox(0,0){\selectfont #3}} }} %----------------------------------------------------------------------- % Compute the lower interger part of the square root of % (the absolute value of) its argument. % The result is obtained with \the@sqrt. % We use Heron's method which converges quickly. \newcounter{cnt@@a}\newcounter{cnt@@b}\newcounter{cnt@@c} \def\gas@sqrt#1{% \ifnum#1<0\setcounter{cnt@@a}{-#1}\else\setcounter{cnt@@a}{#1}\fi \ifnum\thecnt@@a>1 \setcounter{cnt@@b}{\thecnt@@a} \setcounter{cnt@@c}{(\thecnt@@a+1)/2} \@whilenum\thecnt@@b>\thecnt@@c\do{ \setcounter{cnt@@b}{\thecnt@@c} \setcounter{cnt@@c}{(\thecnt@@b+\thecnt@@a/\thecnt@@b)/2}} \edef\the@sqrt{\thecnt@@b} \else \edef\the@sqrt{\thecnt@@a} \fi } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Compatibility with gastex v1.0 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Should be called inside the scope of a group % % {\compatiblegastexun ... } % % The macros \drawloop and \drawedge are redefined to match the old % ones (v1.0) hence the new ones (v2.0) cannot be used inside the scope % of \compatiblegastexun. % % The compatibility is almost 100%: % - the following are ignored % \setmaxbezier % The optional argument of letstate defining the repeated state diameter % - \settransdecal, \setedgedecal give curved edges % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \def\compatiblegastexun{ %----------------------------------------------------------------------- % Definitions %----------------------------------------------------------------------- \unitlength=4pt \d@my@unit= 2048sp % =1/32 pt ~= 0.011 mm \gasset{AHnb=1,AHangle=20} \def\AH@L{\strip@PT\@wholewidth 9 mul } \def\AH@l{\strip@PT\@wholewidth 9 mul 20 cos mul } \def\line@width{\strip@PT\@wholewidth} % \def\setstatediam##1{\gasset{Nw=##1,Nh=##1,Nmr=##1}} \def\setvertexdiam{\setstatediam} \setstatediam{6} % \def\setrepeatedstatediam##1{% \setcounter{cnt@a}{1*\ratio{##1\unitlength}{\d@my@unit}} \edef\repeated@diam{\thecnt@a}}% \setrepeatedstatediam{5} % \def\setloopdiam##1{\gasset{loopdiam=##1}}% \setloopdiam{6} % \def\settranslabelskip##1{\gasset{ELdist=##1}}% \def\setedgelabelskip##1{\gasset{ELdist=##1}} \settranslabelskip{1} % \def\setprofcurve##1{% \setcounter{cnt@a}{1*\ratio{##1\unitlength}{\d@my@unit}} \edef\prof@curve{\thecnt@a}}% \setprofcurve{3} % \def\settransdecal##1{% \setcounter{cnt@a}{1*\ratio{##1\unitlength}{\d@my@unit}} \edef\trans@decal{\thecnt@a}}% \settransdecal{0} \def\setedgedecal{\settransdecal} % \def\setmaxbezier##1{} \def\setnbptbezier##1{} % compatibilite version 0.3 \def\setprecision##1{} % compatibilite version 0.3 % \def\setpsdash{\@ifnextchar[{\i@setpsdash}{\i@setpsdash[0]}} \def\i@setpsdash[##1](##2){% \dim@y=\unitlength \unitlength=1pt \gasset@@dash{0 ##2}{##1} \unitlength=\dim@y \def\ps@dash{[##2] ##1\space}}% \setpsdash() % continuous path % \def\pcolor{} \def\pictcolor##1##2{} % \def\setpsgray##1{\gasset{linegray=##1,fillgray=##1}}% \setpsgray{0} % black %----------------------------------------------------------------------- % States %----------------------------------------------------------------------- \def\letstate{\@ifnextchar[{\i@letstate}{\ii@letstate}}% \def\i@letstate[##1,##2] ##3=(##4,##5){{% \gasset{Nw=##1,Nh=##1,Nmr=##1} \let@node(##3)(##4,##5){}}} \def\ii@letstate ##1=(##2,##3){% \let@node(##1)(##2,##3){}} \def\letvertex{\@ifnextchar[{\i@letvertex}{\ii@letstate}}% \def\i@letvertex[##1] ##2=(##3,##4){{% \gasset{Nw=##1,Nh=##1,Nmr=##1} \let@node(##2)(##3,##4){}}} % \def\drawstate(##1)##2{{\gasset{Nfill=n}\draw@node(##1){##2}}}% \def\drawvertex(##1)##2{{\gasset{Nfill=n,Nframe=n}\draw@node(##1){##2}}}% \def\drawcircledvertex{\drawstate}% % \def\drawinitialstate{% \@ifnextchar[{\@idrawinitialstate}{\@idrawinitialstate[l]}} \def\@idrawinitialstate[##1](##2)##3{{% \gasset{Nfill=n}\draw@node(##2){##3} \setcounter{cnt@a}{\N@w*\ratio{\d@my@unit}{\unitlength}/2} \if##1l \imark[iangle=180,ilength=\thecnt@a](##2) \fi \if##1r \imark[iangle= 0,ilength=\thecnt@a](##2) \fi \if##1t \imark[iangle= 90,ilength=\thecnt@a](##2) \fi \if##1b \imark[iangle=-90,ilength=\thecnt@a](##2) \fi}} % \def\drawfinalstate{% \@ifnextchar[{\@idrawfinalstate}{\@idrawfinalstate[r]}} \def\@idrawfinalstate[##1](##2)##3{{% \gasset{Nfill=n}\draw@node(##2){##3} \setcounter{cnt@a}{\N@w*\ratio{\d@my@unit}{\unitlength}/2} \if##1l \fmark[fangle=180,flength=\thecnt@a](##2) \fi \if##1r \fmark[fangle= 0,flength=\thecnt@a](##2) \fi \if##1t \fmark[fangle= 90,flength=\thecnt@a](##2) \fi \if##1b \fmark[fangle=-90,flength=\thecnt@a](##2) \fi}} % \def\drawrepeatedstate(##1)##2{{% \gasset{Nfill=n}\draw@node(##1){##2} \setcounter{cnt@a}{(\N@w-\repeated@diam)/2} \edef\rep@dist{\thecnt@a}% \rmark(##1)}} %----------------------------------------------------------------------- % Transitions %----------------------------------------------------------------------- \let\gas@edge=\drawedge \def\drawtrans{\@ifnextchar[{\@idrawtrans}{\@idrawtrans[l]}} \def\@idrawtrans[##1](##2,##3)##4{% \setcounter{cnt@a}{\trans@decal*\ratio{\d@my@unit}{\unitlength}} \if##1r \gas@edge[ELside=r,curvedepth=\thecnt@a](##2,##3){##4} \else \if##1b \gas@edge[ELside=r,curvedepth=\thecnt@a](##2,##3){##4} \else \gas@edge[ELside=l,curvedepth=\thecnt@a](##2,##3){##4} \fi\fi} \def\drawedge{\drawtrans} \def\drawundirectededge##1(##2,##3)##4{% {\def\AH@nb{0 }\drawtrans##1(##2,##3){##4}}} % \def\drawcurvedtrans{% \@ifnextchar[{\@idrawcurvedtrans}{\@idrawcurvedtrans[l]}} \def\@idrawcurvedtrans[##1](##2,##3)##4{% \setcounter{cnt@a}{\prof@curve*\ratio{\d@my@unit}{\unitlength}} \if##1r \gas@edge[ELside=r,curvedepth=\thecnt@a](##2,##3){##4} \else \if##1b \gas@edge[ELside=r,curvedepth=\thecnt@a](##2,##3){##4} \else \gas@edge[ELside=l,curvedepth=\thecnt@a](##2,##3){##4} \fi\fi} \def\drawcurvededge{\drawcurvedtrans} \def\drawundirectedcurvededge##1(##2,##3)##4{% {\def\AH@nb{0 }\drawcurvedtrans##1(##2,##3){##4}}} % \def\drawqbeziertrans{% \@ifnextchar[{\@idrawqbeziertrans}{\@idrawqbeziertrans[l]}} \def\@idrawqbeziertrans[##1](##2)(##3,##4)(##5)##6{% \if##1r \drawqbedge[ELside=r](##2,##3,##4,##5){##6} \else \if##1b \drawqbedge[ELside=r](##2,##3,##4,##5){##6} \else \drawqbedge[ELside=l](##2,##3,##4,##5){##6} \fi\fi} \def\drawqbezieredge{\drawqbeziertrans} \def\drawundirectedqbezieredge##1(##2)(##3,##4)(##5)##6{% {\def\AH@nb{0 }\drawqbeziertrans##1(##2)(##3,##4)(##5){##6}}} % \def\drawcbeziertrans{% \@ifnextchar[{\@idrawcbeziertrans}{\@idrawcbeziertrans[l]}} \def\@idrawcbeziertrans[##1](##2)(##3,##4)(##5,##6)(##7)##8{{% \if##1r \edef\EL@s{r} \else \if##1b \edef\EL@s{r} \else \edef\EL@s{l} \fi\fi \draw@bcedge(##2,##3,##4,##7,##5,##6){##8} }} \def\drawcbezieredge{\drawcbeziertrans} \def\drawundirectedcbezieredge##1(##2)(##3,##4)(##5,##6)(##7)##8{% {\def\AH@nb{0 }\drawcbeziertrans##1(##2)(##3,##4)(##5,##6)(##7){##8}}} % \let\gas@loop=\drawloop \def\drawloop{\@ifnextchar[{\@idrawloop}{\@idrawloop[t]}}% \def\@idrawloop[##1](##2)##3{% \if##1l \gas@loop[loopangle=180](##2){##3} \fi \if##1r \gas@loop[loopangle= 0](##2){##3} \fi \if##1t \gas@loop[loopangle= 90](##2){##3} \fi \if##1b \gas@loop[loopangle=-90](##2){##3} \fi} \def\drawundirectedloop##1(##2)##3{% {\def\AH@nb{0 }\drawloop##1(##2){##3}}} } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Compatibility with pspictpg v0.6 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Should be called inside the scope of a group % % {\compatiblepspictpg ... } % % The macros \drawline and \drawcircle are redefined to match those of % pspictpg hence thoses of GasTeX cannot be used inside the scope % of \compatiblepspictpg. % % The following macros are ignored. Use linecolor and fillcolor instead. % \pcolor, \pictcolor % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \def\compatiblepspictpg{ % \def\setpsdash{\@ifnextchar[{\i@setpsdash}{\i@setpsdash[0]}} \def\i@setpsdash[##1](##2){% \dim@y=\unitlength \unitlength=1pt \gasset@@dash{0 ##2}{##1} \unitlength=\dim@y \def\ps@dash{[##2] ##1\space}}% \setpsdash() % continuous path % \def\pcolor{} \def\pictcolor##1##2{} % \def\setpsgray##1{\gasset{linegray=##1,fillgray=##1}}% \setpsgray{0} % black % % Redefinition of latex \line(a,b){L}. % Can be used with any values for a and b. \def\line(##1,##2)##3{{% \@xarg ##1\relax \@yarg ##2\relax \dim@x=##3\unitlength \special{" \gas@initps \line@color \the\@xarg\space \the\@yarg\space \strip@PT\dim@x !pslatexline} }} % % Redefinition of latex \vector(a,b){L}. % Can be used with any values for a and b. \def\vector(##1,##2)##3{{% \@xarg ##1\relax \@yarg ##2\relax \dim@x=##3\unitlength \special{" \gas@initps \line@color \gas@ATnul \gas@AHparam \the\@xarg\space \the\@yarg\space \strip@PT\dim@x !pslatexvector} }} % % redefinition of \circle of LaTeX % can be used with any diameter \def\circle{\@ifnextchar*{\@idisk}{\@icircle}} \def\@icircle##1{{% \dim@x=##1\unitlength \special{" \gas@initps \line@color \strip@PT\dim@x !pscircle} }} \def\@idisk*##1{{% \dim@x=##1\unitlength \special{" \gas@initps \fill@color \strip@PT\dim@x !psdisk} }} % \def\drawline(##1,##2)(##3,##4){\begingroup% \setcounter{cnt@a}{0} \edef\ps@param{}% \process@drawlineopt[ATnb=0,AHnb=0](##1,##2)(##3,##4)} \def\drawvector(##1,##2)(##3,##4){\begingroup% \setcounter{cnt@a}{0} \edef\ps@param{}% \process@drawlineopt[ATnb=0,AHnb=1](##1,##2)(##3,##4)} \def\drawcircle(##1,##2)(##3){{% \gasset{Nframe=y,Nfill=n}\draw@circle(##1,##2,##3)}} \def\drawdisk(##1,##2)(##3){{% \gasset{Nframe=n,Nfill=y}\draw@circle(##1,##2,##3)}} \def\cbezier(##1,##2)(##3,##4)(##5,##6)(##7,##8){% \drawcbezier[ATnb=0,AHnb=0](##1,##2,##3,##4,##5,##6,##7,##8)} \def\cbeziervector(##1,##2)(##3,##4)(##5,##6)(##7,##8){% \drawcbezier[ATnb=0,AHnb=1](##1,##2,##3,##4,##5,##6,##7,##8)} \def\qbezier(##1,##2)(##3,##4)(##5,##6){% \drawqbezier[ATnb=0,AHnb=0](##1,##2,##3,##4,##5,##6)} \def\qbeziervector(##1,##2)(##3,##4)(##5,##6){% \drawqbezier[ATnb=0,AHnb=1](##1,##2,##3,##4,##5,##6)} } \endinput