% $Id: pst-node.tex 940 2019-03-03 12:32:03Z herbert $ %% %% BEGIN pst-node.tex %% %% Nodes with PSTricks. %% This uses the header file `pst-node.pro'. %% %% COPYRIGHT 1993, 1994, 1999 by Timothy Van Zandt, tvz@nwu.edu. %% COPYRIGHT 2009-2018 by Herbert Voss, hvoss tug.org. %% %% This program can be redistributed and/or modified under the terms %% of the LaTeX Project Public License Distributed from CTAN %% archives in directory macros/latex/base/lppl.txt. %% % \csname PSTnodesLoaded\endcsname \let\PSTnodesLoaded\endinput \ifx\PSTricksLoaded\endinput\else\input pstricks.tex \fi\relax \ifx\PSTXKeyLoaded\endinput\else \input pst-xkey \fi % \def\fileversion{1.42} \def\filedate{2019/03/03} \message{ v\fileversion, \filedate} % \edef\TheAtCode{\the\catcode`\@} \catcode`\@=11 % \pstheader{pst-node.pro} \pst@addfams{pst-node} % \SpecialCoor % %%%%%%%%%% compatibility stuff \define@boolkey[psset]{pst-node}[Pst@]{trueAngle}[true]{} \psset[pst-node]{trueAngle=false} %%%%%%%%%% compatibility stuff \define@boolkey[psset]{pst-node}[Pst@]{storeNodeInfo}[true]{} \psset[pst-node]{storeNodeInfo=false} % \def\pst@nodedict{tx@NodeDict begin } \def\pst@zapspace#1 #2{% #1% \ifx#2\@empty\else\expandafter\pst@zapspace\fi #2} % \def\pst@getnode#1#2{\pst@expandafter\pst@@getnode{#1},,\@nil#2} \def\pst@@getnode#1,#2,#3\@nil#4{% \ifx\@empty#3\@empty \edef#4{/N@\pst@zapspace#1 \@empty\space}% \else \pst@cntg=#1\relax \pst@cnth=#2\relax \edef#4{/N@M-\ifnum\psmatrixcnt=\z@ 1\else\the\psmatrixcnt\fi -\the\pst@cntg-\the\pst@cnth\space}% \fi} % % bug fix for xelatex, dvipdfmx uses the wrong scaling \def\tx@NewNode{/NodeScale {\ifx\pstnodescale\@undefined \else\pstnodescale \fi} def NewNode } % \def\psopenNodeFile{% \pst@Verb{ %globaldict begin % tx@NodeDict begin (\jobname.nodes) (w) file /NodeFile exch def % end }} % \def\pscloseNodeFile{\pstVerb{ tx@NodeDict begin NodeFile closefile end }} % \define@boolkey[psset]{pst-node}[Pst@]{showNode}[true]{\ifPst@showNode\psopenNodeFile\fi}% write coors into the logfile \define@boolkey[psset]{pst-node}[Pst@]{markNode}[true]{}% makr the node with its name \define@boolkey[psset]{pst-node}[Pst@]{saveNodeCoors}[true]{} \define@key[psset]{pst-node}{NodeCoorPrefix}[]{\def\psk@NodeCoorPrefix{#1}}% if empty it is N-.x|y \psset[pst-node]{saveNodeCoors=false,showNode=false,markNode=false,NodeCoorPrefix=}% x|y> % \def\pst@newnode#1#2#3#4{% \pst@killglue \leavevmode \pst@getnode{#1}\pst@thenode \pst@Verb{ \ifPst@saveNodeCoors \ifx\relax#3\relax 0 0 \else gsave \pst@dict STV CP T end #3 \tx@UserCoor grestore \fi \if$\psk@NodeCoorPrefix$ /N-#1.y exch def /N-#1.x exch def \else /\psk@NodeCoorPrefix#1y exch def /\psk@NodeCoorPrefix#1x exch def \fi \fi \pst@nodedict {#3} \ifx\psk@name\relax false \else \psk@name true \fi \pst@thenode #2 {#4} \ifPst@showNode exch dup /NodeType ED exch NodeType 10 eq { % pnode type 5 copy cvlit aload pop 20 string cvs (; ) 6 2 roll % InitPnode 20 string cvs (; ) 7 2 roll % type 20 string cvs (; ) 8 2 roll %/N@Name 20 string cvs (; ) 9 2 roll % true/false cvlit dup length 2 eq { aload pop exch 20 string cvs (; ) 11 2 roll 20 string cvs (, ) 12 2 roll % x,y (\string\n) % add newline 13 array astore concatstringarray } { 255 string cvs (; ) 10 2 roll (\string\n) % add newline 11 array astore concatstringarray } ifelse NodeFile exch writestring } if NodeType 14 eq { % dotnode 5 copy /@@temp ED % gsave @@temp % to get X Y 4 -1 roll cvlit pop ( OvalNodePos ) (; ) 5 2 roll 20 string cvs (; ) 6 2 roll % type 20 string cvs (; ) 7 2 roll %/N@Name 20 string cvs (; ) 8 2 roll % true/false Y 20 string cvs (; ) 10 2 roll X 20 string cvs (, ) 12 2 roll (\string\n) % add newline 13 array astore concatstringarray % grestore tx@NodeDict begin NodeFile exch writestring end } if \fi \tx@NewNode end }% % \global\let\psk@name\relax% \pstree@nodehook% \global\let\pstree@nodehook\relax} % \let\pstree@nodehook\relax \define@boolkey[psset]{pst-node}[Pst@]{nodealign}[true]{} \psset[pst-node]{nodealign=false} \def\pst@nodealign{% \pst@dimg=\ht\pst@hbox \advance\pst@dimg by -\dp\pst@hbox \divide\pst@dimg by \tw@ \lower\pst@dimg} % \def\tx@InitPnode{InitPnode } \def\pnode{\@ifnextchar[{\pnode@i}{\pnode@iii}} \def\pnode@i[#1]{\@ifnextchar({\pnode@ii[#1]}{\pnode@ii[#1](0,0)}} \def\pnode@ii[#1](#2)#3{% \pst@getcoor{#1}\pst@tempA% \pst@getcoor{#2}\pst@tempB% \pst@newnode{#3}{10}{\pst@tempA \pst@tempB 3 -1 roll add 3 1 roll add exch }{\tx@InitPnode}% \ifPst@showNode\psdot(#3)\uput[\ifx\psk@rot\@empty0\else\psk@rot\fi]{0}(#3){#3}\fi \ignorespaces} % \def\pnode@iii{\@ifnextchar({\pnode@}{\pnode@(0,0)}} \def\pnode@(#1)#2{% \pst@@getcoor{#1}% \pst@newnode{#2}{10}{\pst@coor}{\tx@InitPnode}% \ifPst@showNode\psdot(#2)\uput[\ifx\psk@rot\@empty0\else\psk@rot\fi]{0}(#2){#2}\fi \ignorespaces} % \def\pnodes{\@ifnextchar[{\pnodes@i}{\pnodes@i[0,0]}} \def\pnodes@i[#1]{\@ifnextchar({\psnodes@ii[#1]}{\pnodes@ii}} \def\psnodes@ii[#1](#2)#3{% \pnode[#1](#2){#3}% \@ifnextchar({\psnodes@ii[#1]}{}% } % \def\tx@InitCnode{InitCnode } % \def\cnode{\pst@object{cnode}} \def\cnode@i{\@ifnextchar({\cnode@ii}{\cnode@ii(0,0)}} \def\cnode@ii(#1)#2#3{% \leavevmode \hbox{% \use@par \pst@@getcoor{#1}% \pssetlength\pst@dimc{#2}% \pst@dimg=\psk@dimen\pslinewidth \advance\pst@dimc-\pst@dimg \advance\pst@dimc.5\pslinewidth \ifPst@nodealign \kern\pst@dimc \vrule width\z@ height \pst@dimc depth \pst@dimc \fi \pscircle@do(#1){#2}% \pst@newnode{#3}{11}{\pst@coor \pst@number\pst@dimc}{\tx@InitCnode}% \ifPst@nodealign\kern\pst@dimc\fi% }% \ignorespaces} % \def\Cnode{\pst@object{Cnode}} \def\Cnode@i{\@ifnextchar({\Cnode@ii}{\Cnode@ii(0,0)}} \def\Cnode@ii(#1)#2{\cnode@ii(#1){\psk@radius}{#2}}% % \def\cnodeput{\pst@object{cnodeput}} \def\cnodeput@i{\@ifnextchar({\cnodeput@iii}{\cnodeput@ii}} \def\cnodeput@ii#1{% \addto@par{rot={#1}}% \@ifnextchar({\cnodeput@iii}{\cnodeput@iii(\z@,\z@)}% } \def\cnodeput@iii(#1)#2{% \pst@killglue \@fixedradiusfalse \def\pst@nodehook{\cnodeput@iv{#2}}% \pst@makebox{\cput@v{#1}}% } \def\cnodeput@iv#1{% \pst@newnode{#1}{11}{\pscirclebox@iv \pst@number\pslinewidth add}{\tx@InitCnode}% \global\let\pst@nodehook\relax \ignorespaces } \def\Cnodeput{\pst@object{Cnodeput}} \def\Cnodeput@i{\@ifnextchar({\Cnodeput@iii}{\Cnodeput@ii}} \def\Cnodeput@ii#1{% \addto@par{rot={#1}}% \@ifnextchar({\Cnodeput@iii}{\Cnodeput@iii(\z@,\z@)}} \def\Cnodeput@iii(#1)#2{% \pst@killglue \@fixedradiustrue \def\pst@nodehook{\Cnodeput@iv{#2}}% \pst@makebox{\cput@v{#1}}% } \def\Cnodeput@iv#1{% \pst@newnode{#1}{11}{% \pst@number{\wd\pst@hbox} 2 div \pst@number\pst@dima % x y \pst@number\pst@dimb \pst@number\pslinewidth \psk@dimen .5 sub mul sub }% r {\tx@InitCnode}% \global\let\pst@nodehook\relax} % \def\circlenode{\pst@object{circlenode}} \def\circlenode@i#1{\pst@makebox{\circlenode@ii{#1}}} \def\circlenode@ii#1{% \begingroup \pst@useboxpar \setbox\pst@hbox=\hbox{% \cnodeput@iv{#1}% \pscirclebox@iii \box\pst@hbox}% \ifPst@nodealign \psboxseptrue \fi \ifpsboxsep \pscirclebox@sep \fi \leavevmode \ifPst@nodealign\pst@nodealign\fi \box\pst@hbox \endgroup} % \def\Circlenode{\pst@object{Circlenode}} \def\Circlenode@i#1{\pst@makebox{\Circlenode@ii{#1}}} \def\Circlenode@ii#1{% \begingroup \pst@useboxpar \pst@dima=\ht\pst@hbox \advance\pst@dima by -\dp\pst@hbox \divide\pst@dima by \tw@ \pssetlength\pst@dimb\psk@radius \setbox\pst@hbox=\hbox{% \Cnodeput@iv{#1}% \pscircle(.5\wd\pst@hbox,\pst@dima){\pst@dimb}% \box\pst@hbox}% \ifPst@nodealign \psboxseptrue \fi \ifpsboxsep \psCirclebox@sep \fi \leavevmode \ifPst@nodealign\pst@nodealign\fi \box\pst@hbox \endgroup} \def\tx@GetRnodePos{GetRnodePos } \def\tx@InitRnode{InitRnode } % \def\psnode{\pst@object{psnode}} \def\psnode@i{\@ifnextchar(\psnode@ii{\psnode@ii(0,0)}} \def\psnode@ii(#1)#2#3{% #1: coordinates, #2: node name, #3 contents \rput(#1){\rnode{#2}{#3}}} % \def\rnode{\@ifnextchar[{\rnode@i}{\def\pst@par{}\rnode@ii}} \def\rnode@i[#1]{\def\pst@par{ref=#1}\rnode@ii} \def\rnode@ii#1{\pst@makebox{\rnode@iii\rnode@iv{#1}}} \def\rnode@iii#1#2{% % DG modification begin - Jan. 1997 \leavevmode % DG modification end \begingroup % DG/SR modification begin - Apr. 28, 1998 - Patch 6 \pst@useboxpar % DG/SR modification end #1% %\if@star\pst@starbox\fi% commented to fix bug witzh \psframebox*{\rnode...} \ifPst@nodealign\lower\pst@dimb\fi \hbox{% \pst@newnode{#2}{16}{% \pst@number{\ht\pst@hbox}% \pst@number{\dp\pst@hbox}% \pst@number{\wd\pst@hbox}% \pst@number\pst@dima% \pst@number\pst@dimb}% {\tx@InitRnode}% \box\pst@hbox}% \endgroup} \def\rnode@iv{% \pst@dima=\psk@xref\wd\pst@hbox \ifx\psk@yref\relax \pst@dimb=\z@ \else \pst@dimb=\ht\pst@hbox \advance\pst@dimb\dp\pst@hbox \pst@dimb=\psk@yref\pst@dimb \advance\pst@dimb-\dp\pst@hbox \fi} % \define@key[psset]{pst-node}{href}[0]{\pst@checknum{#1}\psk@href} \psset[pst-node]{href=0} \define@key[psset]{pst-node}{vref}[0.7ex]{\def\psk@vref{#1}} \psset[pst-node]{vref=0.7ex} \def\Rnode{\pst@object{Rnode}} \def\Rnode@i#1{\pst@makebox{\rnode@iii\Rnode@ii{#1}}} \def\Rnode@ii{% % DG modification begin - Jan. 1997 % - \begingroup removed as it seems to doesn't work any more % - \Rnode doesn't process the optional parameter changes %\begingroup \use@par % DG modification end \pst@dima=\psk@href\wd\pst@hbox \advance\pst@dima\wd\pst@hbox \divide\pst@dima 2 \pssetlength\pst@dimb{\psk@vref}} \def\tx@DiaNodePos{DiaNodePos } \def\dianode{\pst@object{dianode}} \def\dianode@i#1{\pst@makebox{\dianode@ii{#1}}} \def\dianode@ii#1{% \begingroup \pst@useboxpar \psdiabox@iii \setbox\pst@hbox=\hbox{% \pst@newnode{#1}{14}{}{% /X \pst@number\pst@dima def /Y \pst@number\pst@dimb def /w \pst@number\pst@dimc 2 mul def /h \pst@number\pst@dimd 2 mul def /NodePos { \tx@DiaNodePos } def}% \box\pst@hbox}% \ifPst@nodealign\psboxseptrue\fi \ifpsboxsep\psdiabox@sep\fi % DG/SR modification begin - Sep. 2, 1997 - Patch 3 \leavevmode % DG/SR modification end \ifPst@nodealign\lower\pst@dimb\fi \box\pst@hbox \endgroup} % \def\tx@TriNodePos{TriNodePos } \def\tx@InitTriNode{InitTriNode } % \def\trinode{\pst@object{trinode}} \def\trinode@i#1{\pst@makebox{\trinode@ii{#1}}} \def\trinode@ii#1{% \begingroup% \pst@useboxpar% \pstribox@iii \setbox\pst@hbox=\hbox{% \pst@newnode{#1}{14}{}{ \pst@number\pst@dimc \pst@number\pst@dimd \ifodd\psk@trimode exch \pst@number\pst@dima \else \pst@number\pst@dimb \fi \psk@trimode \pst@number{\wd\pst@hbox} \pst@number{\ht\pst@hbox} \pst@number{\dp\pst@hbox} \tx@InitTriNode }% \box\pst@hbox% }% \ifPst@nodealign\psboxseptrue\fi \ifpsboxsep\pstribox@sep\fi % DG/SR modification begin - Sep. 2, 1997 - Patch 3 \leavevmode % DG/SR modification end \ifPst@nodealign\lower\pst@tempa\fi \box\pst@hbox% \endgroup} % \def\tx@OvalNodePos{OvalNodePos } \def\ovalnode{\pst@object{ovalnode}} \def\ovalnode@i#1{\pst@makebox{\ovalnode@ii{#1}}} \def\ovalnode@ii#1{% \begingroup \pst@useboxpar \psovalbox@iii \setbox\pst@hbox=\hbox{% \pst@newnode{#1}{14}{}{% /X \pst@number\pst@dima def /Y \pst@number\pst@dimb def /w \pst@number\pst@dimc def /h \pst@number\pst@dimd def /NodePos { \tx@OvalNodePos } def}% \unhbox\pst@hbox}% \ifPst@nodealign\psboxseptrue\fi \ifpsboxsep\psovalbox@sep\fi % DG/SR modification begin - Sep. 2, 1997 - Patch 3 \leavevmode % DG/SR modification end \ifPst@nodealign\lower\pst@dimb\fi \box\pst@hbox \endgroup} % \def\dotnode{\pst@object{dotnode}} \def\dotnode@i{\@ifnextchar({\dotnode@ii}{\dotnode@ii(\z@,\z@)}} \def\dotnode@ii(#1)#2{% \leavevmode \hbox{% \use@par \pst@@getcoor{#1}% \pst@getdotsize \pstree@nodehook \ifPst@nodealign \pst@dima=\pst@dimg \kern\pst@dima \vrule width\z@ height \pst@dimh depth \pst@dimh \fi \pst@newnode{#2}{14}{}{ \pst@coor /Y exch def /X exch def /w \pst@number\pst@dimg def /h \pst@number\pst@dimh def /NodePos { \tx@OvalNodePos } def}% \psdot@ii(#1)% \ifPst@nodealign\kern\pst@dima\fi}% \ifPst@markNode\uput[\ifx\psk@rot\@empty0\else\psk@rot\fi]{0}(#2){#2}\fi \ignorespaces} % \def\dotnodes{\pst@object{dotnodes}} \def\dotnodes@i{\use@par\dotnodes@ii} \def\dotnodes@ii(#1)#2{% \dotnode(#1){#2}% \@ifnextchar(\dotnodes@ii{\def\pst@par{}}} % \define@key[psset]{pst-node}{framesize}{\pst@expandafter\psset@@framesize{#1} \@nil} \def\psset@@framesize#1 #2\@nil{% \pssetlength\pst@dimg{#1}% \divide\pst@dimg2 \edef\psk@framewidth{\pst@number\pst@dimg}% \ifx\@empty#2\@empty \let\psk@frameheight\psk@framewidth \else \pssetlength\pst@dimg{#2}% \divide\pst@dimg2 \edef\psk@frameheight{\pst@number\pst@dimg}% \fi} % \psset[pst-node]{framesize=10pt} % \def\fnode{\pst@object{fnode}} \def\fnode@i{\@ifnextchar({\fnode@ii}{\fnode@ii(\z@,\z@)}} \def\fnode@ii(#1)#2{% \leavevmode \pst@killglue \hbox{% \use@par% \begin@ClosedObj% \ifPst@nodealign \kern\psk@framewidth\p@ \vrule width\z@ height \psk@frameheight\p@ depth \psk@frameheight\p@ \edef\pst@coor{0 0 }% \else\pst@@getcoor{#1}\fi \pst@newnode{#2}{14}{}{ \pst@coor /Y exch def /X exch def /d \psk@dimen .5 sub CLW mul neg def /r \psk@framewidth d add def /l r neg def /u \psk@frameheight d add def /d u neg def /NodePos { \tx@GetRnodePos } def}% \addto@pscode{ /x2 \psk@framewidth CLW \psk@dimen mul sub def /y2 \psk@frameheight CLW \psk@dimen mul sub def \pst@coor 2 copy y2 sub /y1 ED x2 sub /x1 exch def y2 add /y2 exch def x2 add /x2 exch def \psk@cornersize 1 index 0 eq { pop pop \tx@Rect } { \tx@OvalFrame } ifelse}% \def\pst@linetype{2}% \showpointsfalse% \end@ClosedObj% \ifPst@nodealign\kern\psk@framewidth\p@\fi}% end of \hbox \ignorespaces} % % % This fixes a bug in pst-node, where the XY-direction is wrong % the types are changed 1<->2 between X<->Y % \define@key[psset]{}{XnodesepA}{\pst@getlength{#1}\psk@nodesepA\def\psk@nodeseptypeA{2 }} \define@key[psset]{}{XnodesepB}{\pst@getlength{#1}\psk@nodesepB\def\psk@nodeseptypeB{2 }} \define@key[psset]{}{Xnodesep}{% \pst@getlength{#1}\psk@nodesepA \let\psk@nodesepB\psk@nodesepA \def\psk@nodeseptypeA{2 }% \def\psk@nodeseptypeB{2 }} \define@key[psset]{}{YnodesepA}{\pst@getlength{#1}\psk@nodesepA\def\psk@nodeseptypeA{1 }} \define@key[psset]{}{YnodesepB}{\pst@getlength{#1}\psk@nodesepB\def\psk@nodeseptypeB{1 }} \define@key[psset]{}{Ynodesep}{% \pst@getlength{#1}\psk@nodesepA \let\psk@nodesepB\psk@nodesepA \def\psk@nodeseptypeA{1 }% \def\psk@nodeseptypeB{1 }} %%%% end bugfix %%%%% \define@key[psset]{pst-node}{nodesepA}[0pt]{\pst@getlength{#1}\psk@nodesepA \def\psk@nodeseptypeA{0 }} \define@key[psset]{pst-node}{nodesepB}[0pt]{\pst@getlength{#1}\psk@nodesepB \def\psk@nodeseptypeB{0 }} \define@key[psset]{pst-node}{nodesep}[0pt]{% \pst@getlength{#1}\psk@nodesepA \let\psk@nodesepB\psk@nodesepA \def\psk@nodeseptypeA{0 }% \def\psk@nodeseptypeB{0 }} \psset[pst-node]{nodesep=0pt} %\define@key[psset]{pst-node}{XnodesepA}[]{\pst@getlength{#1}\psk@nodesepA \def\psk@nodeseptypeA{1 }} %\define@key[psset]{pst-node}{XnodesepB}[]{\pst@getlength{#1}\psk@nodesepB \def\psk@nodeseptypeB{1 }} %\define@key[psset]{pst-node}{Xnodesep}[]{% % \pst@getlength{#1}\psk@nodesepA % \let\psk@nodesepB\psk@nodesepA % \def\psk@nodeseptypeA{1 }% % \def\psk@nodeseptypeB{1 }} %\define@key[psset]{pst-node}{YnodesepA}[]{\pst@getlength{#1}\psk@nodesepA \def\psk@nodeseptypeA{2 }} %\define@key[psset]{pst-node}{YnodesepB}[]{\pst@getlength{#1}\psk@nodesepB \def\psk@nodeseptypeB{2 }} %\define@key[psset]{pst-node}{Ynodesep}[]{ % \pst@getlength{#1}\psk@nodesepA % \let\psk@nodesepB\psk@nodesepA % \def\psk@nodeseptypeA{2 }% % \def\psk@nodeseptypeB{2 }} \define@key[psset]{pst-node}{armA}[10pt]{\pst@getlength{#1}\psk@armA \def\psk@armtypeA{0 }} \define@key[psset]{pst-node}{armB}[10pt]{\pst@getlength{#1}\psk@armB \def\psk@armtypeB{0 }} \define@key[psset]{pst-node}{arm}[10pt]{% \pst@getlength{#1}\psk@armA \let\psk@armB\psk@armA \def\psk@armtypeA{0 }% \def\psk@armtypeB{0 }} \psset[pst-node]{arm=10pt} \define@key[psset]{pst-node}{XarmA}[]{\pst@getlength{#1}\psk@armA \def\psk@armtypeA{1 }} \define@key[psset]{pst-node}{XarmB}[]{\pst@getlength{#1}\psk@armB \def\psk@armtypeB{1 }} \define@key[psset]{pst-node}{Xarm}{% \pst@getlength{#1}\psk@armA \let\psk@armB\psk@armA \def\psk@armtypeA{1 }% \def\psk@armtypeB{1 }} \define@key[psset]{pst-node}{YarmA}[]{\pst@getlength{#1}\psk@armA \def\psk@armtypeA{2 }} \define@key[psset]{pst-node}{YarmB}[]{\pst@getlength{#1}\psk@armB \def\psk@armtypeB{2 }} \define@key[psset]{pst-node}{Yarm}[]{% \pst@getlength{#1}\psk@armA \let\psk@armB\psk@armA \def\psk@armtypeA{2 }% \def\psk@armtypeB{2 }} \define@key[psset]{pst-node}{offsetA}[0pt]{\pst@getlength{#1}\psk@offsetA} \define@key[psset]{pst-node}{offsetB}[0pt]{\pst@getlength{#1}\psk@offsetB} \define@key[psset]{pst-node}{offset}[0pt]{\pst@getlength{#1}\psk@offsetA\let\psk@offsetB\psk@offsetA} \psset[pst-node]{offset=0pt} \define@key[psset]{pst-node}{angleA}[0]{\pst@getangle{#1}\psk@angleA} \define@key[psset]{pst-node}{angleB}[0]{\pst@getangle{#1}\psk@angleB}% \define@key[psset]{pst-node}{angle}[0]{% \pst@getangle{#1}\psk@angleA \let\psk@angleB\psk@angleA} \psset[pst-node]{angle=0} \define@key[psset]{pst-node}{arcangleA}[8]{\pst@getangle{#1}\psk@arcangleA} \define@key[psset]{pst-node}{arcangleB}[8]{\pst@getangle{#1}\psk@arcangleB}% \define@key[psset]{pst-node}{arcangle}[8]{% \pst@getangle{#1}\psk@arcangleA \let\psk@arcangleB\psk@arcangleA} \psset[pst-node]{arcangle=8} \define@key[psset]{pst-node}{ncurvA}[0.67]{\pst@checknum{#1}\psk@ncurvA} \define@key[psset]{pst-node}{ncurvB}[0.67]{\pst@checknum{#1}\psk@ncurvB}% \define@key[psset]{pst-node}{ncurv}[0.67]{\pst@checknum{#1}\psk@ncurvA\let\psk@ncurvB\psk@ncurvA} \psset[pst-node]{ncurv=0.67} % \def\tx@GetCenter{GetCenter } \def\tx@XYPos{XYPos } \def\tx@GetEdge{GetEdge } \def\tx@AddOffset{AddOffset } \def\tx@GetEdgeA{GetEdgeA } \def\tx@GetEdgeB{GetEdgeB } \def\tx@GetArmA{GetArmA } \def\tx@GetArmB{GetArmB } % \def\check@arrow#1#2{% \check@@arrow#2-\@nil \if@pst\addto@par{arrows=#2}\def\next{#1}% \else\def\next{#1{#2}}\fi \next} \def\check@@arrow#1-#2\@nil{% \ifx\@nil#2\@nil\@pstfalse\else\@psttrue\fi} % \def\tx@InitNC{InitNC } \def\nc@object#1#2#3#4#5{% \csname begin@#1Obj\endcsname \showpointsfalse \pst@getnode{#2}\pst@tempa \pst@getnode{#3}\pst@tempb \gdef\npos@default{#4 }% \addto@pscode{% /NCLW CLW def \pst@nodedict \psk@offsetA \psk@offsetB neg \psk@nodesepA \psk@nodesepB \psk@nodeseptypeA \psk@nodeseptypeB \pst@tempa \pst@tempb \tx@InitNC { #5 } if end }% \def\use@pscode{% \pst@Verb{gsave \tx@STV newpath \pst@code\space grestore}% \gdef\pst@code{}}% \csname end@#1Obj\endcsname \pst@shortput} % \def\npos@default{.5 } % \def\pc@object#1{% \@ifnextchar({\pc@@object#1}{\pst@getarrows{\pc@@object#1}}} \def\pc@@object#1(#2)(#3){% \pnode(#2){@@A}\pnode(#3){@@B}% #1{@@A}{@@B}} % \def\tx@LPutLine{LPutLine } \def\tx@LPutLines{LPutLines } \def\tx@BezierMidpoint{BezierMidpoint } \def\tx@HPosBegin{HPosBegin } \def\tx@HPosEnd{HPosEnd } \def\tx@HPutLine{HPutLine } \def\tx@HPutLines{HPutLines } \def\tx@VPosBegin{VPosBegin } \def\tx@VPosEnd{VPosEnd } \def\tx@VPutLine{VPutLine } \def\tx@VPutLines{VPutLines } \def\tx@HPutCurve{HPutCurve } \def\tx@NCCoor{NCCoor } \def\tx@NCLine{NCLine } % \def\ncline{\pst@object{ncline}} \def\ncline@i{\check@arrow{\ncline@ii}} \def\ncline@ii#1#2{\nc@object{Open}{#1}{#2}{.5}{\tx@NCLine}} % \def\pcline{\pst@object{pcline}} \def\pcline@i{\pc@object\ncline@ii} % \def\ncLine{\pst@object{ncLine}} \def\ncLine@i{\check@arrow{\ncLine@ii}} \def\ncLine@ii#1#2{\nc@object{Open}{#1}{#2}{.5}% % DG/SR modification begin - Apr. 14, 1999 - Patch 9 %{\tx@NCLine /LPutPos { xB xA yB yA \tx@LPutLine } def}} {\tx@NCLine /LPutPos { xB yB xA yA \tx@LPutLine } def}} % DG/SR modification end % \def\tx@NCLines{NCLines } \def\nclines{\pst@object{nclines}} \def\nclines@i{\check@arrow\nclines@ii} \def\nclines@ii#1#2{% \begingroup \use@par \def\pst@aftercoors{\nclines@iii{#1}{#2}}% \def\pst@coors{}% \pst@@getcoors} \def\nclines@iii#1#2{% \nc@object{Open}{#1}{#2}{.5}{% tx@Dict begin \psline@iii pop end mark \pst@coors \tx@NCLines}% \endgroup \ignorespaces} \def\tx@NCCurve{NCCurve } \def\nccurve{\pst@object{nccurve}} \def\nccurve@i{\check@arrow{\nccurve@ii}} \def\nccurve@ii#1#2{\nc@object{Open}{#1}{#2}{.5}{% /AngleA \psk@angleA\space def /AngleB \psk@angleB\space def \psk@ncurvB\space \psk@ncurvA\space \tx@NCCurve}} \def\pccurve{\pst@object{pccurve}} \def\pccurve@i{\pc@object\nccurve@ii} % \def\ncarc{\pst@object{ncarc}} \def\ncarc@i{\check@arrow{\ncarc@ii}} \def\ncarc@ii#1#2{\nc@object{Open}{#1}{#2}{.5}{% yB yA sub xB xA sub \tx@Atan dup \psk@arcangleA\space add /AngleA exch def \psk@arcangleB\space sub 180 add /AngleB exch def \psk@ncurvB\space \psk@ncurvA\space \tx@NCCurve}} \def\pcarc{\pst@object{pcarc}} \def\pcarc@i{\pc@object\ncarc@ii} % \def\tx@NCAngles{NCAngles } % %border or center as reference point (hv) \define@boolkey[psset]{pst-node}[Pst@]{pcRef}[true]{} \psset[pst-node]{pcRef=false} % \def\ncangles{\pst@object{ncangles}} \def\ncangles@i{\check@arrow{\ncangles@ii}} \def\ncangles@ii#1#2{% \nc@object{Open}{#1}{#2}{1.5}{\ncangles@iii \tx@NCAngles}} \def\ncangles@iii{ tx@Dict begin \psline@iii pop end /AngleA \psk@angleA def /AngleB \psk@angleB def /ArmA \psk@armA \ifPst@pcRef GetEdgeA yA yA1 sub dup mul xA xA1 sub dup mul add sqrt sub \fi def /ArmB \psk@armB def /ArmTypeA \psk@armtypeA def /ArmTypeB \psk@armtypeB def } % \def\pcangles{\pst@object{pcangles}} \def\pcangles@i{\pc@object\ncangles@ii} \def\tx@NCAngle{NCAngle } \def\ncangle{\pst@object{ncangle}} \def\ncangle@i{\check@arrow{\ncangle@ii}} \def\ncangle@ii#1#2{% \nc@object{Open}{#1}{#2}{1.5}{\ncangles@iii \tx@NCAngle}} \def\pcangle{\pst@object{pcangle}} \def\pcangle@i{\pc@object\ncangle@ii} \def\tx@NCBar{NCBar } \def\ncbar{\pst@object{ncbar}} \def\ncbar@i{\check@arrow{\ncbar@ii}} \def\ncbar@ii#1#2{\nc@object{Open}{#1}{#2}{1.5}{% \ncangles@iii /AngleB \psk@angleA def \tx@NCBar}} \def\pcbar{\pst@object{pcbar}} \def\pcbar@i{\pc@object\ncbar@ii} % \define@key[psset]{pst-node}{lineAngle}[0]{% \ifdim#1pt=\z@\else\psset{armB=0.5}\fi \def\psk@lineAngle{#1}}% \psset[pst-node]{lineAngle=0}% % \def\tx@NCDiag{NCDiag } \def\ncdiag{\pst@object{ncdiag}} \def\ncdiag@i{\check@arrow{\ncdiag@ii}} \def\ncdiag@ii#1#2{% \nc@object{Open}{#1}{#2}{1.5}{\ncangles@iii \psk@lineAngle\space \tx@NCDiag}} % \def\pcdiag{\pst@object{pcdiag}} \def\pcdiag@i{\pc@object\ncdiag@ii} % \def\tx@NCDiagg{NCDiagg } \def\ncdiagg{\pst@object{ncdiagg}} \def\ncdiagg@i{\check@arrow{\ncdiagg@ii}} \def\ncdiagg@ii#1#2{% \nc@object{Open}{#1}{#2}{.5}{\ncangles@iii \psk@lineAngle\space \tx@NCDiagg}} \def\pcdiagg{\pst@object{pcdiagg}} % \def\pcdiagg@i{\pc@object\ncdiagg@ii} \def\tx@NCLoop{NCLoop } \define@key[psset]{pst-node}{loopsize}{\pst@getlength{#1}\psk@loopsize} \psset[pst-node]{loopsize=1cm} \def\ncloop{\pst@object{ncloop}} \def\ncloop@i{\check@arrow{\ncloop@ii}} \def\ncloop@ii#1#2{% \nc@object{Open}{#1}{#2}{2.5}% {\ncangles@iii /loopsize \psk@loopsize def \tx@NCLoop}} \def\pcloop{\pst@object{pcloop}} \def\pcloop@i{\pc@object\ncloop@ii} \def\tx@NCCircle{NCCircle } \def\nccircle{\pst@object{nccircle}} \def\nccircle@i{\check@arrow{\nccircle@ii}} \def\nccircle@ii#1#2{% \pssetlength\pst@dima{#2}% \nc@object{Open}{#1}{#1}{.5}{% /AngleA \psk@angleA def /r \pst@number\pst@dima def \tx@NCCircle \psarc@v end}} \def\tx@NCBox{NCBox } \def\ncbox{\pst@object{ncbox}} \def\ncbox@i{\check@arrow{\ncbox@ii}} \def\ncbox@ii#1#2{% \def\pst@linetype{2}% \nc@object{Closed}{#1}{#2}{.5}{% tx@Dict begin \psline@iii pop end \psk@boxheight \psk@boxdepth \tx@NCBox}} \def\pcbox{\pst@object{pcbox}} \def\pcbox@i{\pc@object\ncbox@ii} \def\tx@NCArcBox{NCArcBox } \define@key[psset]{pst-node}{boxheight}[0.4cm]{\pst@getlength{#1}\psk@boxheight} \define@key[psset]{pst-node}{boxdepth}[0.4cm]{\pst@getlength{#1}\psk@boxdepth} \define@key[psset]{pst-node}{boxsize}[0.4cm]{% \pst@getlength{#1}\psk@boxheight% \let\psk@boxdepth\psk@boxheight} \psset[pst-node]{boxsize=0.4cm} % \def\ncarcbox{\pst@object{ncarcbox}} \def\ncarcbox@i{\check@arrow{\ncarcbox@ii}} \def\ncarcbox@ii#1#2{% \def\pst@linetype{1}% \nc@object{Closed}{#1}{#2}{.5}{% \psk@arcangleA \psk@boxheight \psk@boxdepth \pst@number\pslinearc \tx@NCArcBox}} \def\pcarcbox{\pst@object{pcarcbox}} \def\pcarcbox@i{\pc@object\ncarcbox@ii} \def\tx@Tfan{Tfan } % Changed according pst-beta.bug December 3, 1993 % nrot=: does not work when : is active. \begingroup \catcode`\:=13 \gdef\pst@activerot{\def:{\string:}} \endgroup \define@key[psset]{pst-node}{nrot}[0]{% \begingroup \pst@activerot \pst@expandafter{\@ifnextchar:{\psset@@nrot}{\psset@@rot}}{#1}\@nil \global\let\pst@tempg\psk@rot \endgroup \let\psk@nrot\pst@tempg} % \def\psset@@nrot:#1\@nil{% \psset@@rot#1\@nil \edef\psk@rot{NAngle \ifx\psk@rot\@empty\else\psk@rot add \fi}} \psset[pst-node]{nrot=0} % \def\tx@LPutCoor{LPutCoor } \def\tx@LPut{LPut } \define@key[psset]{pst-node}{npos}[{}]{% \def\pst@tempa{#1}% \ifx\pst@tempa\@empty\def\psk@npos{\npos@default}\else\pst@checknum{#1}\psk@npos\fi} \psset[pst-node]{npos=} % \def\ncput{\pst@object{ncput}} \def\ncput@i{\pst@killglue\pst@makebox{\ncput@ii}} \def\ncput@ii{% \begingroup% \use@par% \if@star\pst@starbox\fi% \pst@makesmall\pst@hbox% \pst@rotate\psk@nrot\pst@hbox% \ncput@iii% \endgroup% \pst@shortput} \def\ncput@iii{% \leavevmode% \hbox{% \pst@Verb{ \pst@nodedict /t \psk@npos def \tx@LPut end \tx@PutBegin}% \box\pst@hbox% \pst@Verb{\tx@PutEnd}}} % \def\naput{\pst@object{naput}} \def\naput@i{\pst@killglue\pst@makebox{\naput@ii{NAngle 90 add}}} \def\naput@ii#1{% \begingroup % \addto@par{labelsep=15pt}% \use@par \if@star\pst@starbox\fi \def\psk@refangle{#1 }% \let\psk@rot\psk@nrot \pst@Verb{ gsave STV CP T /ps@refangle {#1 } def /ps@rot { \psk@rot } def grestore }%ADDED (MJS) \uput@vii {exch pop add a \tx@PtoC h1 add exch w1 add exch }% {tx@Dict /NCLW known { NCLW add } if }% \ncput@iii \endgroup \pst@shortput} % \def\nbput{\pst@object{nbput}} \def\nbput@i{\pst@killglue\pst@makebox{\naput@ii{NAngle 90 sub}}} \define@key[psset]{pst-node}{tpos}[0.5]{% \pst@checknum{#1}\psk@tpos \ifdim\psk@tpos \p@<\z@ \def\psk@tpos{.5}% % DG/SR modification begin - Sep. 23, 1998 - Patch 7 %\@pstrickserr{Bad `tpos' value: `#1'. Must be 0\p@ \def\psk@tpos{.5}% % DG/SR modification begin - Sep. 23, 1998 - Patch 7 %\@pstrickserr{Bad `tpos' value: `#1'. Must be 0} \def\MakeShortTab#1#2{% \def\pst@shortput@tab{% \def\pst@tempg{\next}% \ifx#1\next \def\pst@tempg{% \@nameuse{% t\ifodd\psk@treemode\ifpstreeflip b\else a\fi \else\ifpstreeflip r\else l\fi\fi put}}% \else \ifx#2\next \def\pst@tempg{% \@nameuse{% t\ifodd\psk@treemode\ifpstreeflip a\else b\fi \else\ifpstreeflip l\else r\fi\fi put}}% \else \ifx\@sptoken\next \let\pst@tempg\pst@shortput \fi \fi \fi \pst@tempg}} \MakeShortTab{^}{_} \define@key[psset]{pst-node}{shortput}[none]{% \def\pst@tempg{#1}% \ifx\pst@tempg\@none \let\pst@shortput\ignorespaces \else \@ifundefined{pst@shortput@#1}% {\@pstrickserr{Bad short put: `#1'}\@ehpa}% {\edef\pst@shortput{\noexpand\afterassignment\expandafter\noexpand \csname pst@shortput@#1\endcsname\noexpand\let\noexpand\next}}% \fi} \psset[pst-node]{shortput=none} % \def\lput{\def\pst@par{}\pst@ifstar{\@ifnextchar[{\lput@i}{\lput@ii}}} \def\lput@i[#1]{\addto@par{ref=#1}\lput@ii} \def\lput@ii{\@ifnextchar({\lput@iv}{\lput@iii}} \def\lput@iii#1{\addto@par{nrot=#1}\@ifnextchar({\lput@iv}{\ncput@i}} \def\lput@iv(#1){\addto@par{npos=#1}\ncput@i} \def\mput{\def\pst@par{}\pst@ifstar{\@ifnextchar[{\mput@i}{\ncput@i}}} \def\mput@i[#1]{\addto@par{ref=#1}\ncput@i} \def\Lput{\def\pst@par{}\pst@ifstar{\@ifnextchar[{\Lput@ii}{\Lput@i}}} \def\Lput@i#1{\addto@par{labelsep=#1}\Lput@ii} \def\Lput@ii[#1]{\addto@par{ref={#1}}\@ifnextchar({\Lput@iv}{\Lput@iii}} \def\Lput@iii#1{\addto@par{nrot={#1}}\@ifnextchar({\Lput@iv}{\Lput@v}} \def\Lput@iv(#1){\addto@par{npos=#1}\Lput@v} \def\Lput@v{\pst@killglue\pst@makebox{\Lput@vi}} \def\Lput@vi{% \begingroup \use@par \if@star\pst@starbox\fi \Rput@vi \pst@makesmall\pst@hbox \ifx\psk@rot\@empty\else\pst@rotate{ps@rot }\pst@hbox\fi% (MJS) %\pst@rotate\psk@nrot\pst@hbox \ncput@iii \endgroup \pst@shortput} \def\Mput{\def\pst@par{}\pst@ifstar{\@ifnextchar[{\Mput@ii}{\Mput@i}}} \def\Mput@i#1{\addto@par{labelsep=#1}\Mput@ii} \def\Mput@ii[#1]{\addto@par{ref={#1}}\Lput@v} \def\aput@#1{\def\pst@par{}\pst@ifstar{\@ifnextchar[{\aput@i#1}{\aput@ii#1}}} \def\aput@i#1[#2]{\addto@par{labelsep=#2}\aput@ii#1} \def\aput@ii#1{\@ifnextchar({\aput@iv#1}{\aput@iii#1}} \def\aput@iii#1#2{\addto@par{nrot=#2}\@ifnextchar({\aput@iv#1}{#1}} \def\aput@iv#1(#2){\addto@par{npos=#2}#1} \def\aput{\aput@\naput@i} \def\bput{\aput@\nbput@i} \def\Aput{\def\pst@par{}\pst@ifstar{\@ifnextchar[{\Aput@i}{\naput@i}}} \def\Aput@i[#1]{\addto@par{labelsep=#1}\naput@i} \def\Bput{\def\pst@par{}\pst@ifstar{\@ifnextchar[{\Bput@i}{\nbput@i}}} \def\Bput@i[#1]{\addto@par{labelsep=#1}\nbput@i} % \def\node@coor#1;#2\@nil{% for normal nodes (name) \pst@getnode{#1}\pst@tempg \edef\pst@coor{% \pst@nodedict tx@NodeDict \pst@tempg known \pslbrace \pst@tempg load \tx@GetCenter \psrbrace \pslbrace 0 0 \psrbrace ifelse end }} % \def\Node@coor[#1]#2;#3\@nil{% for special nodes ([...]{node}node) \begingroup \psset{angle=0,#1}% angle=0, to prevent problems if angle is set globally \@ifnextchar\bgroup{\Node@@@coor}% we have an additional node [...]{node} {\Node@@coor}#2\@nil% we have [...]node \endgroup \let\pst@coor\pst@tempg} % \def\Node@@coor#1\@nil{% \pst@getnode{#1}\pst@tempg \xdef\pst@tempg{% \pst@nodedict tx@NodeDict \pst@tempg known { \psk@nodesepA \psk@angleA \pst@tempg load \psk@nodeseptypeA \tx@GetEdge \psk@offsetA \psk@angleA \tx@AddOffset \pst@tempg load \tx@GetCenter 3 -1 roll add 3 1 roll add exch } { CP } ifelse end }} % \def\Node@@@coor#1{% [...]{#1}node \pst@@getcoor{#1}% \def\psk@angleA{% \pst@tempg load \tx@GetCenter \pst@coor 3 -1 roll sub 3 1 roll sub neg \tx@Atan \psk@angleB add }% \Node@@coor} % \def\nput{\pst@object{nput}} \def\nput@i#1#2{\pst@killglue\pst@makebox{\nput@ii{#1}{#2}}} \def\nput@ii#1#2{% \begingroup \use@par \if@star\pst@starbox\fi% \psset[pstricks]{refangle=#1}% \let\psk@angleA\psk@refangle \edef\psk@nodesepA{\pst@number\pslabelsep}% \def\psk@nodeseptypeA{0 }% \pslabelsep\z@ \uput@vi \Node@@coor#2\@nil \let\pst@coor\pst@tempg \leavevmode \psput@special\pst@hbox \endgroup \ignorespaces} % \newcount\psrow \newcount\pscol \newcount\psmatrixcnt \newskip\psrowsep \newskip\pscolsep % \define@key[psset]{pst-node}{colsep}[1.5cm]{\pssetlength\pscolsep{#1}} \define@key[psset]{pst-node}{rowsep}[1.5cm]{\pssetlength\psrowsep{#1}} \psset[pst-node]{colsep=1.5cm} \psset[pst-node]{rowsep=1.5cm} \newif\ifpsmatrix % DG/SR modification begin - Nov. 27, 1998 - Patch 8 %\let\mscount\@multicnt \ifx\mscount\@undefined\let\mscount\@multicnt\fi % DG/SR modification end \def\psmatrix{\begingroup{\ifnum0=`}\fi % Don't want to expand any &. \@ifnextchar[{\psmatrix@i}{\ifnum0=`{\fi}{}\psmatrix@ii}} \def\psmatrix@i[#1]{% \ifnum0=`{\fi}{}% \psset{#1}% \psmatrix@ii} \def\psmatrix@ii{% \KillGlue \edef\psm@beginmath{% \ifmmode$\m@th\ifinner\textstyle\else\displaystyle\fi\fi}% \edef\psm@endmath{\ifmmode$\fi}% \let\\\psm@cr \advance\psmatrixcnt by \@ne \def\psm@thenode{M-\the\psmatrixcnt-\the\psrow-\the\pscol}% \tabskip\z@ \psrow=\@ne \pscol\z@ \psset{shortput=tablr}% \leavevmode \vbox\bgroup\halign\bgroup&% \begingroup \global\advance\pscol by \@ne \csname psrowhook\romannumeral\psrow\endcsname \csname pscolhook\romannumeral\pscol\endcsname \psm@beginnode##\psm@endnode\endgroup \cr} % \def\endpsmatrix{% \crcr\egroup\unskip\egroup \endgroup} % % hv 2007-10-16 fix bug with \\[name=...] %\def\psm@cr{{\ifnum0=`}\fi\@ifnextchar[{\psm@@cr}{\psm@@@cr{}}} \def\psm@cr{{\ifnum0=`}\fi\ps@ifnextchar[{\psm@@cr}{\psm@@@cr{}}} % \def\psm@@cr[#1]{\psm@@@cr{\vskip#1\relax}} \def\psm@@@cr#1{% \ifnum0=`{\fi}{}\cr \noalign{% \global\advance\psrow 1 \global\pscol\z@ \vskip\psrowsep #1}} \def\psm@beginnode{% \@ifnextchar\psm@endnode {\let\psm@endnode@i\relax\setbox\pst@hbox=\hbox{}}% {\pst@object{psm@beginnode}}} \def\psm@beginnode@i{% \setbox\pst@hbox=\hbox\bgroup \psm@beginmath \begingroup \ignorespaces} \def\psm@endnode@i{% \unskip \endgroup \psm@endmath \egroup \use@par \@psttrue} \def\psm@endnode{% \@pstfalse \psm@endnode@i \ifnum\pscol>1\relax \pshskip\pscolsep \fi \psk@mnodesize \hfil \Pst@nodealigntrue \if@pst\csname mnode@\psk@mnode\endcsname \else\csname mnode@\psk@emnode\endcsname\fi \psk@mcol \psk@@mnodesize} % DG/SR modification begin - Sep. 3, 1999 - Patch 10 - From Michael Sharpe %\def\psspan#1{\mscount#1\relax\loop\ifnum\mscount>\@ne \sp@n\repeat} \def\psspan#1{\global\mscount#1\relax\pstloop\ifnum\mscount>\@ne\sp@n\repeat} \def\pstloop#1\repeat{\gdef\pstiterate{#1\relax\expandafter\pstiterate\fi}% \pstiterate \let\pstiterate\relax} % DG/SR modification end \define@key[psset]{pst-node}{name}[\relax]{\pst@getnode{#1}\psk@name} \let\psk@name\relax \define@key[psset]{pst-node}{mcol}[c]{% \ifx r#1\relax\let\psk@mcol\relax\else \ifx l#1\relax\let\psk@mcol\hfill\else \let\psk@mcol\hfil\fi\fi} \psset[pst-node]{mcol=c} % \define@key[psset]{pst-node}{mnodesize}[-1pt]{% \pssetlength\pst@dimg{#1}% \ifdim\pst@dimg<\z@ \let\psk@mnodesize\relax \let\psk@@mnodesize\relax \else \edef\psk@mnodesize{\noexpand\hbox to\number\pst@dimg sp\noexpand\bgroup}% \let\psk@@mnodesize\egroup \fi} \psset[pst-node]{mnodesize=-1pt} % \def\mnode@R{\rnode@iii\Rnode@ii{\psm@thenode}} \def\mnode@r{\rnode@iii\rnode@iv{\psm@thenode}} \def\mnode@oval{\ovalnode@ii{\psm@thenode}} \def\mnode@tri{\trinode@ii{\psm@thenode}} \def\mnode@dia{\dianode@ii{\psm@thenode}} \def\mnode@C{{\Pst@nodealigntrue\cnode@ii(\z@,\z@){\psk@radius}{\psm@thenode}}} \def\mnode@f{{\Pst@nodealigntrue\fnode@ii(\z@,\z@){\psm@thenode}}} \def\mnode@circle{\circlenode@ii{\psm@thenode}} % hv modification begin - Aug. 16, 2007 \def\mnode@Circle{\Circlenode@ii{\psm@thenode}} % hv modification end - Aug. 16, 2007 \def\mnode@p{\pnode(\z@,\z@){\psm@thenode}} % DG/SR modification begin - Jul. 22, 1997 - Patch 1 \def\mnode@dot{\dotnode@ii(\z@,\z@){\psm@thenode}} % DG/SR modification end \def\mnode@none{\box\pst@hbox} % \define@key[psset]{pst-node}{mnode}[R]{% \@ifundefined{mnode@#1}% {\@pstrickserr{\string\psmatrix\space node `#1' not defined.}\@ehpa}% {\edef\psk@mnode{#1}}} \define@key[psset]{pst-node}{emnode}[none]{% \@ifundefined{mnode@#1}% {\@pstrickserr{\string\psmatrix\space node `#1' not defined.}\@ehpa}% {\edef\psk@emnode{#1}}} \psset[pst-node]{mnode=R,emnode=none} % %%%% FROM pst-coil.tex \def\nccoil{\pst@object{nccoil}} \def\nccoil@i{\check@arrow{\nccoil@ii}} \def\nccoil@ii#1#2{\nc@object{Open}{#1}{#2}{.5}{ \tx@NCCoor tx@Dict begin 4 2 roll \psk@coilwidth \pscoilheight \psk@coilarmA \psk@coilarmB \psk@coilaspect \psk@coilinc \pst@coildict \tx@Coil end end}% } \def\nczigzag{\pst@object{nczigzag}} \def\nczigzag@i{\check@arrow{\nczigzag@ii}} \def\nczigzag@ii#1#2{\nc@object{Open}{#1}{#2}{.5}{ \tx@NCCoor tx@Dict begin 4 2 roll \pscoilheight \psk@coilwidth \psk@coilarmA \psk@coilarmB \pst@coildict \tx@ZigZag end \psline@iii \tx@Line end}% } % \psGetNodeCenter defines the PS variable #1.x and #1.y, which can then % be used by the user. #1 must be a valid node name \def\psGetNodeCenter#1{ tx@NodeDict begin /N@#1 load GetCenter end % x y on stack in system coor \pst@number\psyunit div /#1.y exch def % /#1.y in user coor \pst@number\psxunit div /#1.x exch def } % /#1.x in user coor %\def\psGetNodeEdgeA#1#2{ tx@NodeDict begin /N@#2 load #2 GetEdgeA end % x y on stack in system coor % \pst@number\psyunit div /#1.y exch def % /#1.y in user coor % \pst@number\psxunit div /#1.x exch def } % /#1.x in user coor \def\psGetEdgeA#1#2{ tx@NodeDict begin \psk@offsetA \psk@offsetB neg \psk@nodesepA \psk@nodesepB 0 0 /N@#1 /N@#2 InitNC { NCCoor } if pop pop \tx@UserCoor end} \def\psGetEdgeB#1#2{ tx@NodeDict begin \psk@offsetA \psk@offsetB neg \psk@nodesepA \psk@nodesepB 0 0 /N@#1 /N@#2 InitNC { NCCoor } if 4 2 roll pop pop \tx@UserCoor end} % %%%%%%%%%%%%%% the pst-node-tools part %%%%%%%%%%%%%%%%%%%%%%%% % \def\ncbarr{\pst@object{ncbarr}} \def\ncbarr@i#1#2{% \begingroup \use@par% \psLNode(#1)(#2){0.5}{barr@tempNode}% \pst@dimc=\psk@angleA pt \pst@dimd=180pt % be sure, that angleA is 0 or 180. if not, we set it to 0 \ifdim\pst@dimc=\z@\else\ifdim\pst@dimc=\pst@dimd\else\psset{angleA=0}\fi\fi \ncbar[arrows=-]{#1}{barr@tempNode} \ifdim\psk@angleA pt=\z@\relax \ncbar[angleA=180,angleB=180]{barr@tempNode}{#2} \else\ncbar[angleA=0,angleB=0]{barr@tempNode}{#2}\fi% \endgroup% } % #1-------#4----------------#2 % where #1#4= #3 * #1#2 % \def\psLNode(#1)(#2)#3#4{% \pst@getcoor{#1}\pst@tempA% \pst@getcoor{#2}\pst@tempB% \pnode(! \pst@tempA /YA exch \pst@number\psyunit div def /XA exch \pst@number\psxunit div def \pst@tempB /YB exch \pst@number\psyunit div def /XB exch \pst@number\psxunit div def /dx XB XA sub def /dy YB YA sub def XA dx #3\space mul add YA dy #3\space mul add){#4}} % % build the linear combination #2*#1+#4*#3=#5 \def\psLCNode(#1)#2(#3)#4#5{% \pst@getcoor{#1}\pst@tempA% \pst@getcoor{#3}\pst@tempB% \pnode(! \pst@tempA /YA exch \pst@number\psyunit div def /XA exch \pst@number\psxunit div def \pst@tempB /YB exch \pst@number\psyunit div def /XB exch \pst@number\psxunit div def XA #2\space mul XB #4\space mul add YA #2\space mul YB #4\space mul add){#5}} % \def\psLDNode(#1)(#2)#3#4{% % #1: node A #2: node B #3: dimen measured from A #4: node name \pst@getcoor{#1}\pst@tempA% \pst@getcoor{#2}\pst@tempB% \pssetlength\pst@dimb{#3}% \pnode(!% \pst@tempA /YA exch \pst@number\psyunit div def /XA exch \pst@number\psxunit div def \pst@tempB /YB exch \pst@number\psyunit div def /XB exch \pst@number\psxunit div def /dx XB XA sub def /dy YB YA sub def /angle dy dx Atan def /linelength \pst@number\pst@dimb \pst@number\psunit div def XA linelength angle cos mul add YA linelength angle sin mul add ){#4}% } \def\psRelNode{\pst@object{psRelNode}} \def\psRelNode@i(#1)(#2)#3#4{{% A - B - factor - node name \use@par % \pst@killglue \pst@getcoor{#1}\pst@tempA% \pst@getcoor{#2}\pst@tempB% \pnode(! \pst@tempA /YA exch \pst@number\psyunit div def /XA exch \pst@number\psxunit div def \pst@tempB /YB exch \pst@number\psyunit div def /XB exch \pst@number\psxunit div def /AlphaStrich \psk@angleA\space def /unit \pst@number\psyunit \pst@number\psxunit div def % yunit/xunit % /dx XB XA sub def /dy YB YA sub \ifPst@trueAngle\space unit mul \fi\space def /laenge dy dup mul dx dup mul add sqrt #3 mul def /Alpha dy dx atan def /beta Alpha AlphaStrich add def laenge beta cos mul XA add laenge beta sin mul \ifPst@trueAngle\space unit div \fi\space YA add ){#4}% }\ignorespaces} % \define@cmdkeys[psset]{pstricks-add}[PSTPSPNk@]{% Christophe Jorssen 2007 blName,bcName,brName, clName,ccName,crName, tlName,tcName,trName}[]{}% \psset[pstricks-add]{% blName=PSPbl,bcName=PSPbc,brName=PSPbr, clName=PSPcl,ccName=PSPcc,crName=PSPcr, tlName=PSPtl,tcName=PSPtc,trName=PSPtr} \def\psDefPSPNodes{\def\pst@par{}\pst@object{psDefPSPNodes}} \def\psDefPSPNodes@i{% \pst@killglue \begingroup \use@par \expandafter\psDefPSPNodes@ii\pic@coor} % \def\psDefPSPNodes@ii(#1)(#2)(#3){% % \pnode(#1){PSPN@temp}\pnode([nodesep=.75,angle=45]PSPN@temp){\PSTPSPNk@blName} % \pnode(#3){PSPN@temp}\pnode([nodesep=.75,angle=-135]PSPN@temp){\PSTPSPNk@trName} \pnode(#1){PSPN@temp}\pnode([angle=45]PSPN@temp){\PSTPSPNk@blName} \pnode(#3){PSPN@temp}\pnode([angle=-135]PSPN@temp){\PSTPSPNk@trName} \pnode(\PSTPSPNk@blName|\PSTPSPNk@trName){\PSTPSPNk@tlName} \pnode(\PSTPSPNk@trName|\PSTPSPNk@blName){\PSTPSPNk@brName} \ncline[linestyle=none]{\PSTPSPNk@blName}{\PSTPSPNk@tlName} \ncput[npos=.5]{\pnode{\PSTPSPNk@clName}} \ncline[linestyle=none]{\PSTPSPNk@blName}{\PSTPSPNk@brName} \ncput[npos=.5]{\pnode{\PSTPSPNk@bcName}} \pnode(\PSTPSPNk@brName|\PSTPSPNk@clName){\PSTPSPNk@crName} \pnode(\PSTPSPNk@bcName|\PSTPSPNk@trName){\PSTPSPNk@tcName} \pnode(\PSTPSPNk@bcName|\PSTPSPNk@clName){\PSTPSPNk@ccName} \endgroup \ignorespaces} % % \def\psDefBoxNodes#1#2{\rnode[tl]{#1:tl}{\rnode[Bl]{#1:Bl}{\rnode[tr]{#1:tr}{% \rnode[bl]{#1:bl}{\rnode[Br]{#1:Br}{\rnode[br]{#1:br}{#2}}}}}}% \pnode(!\psGetNodeCenter{#1:bl} \psGetNodeCenter{#1:tl} #1:bl.x #1:tl.x add 2 div #1:bl.y #1:tl.y add 2 div ){#1:Cl}% \pnode(!\psGetNodeCenter{#1:tr} \psGetNodeCenter{#1:br} #1:tr.x #1:br.x add 2 div #1:tr.y #1:br.y add 2 div ){#1:Cr}% \pnode(!\psGetNodeCenter{#1:Cl} \psGetNodeCenter{#1:Cr} #1:Cl.x #1:Cr.x add 2 div #1:Cl.y #1:Cr.y add 2 div ){#1:C}% \pnode(!\psGetNodeCenter{#1:Br} \psGetNodeCenter{#1:Bl} #1:Br.x #1:Bl.x add 2 div #1:Br.y #1:Bl.y add 2 div ){#1:BC}% \pnode(!\psGetNodeCenter{#1:tr} \psGetNodeCenter{#1:tl} #1:tr.x #1:tl.x add 2 div #1:tr.y #1:tl.y add 2 div ){#1:tC}% \pnode(!\psGetNodeCenter{#1:br} \psGetNodeCenter{#1:bl} #1:br.x #1:bl.x add 2 div #1:br.y #1:bl.y add 2 div ){#1:bC}}% % % %% Author: Michael Sharpe (msharpe at ucsd.edu) % Macros defined in this file: % \defaultvalue{}{} assigns to is command is not defined, or is empty. % \testAlg---used internally to test whether an parametric expression in t is algebraic % \trim{} trims white space from ends of expansion of % \hasparen sets \parentrue if its argument contains a ( % \hasequal sets \equaltrue if its argument starts with = % \equalwhat returns what follows = % \parsenodexn parses a node expression recursively. Better to use \nodexn. % \normalvec(){} returns vector normal to (same length) in % \curvepnode{}{}{} Eg, \curvepnode{1}{sin(t) | cos(t)}{P} sets a pnode named P at (cos(1), sin(1)) % \psparnode{}{ in t>}{} is called by \curvename if expression is PostScript, not algebraic % \algparnode{}{ in t>}{} is called by \curvename if expression is algebraic, not PostScript % \nodexn is like \parsenodexn, slightly different syntax. \nodexn{}{} evaluates as a node expression and calls the result . % \psxline(P){}{} draws line from P+ to P+. The novelty is that the last two arguments can be node expressions. % \curvepnodes{}{}{}{} Uses current setting of plotpoints (default 50) to define a sequence of pnodes along the curve. Eg, \curvepnodes[plotpoints=100]{0}{1}{t+t^2 | Ex(-t)}{P} sets pnodes P0..P99 at equally spaced t values along the curve, and defines the macro \Pnodecount to 99, the highest index. The expression in t may be either algebraic or PostScript, and is handled automatically detected. % \fnpnode{}{}{} sets a single pnode on graph. Eg, \fnpnode{.5}{x 2 mul x 1 add mul}{P} declares the pnode P at the point x=0.5 on the graph. (Same as \pnode(!/x 0.5 def x x 2 mul x 1 add mul}){P}.) If your expression in t is algebraic, you must use the keyword algebraic, as in \fnpnode[algebraic]{0.5}{2*x*(x+1)}{P}. % \fnpnodes{}{}{} Is exactly the same as \curvenodes, but for the graph of a function. The keyword algebraic must be specified if your expression is algebraic % \AtoB(A)(B){C} defines node by name C essentially as B-A % \AplusB(A)(B){C} defines node by name C essentially as A+B % \midAB(A)(B){C} defines node by name C essentially as (A+B)/2 % \psnline[linewidth=1pt,arrows=->](3,5){P}, for example, expects that there are pnodes named P3..P7 (total of 5), and effectively gives the same result as \psline[linewidth=1pt,arrows=->](P3)(P4)(P5)(P6)(P7). Note that arrow must be specified with a keyword, not as an argument. % \shownode(P) displays in the console window the coordinates of node P. This will not appear until the final stage of processing the PostScript file. It is a debugging tool. % \getnodelist{}{} is useful in writing pstricks macros, where there is a list of parenthesized coordinates to be read and turned into a node sequence, following which is followed. % \pnodes{P}(1,2)(2;3)... is effectively \getnodelist{P}{}(1,2)(2;3)..., just a quick way to turn a list of coordinates into pnodes P0 P1 ... % \psLCNodeVar is similar to \psLCNode, and provides a means of forming a linear combination of two nodes, thought of as vectors. Where \psLCNode(A){a}(B){b}{C} effectively makes C=aA+bB, \psLCNodeVar(A)(B)(a,b){C} does the same, but the third argument (a,b) may be specified in PostScript code or any form recognized by \SpecialCoor. Unlike \psLCNode, the name C may be one of A, B. % \psRelNodeVar is similar to \psRelNode, and provides a means of rotating and changing the length of a line segment AB about A. The effect of \psRelNodeVar(A)(B)(2;30){C} is the same as \psRelNode[angle=30](A)(B){2}{C}, but the third argument (2;30) may be specified in PostScript code, which is not possible with \psRelNode. % \psRelLineVar stands to \psRelLine as \psRelNodeVar stands to \psRelNode. % \rhombus{}(A)(B){C}{D} computes the two remaining vertices C, D given two opposing vertices A, B of a rhombus with given edge length. It does not draw the rhombus--- that can be handled easily by \pspolygon(A)(C)(B)(D). % \psrline(P)(Q)... is like \psline, drawing a line starting at (P), with successive increments (Q)... It has the same options as \psline. Eg, \psrline[linecolor=red]{->}(1,1)(1,0) % \polyIntersection is the most complicated macro in the collection. It has two forms % \polyIntersection{}{}(A)(B)(1,2)(3;30)(6,5)... %works with the line starting at A heading toward B, and computes the first point that lies on the polyline (1,2)(3;30)(6,5)..., calling it . It also computes the first point in the opposite direction (from A) lying on that polyline, naming it . If one or other of these intersections is empty, the nodes are set to remote points on the line. The two nodes are then joined by a line. The effect depends on the location of A and B relative to the polyline, with two cases worth noting. % (a) if the polyline is closed and if A, B are interior to one of its components, you get a line segment from one edge to the other, containing AB. % (b) If the polylne is simple and closed, and one of A, B is inside and the other outside, the resulting line segment will contain A but not B. % \polyIntersection{}{}(A)(B){P}{n} works exactly the same as \polyIntersection{}{}(A)(B)(P0)(P1)...(Pn), assuming P0...Pn are previously defined as pnodes. % \psStepa is like \psStep (pstricks-add) but for a node sequence rather than equally spaced abscissas. \psStepa[options]{}{} draws a step function with jumps at the successive nodes in the node sequence. Eg, \psStepa{P}{10} has jumps at P0..P10 % \newcount\pst@args%used in several macros \newcount\num@pts \newcount\pst@argcnt% for use in parsing node expressions \def\PST@root{} \let\pst@next\relax %my scratch variables \def\my@tempA{} \def\my@tempB{} \def\my@tempC{} \def\my@tempD{} \def\my@next{} \newif\if@paren% \newif\if@equal% \newif\if@colon% \newif\ifshow \def\plussign{+}\def\minussign{-} % % \def\defaultvalue#1#2{%#1 is a command, #2 is a value, possibly a command \ifdefined#1\ifx#1\@empty\xdef#1{#2}\fi\else\xdef#1{#2}\fi}% % \def\testAlg#1|#2\@nil{% \ifx\relax#2\relax% \let\my@next\psparnode\xdef\my@tempD{}% \else% \let\my@next\algparnode\xdef\my@tempD{A}% algebraic \fi}% % %Jonathan Fine's trim \def\trim #1{\expandafter\trim@\expandafter{#1 }#1}% \def\trim@ #1{\trim@@ @#1 @ #1 @ @@}% \def\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @}% \def\unbrace#1{#1}% \unbrace{\def\trim@@@ #1 } #2@#3{\expandafter\def% \expandafter #3\expandafter {#1}}% % \def\hasparen#1(#2\@nil{%check if expression contains a (--call with \hasparen#1(\@nil \ifx\relax#2\relax \@parenfalse \else \@parentrue\fi}% % \def\hasequal#1=#2\@nil{%check if expression contains a =--call with \hasequal#1=\@nil \ifx\relax#2\relax \@equalfalse \else \@equaltrue\fi \hascolon#2:\@nil}% % \def\hascolon#1:#2\@nil{%check if expression contains a :--call with \hascolon#1:\@nil \ifx\relax#2\relax \@colonfalse \else \@colontrue\fi}% % \def\equalwhat#1=#2:#3\@nil{{#2}{#3}}% % \def\parsenodexn#1(#2)#3\@nil{% \def\coeffA{#1}\edef\nodeA{#2}% \trim\coeffA% \ifx\nodeA\@empty\else% \pnode(#2){@@TMP}% \ifx\coeffA\@empty\def\coeffA{1}\else% \ifx\coeffA\plussign\def\coeffA{1}\else\ifx\coeffA\minussign\def\coeffA{-1}\fi\fi\fi% \edef\cmd{\noexpand\psLCNode(@TMP\the\pst@argcnt){1}(@@TMP){\coeffA}{@TMP}}% \cmd% \advance\pst@argcnt by \@ne% \pnode(@TMP){@TMP\the\pst@argcnt}% \parsenodexn#3\@nil% \fi}% % \def\normalvec(#1)#2{% %pnode | new pnode normal to old, same length \psRelNodeVar(0,0)(#1)(0,1){#2}}% % \def\curvepnode#1#2#3{% % #1=t value, #2=x(t) y(t) in either form,#3=node name, %must first detect which form of x(t) y(t), looking for | \edef\my@tempA{#2}% x(t) y(t) expanded \expandafter\testAlg\my@tempA|\@nil\my@next {#1}{#2}{#3}} % \def\psparnode#1#2#3{% % #1=t value, #2=x(t) y(t) in PS form,#3=node name, \pnode(!/t #1 def #2){#3}% \pnode(!/t #1 .001 sub def #2 /t #1 .001 add def #2 3 -1 roll sub 3 1 roll sub neg 2 copy Pyth dup 3 1 roll div 3 1 roll div ){#3tang}}%unit tangent vector at t % \def\algparnode#1#2#3{% % #1=t value, #2=x(t) | y(t) in alg form,#3=node name, %\pstVerb{tx@Dict begin /t #1 def /Func (#2) AlgParser cvx def end} %\pnode(!Func){#3}}% \pstVerb{tx@Dict begin /Func (#2) AlgParser cvx def end } \pnode(!/t #1 def Func){#3} \pnode(!/t #1 .001 sub def Func /t #1 .001 add def Func 3 -1 roll sub 3 1 roll sub neg 2 copy Pyth dup 3 1 roll div 3 1 roll div ){#3tang}%unit tangent vector at t }% % \def\nodex#1{% %#1=node expression --set nodename to @TMP \expandafter\hasparen#1(\@nil% \if@paren%it's an expression \pnode(0,0){@TMP0}% \pst@argcnt=0% \expandafter\parsenodexn#1()\@nil% \else% \def\my@tempC{#1}% \ifx\my@tempC\@empty\pnode(0,0){@TMP}\else\pnode(#1){@TMP}\fi% \fi}%\if@paren % \def\nodexn#1#2{% %#1=node expression | #2=node name \expandafter\hasparen#1(\@nil%%% hv 20130917 use \expandafter \if@paren%it's an expression \pnode(0,0){@TMP0}% \pst@argcnt=0% \parsenodexn#1()\@nil% \pnode(@TMP){#2}% \else% \def\my@tempC{#1}% \ifx\my@tempC\@empty\pnode(0,0){#2}\else\pnode(#1){#2}\fi% \fi}%\if@paren % \def\psxline{\pst@object{psxline}}% \def\psxline@i{\@ifnextchar({\psxline@iii}{\psxline@ii}}% \def\psxline@ii#1{% \addto@par{arrows=#1}% \psxline@iii}% \def\psxline@iii(#1)#2#3{{%#1=basepoint, #2,#3 node expressions \pst@killglue% \use@par% \nodexn{#2}{@TMP@a}% \AplusB(#1)(@TMP@a){@TMP@A}% \nodexn{#3}{@TMP@a}% \AplusB(#1)(@TMP@a){@TMP@B}% \psline(@TMP@A)(@TMP@B)% }% \ignorespaces}% % \def\curvepnodes{\pst@object{curvepnodes}} \def\curvepnodes@i#1#2#3#4{{%optional [plotpoints=xx] % #1=tmin,#2=tmax,#3=function (of t),#4=node root name, \pst@killglue \use@par \edef\my@tempA{#3}% x(t) y(t) expanded \expandafter\testAlg\my@tempA|\@nil % \pstVerb{% tx@Dict begin % so we can use definitions from tx@Dict /t0 #1 def /t1 #2 def t1 t0 sub end \psk@plotpoints div /dt exch def }% \pst@cntc=\psk@plotpoints\relax%\psk@plotpoints=plotpoints-1 \advance\pst@cntc by \@ne\relax %=plotpoints \ifx\my@tempD\@empty\pstVerb{tx@Dict begin /Func (#3) cvx def end }%add tx@Dict \else\pstVerb{tx@Dict begin /Func (#3 ) AlgParser cvx def end }% \fi% \multido{\i=0+1}{\pst@cntc}{% \pnode(! /t #1 dt \i\space mul add def Func ){#4\i}}% remove t before Func \expandafter\xdef \csname #4nodecount\endcsname {\psk@plotpoints}% \ifnum\Pst@Debug>0 \typeout{Created nodes #40 .. #4\psk@plotpoints}\fi% }\ignorespaces}% % \def\fnpnode{\pst@object{fnpnode}} \def\fnpnode@i#1#2#3{{%optional [algebraic] %#1=x value | #2=fn of x | #3=node name \pst@killglue \use@par \ifPst@algebraic\pnode(*#1 {#2}){#3}\else\pnode(! /x #1 def x #2){#3}\fi }\ignorespaces}% % \def\fnpnodes{\pst@object{fnpnodes}} \def\fnpnodes@i#1#2#3#4{{%optional [algebraic] %#1=xmin | #2=xmax | #3= fn of x | #4=node name \pst@killglue \use@par \pst@dima=#1pt \pst@dimb=#2pt \advance\pst@dimb -\pst@dima% \pst@cnta=\psk@plotpoints \relax %=plotpoints-1 \def\PST@root{#4} \divide\pst@dimb by \pst@cnta%plotpoint-1 intervals \pst@cntc=\pst@cnta % \advance\pst@cntc by 1 \relax %=plotpoints \ifPst@algebraic \multido{\i=0+1}{\pst@cntc}{\pnode(*{\pst@number\pst@dima} {#3}){#4\i}% hv 20130713 \advance\pst@dima \pst@dimb}% \else \multido{\i=0+1}{\pst@cntc}{\pnode(!/x \pst@number\pst@dima\space def x #3){#4\i}% \advance\pst@dima \pst@dimb}% \fi% \expandafter\xdef \csname \PST@root nodecount\endcsname {\the\pst@cnta}% \ifnum\Pst@Debug>0 \typeout{Created nodes #40 .. #4\the\pst@cnta}\fi% }\ignorespaces}% % \def\AtoB(#1)(#2)#3{\psLCNodeVar(#1)(#2)(-1,1){#3}} \def\AplusB(#1)(#2)#3{\psLCNodeVar(#1)(#2)(1,1){#3}} \def\midAB(#1)(#2)#3{\psLCNodeVar(#1)(#2)(.5,.5){#3}} % \def\psnline{\pst@object{psnline}}%line of nodes \def\psnline@i{\pst@getarrows{\psnline@ii}} \def\psnline@ii(#1,#2)#3{{% \pst@killglue% \use@par% \pst@cnta=#2 \relax\advance\pst@cnta by 1 \edef\@tmp{}% \multido{\i=#1+1}{\pst@cnta}{\xdef\@tmp{\@tmp(#3\i)}}% \expandafter\psline\@tmp}% \ignorespaces}% % \def\psnpolygon{\pst@object{psnpolygon}}%polygon of nodes \def\psnpolygon@i{\pst@getarrows{\psnpolygon@ii}} \def\psnpolygon@ii(#1,#2)#3{{% \pst@killglue% \use@par% \pst@cnta=#2 \relax\advance\pst@cnta by 1 \edef\@tmp{}% \multido{\i=#1+1}{\pst@cnta}{\xdef\@tmp{\@tmp(#3\i)}}% \expandafter\pspolygon\@tmp}% \ignorespaces}% % \def\psncurve{\pst@object{psncurve}}%line of nodes \def\psncurve@i{\pst@getarrows{\psncurve@ii}} \def\psncurve@ii(#1,#2)#3{{% \pst@killglue% \use@par% \pst@cnta=#2 \relax\advance\pst@cnta by 1 \edef\@tmp{}% \multido{\i=#1+1}{\pst@cnta}{\xdef\@tmp{\@tmp(#3\i)}}% \expandafter\pscurve\@tmp}% \ignorespaces}% % \def\psnccurve{\pst@object{psnccurve}}%line of nodes \def\psnccurve@i{\pst@getarrows{\psnccurve@ii}} \def\psnccurve@ii(#1,#2)#3{{% \pst@killglue% \use@par% \pst@cnta=#2 \relax\advance\pst@cnta by 1 \xdef\@tmp{}% \multido{\i=#1+1}{\pst@cnta}{\xdef\@tmp{\@tmp(#3\i)}}% \expandafter\psccurve\@tmp}% \ignorespaces}% % \def\shownode(#1){%display node user coords in console \pst@killglue% \pstVerb{% gsave tx@Dict begin % tx@NodeDict /N@#1 known { % known node /tmpar [(Node #1: ) <28> () (, ) () <29>] def % /str 12 string def STV CP T \psGetNodeCenter{#1}\space tmpar 2 #1.x str cvs put /str 12 string def tmpar 4 #1.y str cvs put tmpar concatstringarray = }% {% not known (Node #1: (NOT KNOWN)) = % } ifelse % end grestore }% \ignorespaces}% % % Use to construct a sequence of nodes % Eg, \pnodes{P}(0,1)(2;5)(3,4) defines nodes P0, P1, P2 with respective locations % and a macro \Pnodecount containing the highest index created \def\pnodes@ii#1{\getnodelist{#1}{}} % \def\getnodelist#1#2{% \pst@args=0 \relax% \def\PST@root{#1}% \def\pst@next{#2}% command to perform after reading list \getnext@Node}% % \def\getnext@Node{\@ifnextchar({\getnext@Node@i}% {\advance\pst@args by \m@ne \expandafter\xdef \csname \PST@root nodecount\endcsname {\the\pst@args} \ifnum\Pst@Debug>0 \typeout{Created nodes \PST@root0 .. \PST@root\the\pst@args}\fi% \pst@next}% }% % \def\getnext@Node@i(#1){% \pnode(#1){\PST@root\the\pst@args}% \advance\pst@args by \@ne\relax% \getnext@Node}% % \def\psLCNodeVar(#1)(#2)(#3)#4{% \pst@getcoor{#1}\my@tempA% \pst@getcoor{#2}\my@tempB% \pnode(#3){tmpLCn@de}% \pnode(!% \my@tempA /YA exch \pst@number\psyunit div def /XA exch \pst@number\psxunit div def \my@tempB /YB exch \pst@number\psyunit div def /XB exch \pst@number\psxunit div def %stack now empty \psGetNodeCenter{tmpLCn@de}\space XA tmpLCn@de.x mul XB tmpLCn@de.y mul add YA tmpLCn@de.x mul YB tmpLCn@de.y mul add){tmpLCn@deA}% \pnode(tmpLCn@deA){#4}% }% % \def\psRelNodeVar{\pst@object{psRelNodeVar}} \def\psRelNodeVar@i(#1)(#2)(#3)#4{{% A - B - factor;angle - node name \use@par \pst@getcoor{#1}\my@tempA% \pst@getcoor{#2}\my@tempB% \pnode(#3){tmpn@de}% \pnode(! /unit \pst@number\psyunit \pst@number\psxunit div def % yunit/xunit \my@tempA /YA exch \pst@number\psyunit div def /XA exch \pst@number\psxunit div def \my@tempB /YB exch \pst@number\psyunit div YA sub \ifPst@trueAngle\space unit mul \fi\space def /XB exch \pst@number\psxunit div XA sub def %complex multiply (XB,YB) and (P.x,P.y), then add (XA,YA) \psGetNodeCenter{tmpn@de} XB tmpn@de.x mul YB tmpn@de.y mul sub YB tmpn@de.x mul XB tmpn@de.y mul add \ifPst@trueAngle\space unit div \fi\space YA add exch XA add exch %x, y coords on stack ){#4}% }} % \def\psRelLineVar{\pst@object{psRelLineVar}} \def\psRelLineVar@i{\@ifnextchar({\psRelLineVar@iii}{\psRelLineVar@ii}} \def\psRelLineVar@ii#1{% \addto@par{arrows=#1}% \psRelLineVar@iii} \def\psRelLineVar@iii(#1)(#2)(#3)#4{{% \pst@killglue \use@par \psRelNodeVar(#1)(#2)(#3){#4}% \psline(#1)(#4)% }\ignorespaces} % \def\rhombus#1(#2)(#3)#4#5{% \rhombus{m}(B)(D){A}{C} \AtoB(#2)(#3){node@P}% P=BD % compute angle between BD and BC, in Postscript \pnode(! %compute angle and scale in PS /tmp \psGetNodeCenter{node@P} node@P.x node@P.y Pyth 2 div def %tmp=half-length of BD /ang tmp #1\space div Acos def %ang=angle from BD to BC & BA #1\space tmp 2 mul div %scale factor s=m/BD dup ang cos mul exch ang sin mul ){node@A1}% s cos(ang), s sin(ang) \pnode(! \psGetNodeCenter{node@A1} node@A1.x node@A1.y neg ){node@A2}%reflect in x axis \psRelNodeVar(#2)(#3)(node@A1){#4}% \psRelNodeVar(#2)(#3)(node@A2){#5}% }% % \def\psrline{\pst@object{psrline}}% relative lines \def\psrline@i{\@ifnextchar({\psrline@iii}{\psrline@ii}}% \def\psrline@ii#1{% \addto@par{arrows=#1}% \psrline@iii}% \def\psrline@iii{% \getnodelist{@tmpnode}{\psrline@iv}% }% \def\psrline@iv{% \ifnum\pst@args<0\else%do nothing \pnode(@tmpnode0){@tmpnodeB0}% \multido{\iA=1+1,\iB=0+1}{\pst@args}{% \AplusB(@tmpnodeB\iB)(@tmpnode\iA){@tmpnodeB\iA}}% \psrline@v% \fi% }% \def\psrline@v{{%finish up \pst@killglue% \use@par% \xdef\tmp{(@tmpnodeB0)}% \multido{\i=1+1}{\pst@args}% {\xdef\tmp{\tmp(@tmpnodeB\i)}}% \expandafter\psline\tmp% }\ignorespaces}% % \def\polyIntersections#1#2(#3)(#4){% %nodename1 | nodename2 | A | B | % intersections with line from A, B \def\nodenameA{#1}\def\nodenameB{#2}% \pnode(#3){P@A}\pnode(#4){P@B}% \@ifnextchar({\polyIntersections@next}{\polyIntersections@ii}% }% \def\polyIntersections@ii#1#2{% \def\root@node{#1}\num@pts=#2 \relax% \polyIntersections@iii}% % \def\polyIntersections@next{%read as many points as exist \def\root@node{P@}\getnodelist{P@}{\num@pts=\pst@args \relax\polyIntersections@iii}% }% \def\polyIntersections@iii{%nodes are now XXX0....XXXn, n=num@pts \pst@cnta=\num@pts \relax\advance\pst@cnta by 1 \relax% \pstVerb{% /xarray \the\pst@cnta\space array def /yarray \the\pst@cnta\space array def tx@Dict begin }% \multido{\i=0+1}{\the\pst@cnta}{\pstVerb{ \psGetNodeCenter{\root@node\i} xarray \i\space \root@node\i.x put yarray \i\space \root@node\i.y put }}% \pstVerb{ /tposmin 100 def /tnegmax -100 def %/argposmin 0 def /argposmax 0 def \psGetNodeCenter{P@B} \psGetNodeCenter{P@A} /dx P@B.x P@A.x sub def /dy P@B.y P@A.y sub def /lenAB dx dy Pyth def /oldx xarray 0 get def /oldy yarray 0 get def 1 1 \the\num@pts\space {/k exch def /newx xarray k get def /newy yarray k get def /ddx newx oldx sub def /ddy newy oldy sub def /det ddy dx mul ddx dy mul sub def det abs lenAB ddx ddy Pyth mul .001 mul gt {/ac oldx P@A.x sub def /bd oldy P@A.y sub def /tt ac ddy mul bd ddx mul sub det div def %solve for t value at intersection /ss ac dy mul bd dx mul sub det div def % solve for s value at intersection ss 0 ge {ss 1 le {tt 0 lt {tt tnegmax gt {/tnegmax tt def} if } {tt tposmin lt {/tposmin tt def} if } ifelse } if } % ss 1 le if }%ss 0 ge if %det> /oldx newx def /oldy newy def} for end }% \pnode(! \psGetNodeCenter{P@A} \psGetNodeCenter{P@B} P@B.x P@A.x sub tposmin mul P@A.x add P@B.y P@A.y sub tposmin mul P@A.y add ){\nodenameA}% \pnode(! \psGetNodeCenter{P@A} \psGetNodeCenter{P@B} P@B.x P@A.x sub tnegmax mul P@A.x add P@B.y P@A.y sub tnegmax mul P@A.y add){\nodenameB}% }% % \def\actualscale#1 #2 scale{% extract x-scale from, eg, {2. 2. scale} #1} % \def\psGetCenter#1{ tx@NodeDict begin /N@#1 load GetCenter end }% x y on stack in system coor % \def\ArrowNotch{\pst@object{ArrowNotch}} \def\ArrowNotch@i#1#2#3#4{{% %noderootname | index | arrowdirection | notchnodename % \pst@killglue% \use@par% \def\inc{-1}% \ifx#3<\def\inc{1}\fi% -1 means notch to left of arrowhead %get length of pointed arrow under these conditions (types ->, -D> and their reverses) \pstVerb{ 1 \psk@arrowinset\space sub \psk@arrowlength\space \psk@arrowsize\space \pst@number\pslinewidth \space mul add mul mul \expandafter\actualscale\psk@arrowscale \space mul /hh exch def /hh1 hh .05 sub def }% PS variable hh contains dist from tip to notch of arrow, in pts \def\root@node{#1}\num@pts=\csname\root@node nodecount\endcsname % \pst@cntb=\num@pts \advance\pst@cntb by \@ne%actual node count \pst@cnta=\num@pts \advance\pst@cnta by \thr@@%size of PS array \pst@cntc=#2 \relax% index of center of circle \ifnum\pst@cntc>\num@pts \pnode(0,0){#4}\else %compute a (screen based) unit vector in directions P1P0 and Pn-1Pn \pstVerb{% /PythSq { dup mul exch dup mul add } def /PtSub { % xA yA xB yB 3 -1 roll % xA xB yB yA sub neg % xA xB yA-yB 3 1 roll % yB-yA xA xB sub % yB-yA xA-xB exch % xB-xA yA-yB } def /xarray \the\pst@cnta\space array def /yarray \the\pst@cnta\space array def tx@Dict begin }% end pstVerb \multido{\i=0+1,\ib=1+1}{\the\pst@cntb}{\pnode(! \psGetCenter{\root@node\i}\space % center on stack in system coords, not user coords yarray \ib\space 3 -1 roll put xarray \ib\space 3 -1 roll put 0 0 ){@tmp}}% end multido %\pstVerb{ \psGetCenter{\root@node6} == == } \pnode(! xarray 1 get dup yarray 1 get dup 3 1 roll % x1 y1 x1 y1 xarray 2 get yarray 2 get PtSub % x1 y1 x1-x2 y1-y2 2 copy Pyth hh div 2 div dup % x1 y1 x1-x2 y1-y2 d d ,d->d/2*hh 3 1 roll % x1 y1 x1-x2 d y1-y2 d div 3 1 roll div %x1 y1 (y1-y2)/d (x1-x2)/d 3 1 roll %x1 (x1-x2)/d y1 (y1-y2)/d add 3 1 roll add % y1-(y2-y1)/d x1-(x2-x1)/d xarray 0 3 -1 roll put yarray 0 3 -1 roll put %stack empty xarray length 2 sub /topnum exch def xarray topnum get dup yarray topnum get dup 3 1 roll %xn yn xn yn topnum 1 sub /topnum exch def xarray topnum get yarray topnum get % xn yn xn yn x(n-1) y(n-1) 3 -1 roll sub neg 3 1 roll sub exch % xn yn (xn-x(n-1)) (yn-y(n-1)) 2 copy Pyth hh div 2 div dup % xn yn (xn-x(n-1)) (yn-y(n-1)) d d (d->d/(2*h)) 3 1 roll div 3 1 roll div %xn yn (xn-x(n-1))/d (yn-y(n-1))/d 3 -1 roll add 3 1 roll % y(n+1) x(n+1) topnum 2 add /topnum exch def xarray topnum 3 -1 roll put yarray topnum 3 -1 roll put % empty % next step--find first index outside circle of radius hh /oldcindex \the\pst@cntc\space 1 add def %position in array xarray oldcindex get /xc exch def yarray oldcindex get /yc exch def %hh .05 sub /hh exch def % that's close enough for a crossing /inc \inc\space def %+1 for left facing arrow, else -1 /cindex oldcindex def {cindex inc add /cindex exch def xarray cindex get xc sub yarray cindex get yc sub Pyth dup hh1 gt { exit } if } loop % exit from loop with cindex the first index of an external point--dist on stack hh1 .1 add lt { xarray cindex get yarray cindex get } %else within segment { xarray cindex inc sub get dup yarray cindex inc sub get dup 4 -1 roll exch xarray cindex get yarray cindex get PtSub /dy1 exch def /dx1 exch def dx1 dy1 PythSq /Aterm exch def % dx1=x(n-1)-x(n), dy1=y(n-1)-y(n) [if inc=1]: dx1=x(n+1)-x(n), dy1=y(n+1)-y(n) [if inc=-1] % x(n-inc) y(n-inc), Aterm=dx1^2+dy1^2 2 copy xc yc PtSub % x(n-inc) y(n-inc) (x(n-inc)-xc) (y(n-inc)-yc) 2 copy 2 copy 3 -1 roll mul 3 1 roll mul add hh dup mul sub % x(n-inc) y(n-inc) (y(n-inc)-yc) (x(n-inc)-xc) (x(n-inc)-xc)^2+(y(n-inc)-yc)^2-hh^2 Aterm div /Cterm exch def % x(n-inc) y(n-inc) (y(n-inc)-yc) (x(n-inc)-xc) , Cterm=((x(n-inc)-xc)^2+(y(n-inc)-yc)^2-hh^2)/(Aterm) (<0) dx1 dy1 % x(n-inc) y(n-inc) (y(n-inc)-yc) (x(n-inc)-xc) dx1 dy1 4 1 roll mul 3 1 roll mul add Aterm div /Bterm exch def % x(n-inc) y(n-inc) , Bterm=( (x(n-inc)-xc)*dx1+(y(n-inc)-yc)*dy1)/Aterm Bterm abs neg dup dup mul Cterm sub sqrt add dup /tval exch def % x(n-inc) y(n-inc) tvalue dup dx1 dy1 4 1 roll mul 3 1 roll mul % x(n-inc) y(n-inc) t*dx1 t*dy1 PtSub } ifelse % x y screen coords of arrow notch now on stack---convert to user x y \pst@number\psyunit div exch \pst@number\psxunit div exch %use coords now on stack ){#4}\fi% \pstVerb { end } %tx@Dict }\ignorespaces}% % \def\saveDataAsNodes#1#2{% Filename NodePrefix \psLoopIndex=0\relax \typeout{Open file #1}% \openin7=#1 \loop \read7 to \@Data \ifeof7\else \ifx\@Data\@empty \else \pnode(!\@Data){#2\the\psLoopIndex}% \typeout{#2\the\psLoopIndex -> \@Data}% \advance\psLoopIndex by 1 \let\@oldData\@Data \fi \repeat \closein7 \advance\psLoopIndex by -1 \pnode(!\@oldData){#2Last}% } % \catcode`\@=\TheAtCode\relax \endinput %% %% END pst-node.tex