[pstricks] Arrow between two nodes

Denis Girou Denis.Girou at idris.fr
Thu Oct 24 21:29:24 CEST 2002


>>>>> "R.K.Mehta" == R K Mehta <R.K.Mehta> writes:

    R.K.Mehta> I want an arrow on the line (and curve) joining two nodes with label above
    R.K.Mehta> and
    R.K.Mehta> below the arrow as:

    R.K.Mehta>               g
    R.K.Mehta>       B	*----->-----*B

    R.K.Mehta> I remember Mr. D.G. had already given us the solution on this aspect a
    R.K.Mehta> long back ago. kindly help now.

  Yes, this was (already...) five years ago:
http://tug.org/pipermail/pstricks/1997/000093.html
but not for node connections.

  This is very easy to do the same for lines joining nodes. So, in your case,
you have just to say (note that I do not use a value of 0.5 but of 0.65
to have the arrow at the real middle of the segment, as this value fix
the point where the arrow is pointed, which is not aesthetic in your case):

\begin{pspicture}(2,1)
  \pcline[ArrowInside=->,ArrowInsidePos=0.65]{*-*}(0,0)(2,0)
  \naput[labelsep=0.3]{\large$g$}
\end{pspicture}

  I also give again the code for Bezier curves, because I found during my
recent tests that there was a bug when ArrowInsidePos=0, which gave a wrong
position of the arrow.

  I made various attempts to do the same for \nccurve. This is really more
difficult, even if we can use the same idea than for \psbezier. Nevertheless,
I do not succeed to have a correct version, sorry...

D.G.


\documentclass{article}

\usepackage{pst-node}

\pagestyle{empty}

\makeatletter

% DG addition begin - Dec. 18/19, 1997 and Oct. 11, 2002

