% This file is part of the Petri-nets packages. See file README for % copyright notice. \message{ ** Petri-nets / draw commands ** } \input pnversion \input pstricks \input pst-node \let\pst=\relax \catcode`\:=11 %% %% option parsing facilities %% \def\expandonce{\expandafter\noexpand} \outer\def\newopt #1#2{% group/character (+ params and body) \expandafter\ifx\csname setcode:#1\endcsname\relax \expandafter\edef\csname setcode:#1\endcsname{% \noexpand\catcode`\string#2=12 \relax}% \expandafter\edef\csname resetcode:#1\endcsname{% \noexpand\catcode`\string#2=\the\catcode`#2 \relax}% \else \expandafter\edef\csname setcode:#1\endcsname{% \noexpand\catcode`\string#2=12 \relax \expandafter\expandonce\csname setcode:#1\endcsname}% \expandafter\edef\csname resetcode:#1\endcsname{% \noexpand\catcode`\string#2=\the\catcode`#2 \relax \expandafter\expandonce\csname resetcode:#1\endcsname}% \fi \edef\newopt:name{opt:#1\string#2}% \expandafter\expandafter\def\csname\newopt:name\endcsname} \def\getopt #1#2{% group/macro to run after getting options \def\getopt:end{\csname resetcode:#1\endcsname #2}% \begingroup \edef\getopt:group{opt:#1}% \csname setcode:#1\endcsname \nextopt} \let\endopt=\endgroup \def\nextopt{\begingroup \futurelet\next\getopt:next} \def\getopt:next{\ifcat\next\string*% \aftergroup\getopt:run \else \aftergroup\getopt:end \fi \endgroup} \def\getopt:run #1{\edef\getopt:name{\getopt:group\string#1}% \expandafter\csname\getopt:name\endcsname} %% %% misc setup %% % pstrick tunning \psset{unit=1cm, xunit=1cm, yunit=1cm, linewidth=.5pt, doublesep=.5pt, dimen=iner, labelsep=2pt, arcangle=0, arrowlength=1.4, arrowinset=0, arrowsize=2pt 2} % nodes sizes \newdimen\placesize \newdimen\transsize \newdimen\storesize \newdimen\modulesize \newdimen\sourcesize \def\nodessize #1{% \placesize = #1 \transsize = #1 \storesize = #1 \modulesize = #1 \sourcesize = #1 \relax} \nodessize{5mm} % something to run before when a new net \newtoks\everynet \everynet={} % something to run before typesetting labels \newtoks\everylabel \everylabel={} %% %% begin/end a net %% \newopt{net}[#1]{\psset{#1}\nextopt} \newopt{net}(#1)(#2){\pspicture(#1)(#2)% \def\net:bottom:left{#1}\def\net:top:right{#2}% % adds white points in order to setup bounding box for a possible % `dvips -E' \rput(#1){{\white\vrule width 1sp height 1sp depth 0sp}}% \rput(#2){{\white\vrule width 1sp height 1sp depth 0sp}}% \the\everynet} {\catcode`\^^M=\active \let^^M=\relax % \global\def\beginnet{\leavevmode\hbox\bgroup% \let\place=\net:place% \let\trans=\net:trans% \let\store=\net:store% \let\module=\net:module% \let\source=\net:source% \let\text=\net:text% \let\link=\net:link% \let\arc=\net:arc% \let\label=\net:label% \let\showbb=\net:showbb% \def\net:s{empty}% \catcode`\^^M=\active\let^^M=\relax% \getopt{net}\relax}} \let\begin:net=\beginnet \def\endnet{\endpspicture\endopt\egroup \global\let\beginnet=\begin:net} \newbox\net:box \def\save:net\leavevmode{\global\setbox\net:box} \def\savenet{\def\beginnet{\expandafter\save:net\begin:net}} \def\shownet{{\setbox0\copy\net:box\unhbox0}} %% %% globally used for labels %% \def\net:math #1\net:endmath{$#1$} %% %% draws net bounding box %% {\catcode`\^^M=\active \let^^M=\relax % \global\def\net:showbb #1^^M{% options (if any) {\psframe#1(\net:bottom:left)(\net:top:right)}}} %% %% places %% \newopt{net:place}"{\let\net:math\relax \let\net:endmath\relax \nextopt} \newopt{net:place}={\psset{doubleline=true}\nextopt} \newopt{net:place}!{\psset{linewidth=2pt,linecolor=black}\nextopt} \newopt{net:place}[#1]{\psset{#1}\nextopt} \def\net:place{\getopt{net:place}\net:place:draw} {\catcode`\^^M=\active \let^^M=\relax % \global\def\net:place:draw #1(#2,#3)#4^^M{% options/name/x/y/label \global\edef\net:x{#2}% \global\edef\net:y{#3}% \global\def\net:s{circle}% \cnode(#2,#3){.5\placesize}{#1}% \rput(#2,#3){\hbox{\net:math\the\everylabel #4\net:endmath}}\endopt}} %% %% source %% \def\net:source{\getopt{net:trans}\net:source:draw} {\catcode`\^^M=\active \let^^M=\relax % \global\def\net:source:draw #1(#2,#3)#4^^M{% name/x/y/label \placesize=\sourcesize \transsize=\sourcesize% \place[dimen=outer]#1(#2,#3) \trans #1(#2,#3)#4 \endopt}} %% %% transitions %% \newopt{net:trans}"{\let\net:math\relax \let\net:endmath\relax \nextopt} \newopt{net:trans}={\psset{doubleline=true}\nextopt} \newopt{net:trans}!{\psset{linewidth=2pt,linecolor=black}\nextopt} \newopt{net:trans}*{\let\net:trans:draw\net:trans:draw:rectangle \nextopt} \newopt{net:trans}[#1]{\psset{#1}\nextopt} \def\net:trans{\let\net:trans:draw\net:trans:draw:square \getopt{net:trans}\net:trans:draw} {\catcode`\^^M=\active \let^^M=\relax % \global\def\net:trans:draw:square #1(#2,#3)#4^^M{% name/x/y/label \global\edef\net:x{#2}\global\edef\net:y{#3}\global\def\net:s{square}% \rput(#2,#3){\rnode{#1}{\psframebox[framesep=-\pslinewidth]{% \hbox to \transsize{\hss\vbox to \transsize{\vss}}}}}% \rput(#2,#3){\hbox{\net:math\the\everylabel #4\net:endmath}}\endopt}} {\catcode`\^^M=\active \let^^M=\relax % \global\def\net:trans:draw:rectangle #1(#2,#3)#4^^M{% options/name/x/y/label \global\edef\net:x{#2}\global\edef\net:y{#3}\global\def\net:s{rectangle}% {\setbox0=\hbox{\net:math\the\everylabel #4\net:endmath}\dimen0=\ht0 % \advance\dimen0 by \dp0 \advance\dimen0 by 4pt % \global\edef\net:h{\the\dimen0}\dimen0=\wd0 % \advance\dimen0 by 4pt \global\edef\net:w{\the\dimen0}}% \rput(#2,#3){\rnode{#1}{\psframebox[framesep=2pt]{% \hbox{\net:math\the\everylabel #4\net:endmath}}}}\endopt}} %% %% module %% \def\net:module{\getopt{net:trans}\net:module:draw} {\catcode`\^^M=\active \let^^M=\relax % \global\def\net:module:draw #1(#2,#3)#4^^M{% name/x/y/label \psclip{\rput(#2,#3){\rnode{#1}{\psframebox[framesep=-\pslinewidth]{% \hbox to \modulesize{\hss\vbox to \modulesize{\vss}}}}}}% \pscustom{\moveto(#2,#3)% \rlineto(-.2\modulesize,-.2\modulesize)% \movepath(.5\modulesize,-.3\modulesize)}% \endpsclip% \transsize=\modulesize\trans #1(#2,#3)#4 \endopt}} %% %% store %% \def\net:store{\getopt{net:place}\net:store:draw} {\catcode`\^^M=\active \let^^M=\relax % \global\def\net:store:draw #1(#2,#3)#4^^M{% name/x/y/label \placesize=\storesize% \psclip{\cnode(#2,#3){.5\placesize}{ }}% \pscustom{\moveto(#2,#3)% \rlineto(.5\storesize,.5\storesize)% \rlineto(-\storesize,-\storesize)% \stroke\moveto(#2,#3)% \rlineto(.5\storesize,-.5\storesize)% \rlineto(-\storesize,\storesize)}% \endpsclip% \place #1(#2,#3) \endopt}} %% %% free text %% \newopt{net:text}"{\let\net:math\relax \let\net:endmath\relax \nextopt} \newopt{net:text}[#1]{\psset{#1}\nextopt} \def\net:text{\getopt{net:text}\net:text:draw} {\catcode`\^^M=\active \let^^M=\relax % \global\def\net:text:draw #1(#2,#3)#4^^M{% options/name/x/y/label \global\edef\net:x{#2}\global\edef\net:y{#3}% \global\def\net:s{rectangle}% {\setbox0=\hbox{\net:math\the\everylabel #4\net:endmath}\dimen0=\ht0 % \advance\dimen0 by \dp0 \advance\dimen0 by 4pt % \global\edef\net:h{\the\dimen0}\dimen0=\wd0 % \advance\dimen0 by 4pt \global\edef\net:w{\the\dimen0}}% \rput(#2,#3){\rnode{#1}{\hbox{\net:math\the\everylabel % #4\net:endmath}}}\endopt}} %% %% links %% \newopt{net:link}"{\let\net:math\relax \let\net:endmath\relax \nextopt} \newopt{net:link}^{\def\net:link:put{\aput}\nextopt} \newopt{net:link}_{\def\net:link:put{\bput}\nextopt} \newopt{net:link}*{\def\net:link:put{\lput*}\nextopt} \newopt{net:link}={\psset{doubleline=true}\nextopt} \newopt{net:link}!{\psset{linewidth=2pt,linecolor=black}\nextopt} \newopt{net:link}<#1>{\def\net:link:pos{(#1)}\nextopt} \newopt{net:link}[#1]{\psset{#1}\nextopt} \newopt{net:link}/#1/{\def\net:link:arrows{{#1}}\nextopt} \def\net:link{\def\net:link:put{\aput}\def\net:s{link}% \def\net:link:arrows{{-}}% \def\net:link:pos{(.5)}\def\net:link:opt{}% \getopt{net:link}\net:link:draw} {\catcode`\^^M=\active \let^^M=\relax % \global\def\net:link:draw #1#2#3^^M{% from/to/label \expandafter\ncarc\net:link:arrows{#1}{#2}% \expandafter\net:link:put\net:link:pos{% \hbox{\net:math\the\everylabel #3\net:endmath}}\endopt}} \def\net:arc{\link/->/} %% %% additional labels %% % calls the right label macro \newopt{net:label}"{\let\net:math\relax \let\net:endmath\relax \nextopt} \def\net:label{\getopt{net:label}\net:label:call} \def\net:label:call{\edef\net:label:shape{net:label:\net:s}% \expandafter\csname\net:label:shape\endcsname} % if no node or link has been drawn, we just ignore the label {\catcode`\^^M=\active \let^^M=\relax % \global\def\net:label:empty #1^^M{}} % calculates angle which can be an integer, one or two letters. \def\net:setangle #1{\relax \expandafter\ifx\csname net:angle:#1\endcsname\relax \edef\net:angle{#1}% \else\edef\net:angle{\csname net:angle:#1\endcsname}\fi} \def\net:angle:r{0} \def\net:angle:tr{45} \let\net:angle:rt=\net:angle:tr \def\net:angle:t{90} \def\net:angle:tl{135} \let\net:angle:lt=\net:angle:tl \def\net:angle:l{180} \def\net:angle:bl{225} \let\net:angle:lb=\net:angle:b \def\net:angle:b{270} \def\net:angle:br{315} \let\net:angle:rb=\net:angle:br % for a circle {\catcode`\^^M=\active \let^^M=\relax % \global\def\net:label:circle #1#2^^M{% pos/text \net:setangle{#1}% \advance\placesize by \labelsep% \uput{.5\placesize}[\net:angle](\net:x,\net:y){% \hbox{\net:math\the\everylabel #2\net:endmath}}\endopt}} % for a square {\catcode`\^^M=\active \let^^M=\relax % \global\def\net:label:square #1#2^^M{% pos/text \net:setangle{#1}% \begingroup \dimen0=\net:angle pt% \loop \ifdim\dimen0<-45pt \advance\dimen0 by 90pt \repeat% \loop \ifdim\dimen0>45pt \advance\dimen0 by -90pt \repeat% \edef\tmp{\expandafter\clear\the\dimen0}% \cossin\cos\sin\tmp% \realdiv\tmp=\sin/\cos% \realmul\tmp=\tmp*\tmp% \realadd\tmp=1+\tmp% \realsqrt\tmp\tmp% \realmul\tmp=.65*\tmp% \uput{\tmp\transsize}[\net:angle](\net:x,\net:y){% \hbox{\net:math\the\everylabel #2\net:endmath}}\endgroup\endopt}} % for a rectangle {\catcode`\^^M=\active \let^^M=\relax % \global\def\net:label:rectangle #1#2^^M{% pos/text \net:setangle{#1}% \begingroup \dimen0=\net:angle pt% \loop \ifdim\dimen0<0pt \advance\dimen0 by 360pt \repeat% \loop \ifdim\dimen0>360pt \advance\dimen0 by -360pt \repeat% \ifdim\dimen0>180pt \advance\dimen0 by -180pt \fi% \ifdim\dimen0>90pt \advance\dimen0 by -180pt \dimen0=-\dimen0 \fi% \edef\tmp{\expandafter\clear\the\dimen0}% \cossin\cos\sin\tmp% \edef\w{\expandafter\clear\net:w}% \edef\h{\expandafter\clear\net:h}% \realmul\w=.4*\w% the test below is done using \w, this gives it a \realmul\h=.6*\h% greater importance so is is balanced here. \realmul\ww=\w*\w% \realmul\hh=\h*\h% \realadd\d=\ww+\hh% \realsqrt\d\d% \realmul\dcos=\cos*\d% \ifdim\dcos pt < \w pt % \realdiv\tmp=\h/\sin% \else% \realdiv\tmp=\w/\cos% \fi% \realmul\tmp=1.5*\tmp% \uput{\tmp pt}[\net:angle](\net:x,\net:y){% \hbox{\net:math\the\everylabel #2\net:endmath}}\endgroup\endopt}} % for a link \def\net:label:link{\getopt{net:angle}\net:label:link:draw} {\catcode`\^^M=\active \let^^M=\relax % \global\def\net:label:link:draw #1^^M{% from/to/label \expandafter\net:link:put\net:link:pos{% \hbox{\net:math\the\everylabel #1\net:endmath}}\endopt\endopt}} %% %% trigonometric and real number stuff %% % absolute value \def\realabs #1=|#2|{{% \dregA=#2pt \ifdim \dregA<0pt \dregA=-\dregA \fi \global\edef\tmptrigoA{\expandafter\clear\the\dregA}}% \edef#1{\tmptrigoA}} % add two reals \def\realadd #1=#2+#3{{% \dregA=#2pt \dregB=#3pt \advance\dregA by\dregB \global\edef\tmptrigoA{\expandafter\clear\the\dregA}}% \edef#1{\tmptrigoA}} % substract two reals \def\realsub #1=#2-#3{% \realadd#1=#2+{-#3}} % multiply two reals \def\realmul #1=#2*#3{{% \dregA=#2pt \dregA=#3\dregA \global\edef\tmptrigoA{\expandafter\clear\the\dregA}}% \edef#1{\tmptrigoA}} % divide two reals \def\realdiv #1=#2/#3{{% \dregA=#2pt\cregA=\dregA \dregA=#3pt\cregB=\dregA \intdiv\res=\cregA/\cregB \global\edef\tmptrigoA{\res}}% \edef#1{\tmptrigoA}} % radians -> degrees \def\todeg #1#2{% #1=deg(#2) \realmul#1=#2*{180}% \realdiv#1=#1/{3.14159265359}} % degrees -> radian \def\torad #1#2{% #1=rad(#2) \realmul#1=#2*{3.14159265359}% \realdiv#1=#1/{180}} % cosinus and sinus \def\cossin #1#2#3{{% #1=cos(#3) #2=sin(#3) \dregA=#3pt % be sure \dregA is in [-180,180] \loop \ifdim\dregA<-180pt \advance\dregA by 360pt \repeat \loop \ifdim\dregA>180pt \advance\dregA by -360pt \repeat % let's go \ifdim\dregA<-90pt \advance\dregA by 90pt \edef\tmptrigoA{\expandafter\clear\the\dregA}% \torad\rad\tmptrigoA \cordic\negsin\cos\rad \global\edef\tmptrigoA{\cos}% \global\edef\tmptrigoB{-\negsin}% \else\ifdim\dregA>90pt \advance\dregA by -90pt \edef\tmptrigoA{\expandafter\clear\the\dregA}% \torad\rad\tmptrigoA \cordic\sin\negcos\rad \global\edef\tmptrigoA{-\negcos}% \global\edef\tmptrigoB{\sin}% \else \edef\tmptrigoA{\expandafter\clear\the\dregA}% \torad\rad\tmptrigoA \cordic\cos\sin\rad \global\edef\tmptrigoA{\cos}% \global\edef\tmptrigoB{\sin}% \fi\fi}% \edef#1{\tmptrigoA}\edef#2{\tmptrigoB}} % square root \def\realsqrt #1#2{{% #1=(#2)^{-1/2} \edef\a{#2}% \edef\an{#2}% \loop \realdiv\anA=\a/\an \realadd\anB=\an+\anA \realdiv\anA=\anB/2 \realsub\err=\an-\anA \dregA=\err pt \ifdim \dregA>0.0001pt \edef\an{\anA}% \repeat \global\edef\tmptrigoA{\anA}}% \edef#1{\tmptrigoA}} %% internal stuff \newdimen\dregA \newdimen\dregB % \newdimen\dregC %\newdimen\dregD \newdimen\dregE \newdimen\dregF \newcount\cregA \newcount\cregB \newcount\cregC \newcount\cregD \newcount\cregE % \newcount\cregF % arrays of numbers \def\setarray #1[#2]=#3{\expandafter \edef\csname#1[#2]\endcsname{#3}} \def\getarray #1=#2[#3]{\edef\tmptrigoA{#2[#3]}% \edef#1{\expandafter\csname\tmptrigoA\endcsname}} % remove trailing `pt' {\catcode`\p=12 \catcode`\t=12 \global\def\clear #1pt{#1}} % divide two integers \def\intdiv #1=#2/#3{{% \cregA=#2% \cregB=#3% \ifnum\cregB<0 \cregA=-\cregA \cregB=-\cregB \fi \cregD=1 \ifnum\cregA<0 \cregA=-\cregA \cregD=-1 \fi \cregC=\cregA\divide\cregC by\cregB \cregE=\cregC\multiply\cregE by\cregB \advance\cregA by-\cregE \cregE=-1 \loop \advance\cregE by1 \ifnum\cregE<16 \multiply\cregC by2 \multiply\cregA by2 \ifnum\cregA<\cregB\else \advance\cregC by1 \advance\cregA by-\cregB \fi \repeat \divide\cregB by2 \ifnum\cregA<\cregB \advance\cregC by1 \fi \ifnum\cregD<0 \cregC=-\cregC \fi \dregA=\cregC sp \global\edef\tmptrigoA{\expandafter\clear\the\dregA}}% \edef#1{\tmptrigoA}} % cordic algorithm to compute cos and sin \def\cordic #1#2#3{{% #1=cos(#3) #2=sin(#3) with #3 \in [-\pi/2,\pi/2] % prepared values \setarray e[0]={.785398163397448}% \setarray e[1]={.463647609000806}% \setarray e[2]={.244978663126864}% \setarray e[3]={.124354994546761}% \setarray e[4]={.0624188099959574}% \setarray e[5]={.0312398334302683}% \setarray e[6]={.0156237286204768}% \setarray e[7]={.00781234106010111}% \setarray e[8]={.00390623013196697}% \setarray e[9]={.00195312251647882}% \setarray e[10]={.000976562189559319}% \setarray e[11]={.000488281211194898}% \setarray e[12]={.000244140620149362}% \setarray e[13]={.00012207031189367}% % init \def\xn{.607252935032446}% \def\yn{0}% \edef\zn{#3}% \cregA=0 \cregB=1 % cordic loop \loop \realdiv\xtmp=\yn/\cregB \realdiv\ytmp=\xn/\cregB \getarray\ztmp=e[\the\cregA]% \dregA=\zn pt \ifdim\dregA<0pt \realadd\xn=\xn+\xtmp \realsub\yn=\yn-\ytmp \realadd\zn=\zn+\ztmp \else \realsub\xn=\xn-\xtmp \realadd\yn=\yn+\ytmp \realsub\zn=\zn-\ztmp \fi \ifnum\cregA<13 \advance\cregA by1 \multiply\cregB by2 \repeat % terminating \global\edef\tmptrigoA{\xn}\global\edef\tmptrigoB{\yn}}% \edef#1{\tmptrigoA}\edef#2{\tmptrigoB}} %% %% end %% \catcode`\:=12