% Adapted from \psset at arrows
\def\psset at ArrowInside#1{%
\begingroup
\pst at activearrows
\xdef\pst at tempg{<#1}%
\endgroup
\expandafter\psset@@ArrowInside\pst at tempg\@empty-\@empty\@nil
\if at pst\else
\@pstrickserr{Bad intermediate arrow specification: #1}\@ehpa
\fi}

% Adapted from \psset@@arrows
\def\psset@@ArrowInside#1-#2\@empty#3\@nil{%
\@psttrue
\def\next##1,#1-##2,##3\@nil{\def\pst at tempg{##2}}%
\expandafter\next\pst at arrowtable,#1-#1,\@nil
\@ifundefined{psas@#2}%
{\@pstfalse\def\psk at ArrowInside{}}%
{\def\psk at ArrowInside{#2}}}
% Default value empty
\def\psk at ArrowInside{}

% Modified version of \pst at addarrowdef
\def\pst at addarrowdef{%
\addto at pscode{%
/ArrowA {
\ifx\psk at arrowA\@empty
\pst at oplineto
\else
\pst at arrowdef{A}
moveto
\fi
} def
/ArrowB {
\ifx\psk at arrowB\@empty \else \pst at arrowdef{B} \fi
} def
% DG addition
/ArrowInside {
\ifx\psk at ArrowInside\@empty \else \pst at arrowdefA{Inside} \fi
} def
}}

% Adapted from \pst at arrowdef
\def\pst at arrowdefA#1{%
\ifnum\pst at repeatarrowsflag>\z@
/Arrow#1c [ 6 2 roll ] cvx def Arrow#1c
\fi
\tx at BeginArrow
\psk at arrowscale
\@nameuse{psas@\@nameuse{psk at Arrow#1}}
\tx at EndArrow}

% ArrowInsidePos parameter (default value 0.5)
\def\psset at ArrowInsidePos#1{\pst at checknum{#1}\psk at ArrowInsidePos}%
\psset at ArrowInsidePos{0.5}

% Redefinition of the PostScript /Line macro to print the intermediate
% arrow on each segment of the line
\pst at def{Line}<{%
NArray
n 0 eq not
  { n 1 eq { 0 0 /n 2 def } if
    2 copy
    /y1 ED
    /x1 ED
    ArrowA
    x1 y1
    /n n 1 sub def
    n { 4 copy
        /y1 ED
        /x1 ED
        /y2 ED
        /x2 ED
        x1
        y1
        x2 x1 sub \psk at ArrowInsidePos mul x1 add
        y2 y1 sub \psk at ArrowInsidePos mul y1 add
        ArrowInside
        pop pop pop pop
        Lineto
      } repeat
    CP 4 2 roll ArrowB L pop pop } if}>

% Redefinition of the PostScript /OpenBezier macro to print the intermediate
% arrow
\pst at def{OpenBezier}<{%
BezierNArray
n 1 eq
  { pop pop }
  { 2 copy
    /y0 ED
    /x0 ED
    ArrowA
    n 4 sub 3 idiv
      { 6 2 roll 4 2 roll curveto } repeat
    6 2 roll
    4 2 roll
    ArrowB
    /y3 ED
    /x3 ED
    /y2 ED
    /x2 ED
    /y1 ED
    /x1 ED
    /t \psk at ArrowInsidePos def
    /t0 1 t sub neg def
    /cx x1 x0 sub 3 mul def
    /cy y1 y0 sub 3 mul def
    /bx x2 x1 sub 3 mul cx sub def
    /by y2 y1 sub 3 mul cy sub def
    /ax x3 x0 sub cx sub bx sub def
    /ay y3 y0 sub cy sub by sub def
    ax t0 3 exp mul bx t0 t0 mul mul add cx t0 mul add x0 add
    ay t0 3 exp mul by t0 t0 mul mul add cy t0 mul add y0 add
    ax t 3 exp mul bx t t mul mul add cx t mul add x0 add
    ay t 3 exp mul by t t mul mul add cy t mul add y0 add
    ArrowInside pop pop pop pop
    x1 y1 x2 y2 x3 y3 curveto } ifelse }>

% Redefinition of the PostScript /NCLine macro to print the intermediate
% arrow of the line
\pst at def{NCLine}<{%
NCCoor
tx at Dict begin
  ArrowA
  CP
  4 2 roll
  ArrowB
  4 copy
  /y2 ED
  /x2 ED
  /y1 ED
  /x1 ED
  x1
  y1
  x2 x1 sub \psk at ArrowInsidePos mul x1 add
  y2 y1 sub \psk at ArrowInsidePos mul y1 add
  ArrowInside
  pop pop pop pop
  lineto
  pop pop
end}>

% DG addition end

\makeatother

\begin{document}

\psset{arrowscale=3}

% Lines (\psline macro)

\begin{pspicture}(2,1)
  \psline[ArrowInside=->](2,1)
\end{pspicture}

\begin{pspicture}(2,1)
  \psline[ArrowInside=->]{<->}(2,1)
\end{pspicture}

\begin{pspicture}(2,1)
  \psline[ArrowInside=-|,ArrowInsidePos=0.75]{|-|}(0,0)(2,1)
\end{pspicture}

\begin{pspicture}(0,-1)(10,2)
  \psline[ArrowInside=-<,ArrowInsidePos=0.75]{->}(0,0)(2,1)(3,-1)(5,-1)(10,2)
\end{pspicture}

% Lines (\pcline macro)

\begin{pspicture}(2,1)
  \pcline[ArrowInside=->](0,0)(2,1)
\end{pspicture}

\begin{pspicture}(2,1)
  \pcline[ArrowInside=->]{<->}(0,0)(2,1)
\end{pspicture}

\begin{pspicture}(2,1)
  \pcline[ArrowInside=-|,ArrowInsidePos=0.75]{|-|}(0,0)(2,1)
\end{pspicture}

\begin{pspicture}(2,1)
  \pcline[ArrowInside=->,ArrowInsidePos=0.65]{*-*}(0,0)(2,0)
  \naput[labelsep=0.3]{\large$g$}
\end{pspicture}

% Bezier curves (\psbezier macro)

\begin{pspicture}(3,4)
  \psbezier[ArrowInside=-|](1,1)(2,2)(3,3)
  \psset{linestyle=none,ArrowInside=-o}
  \psbezier[ArrowInsidePos=0.25](1,1)(2,2)(3,3)
  \psbezier[ArrowInsidePos=0.75](1,1)(2,2)(3,3)
  \psset{linestyle=none,ArrowInside=-*}
  \psbezier[ArrowInsidePos=0](1,1)(2,2)(3,3)
  \psbezier[ArrowInsidePos=1](1,1)(2,2)(3,3)
\end{pspicture}

\begin{pspicture}(3,4)
  \psbezier[ArrowInside=->,ArrowInsidePos=0](1,1)(2,2)(3,3)
  \psset{linestyle=none,ArrowInside=->}%
  \psbezier[linecolor=red,ArrowInsidePos=0.1](1,1)(2,2)(3,3)
  \psbezier[linecolor=blue,ArrowInsidePos=0.2](1,1)(2,2)(3,3)
  \psbezier[linecolor=magenta,ArrowInsidePos=0.9](1,1)(2,2)(3,3)
  \psbezier[linecolor=green,ArrowInsidePos=1](1,1)(2,2)(3,3)
\end{pspicture}

\end{document}



More information about the PSTricks mailing list