arrows in the middle of bezier curves

Denis Girou Denis.Girou at idris.fr
Fri Dec 19 21:28:41 CET 1997

-----------------------------------------------------------------------------
This is the PSTricks mailing list, devoted to discussions about computational
graphics in (La)TeX using the PSTricks package from Timothy van Zandt.
For help using this mailing list, see instructions at the end of message.
-----------------------------------------------------------------------------

D.G.>   Here is my own (limited) attempt

I continue tonight and follow the same way for \pspolygon and \psbezier
(probably that \pscurve would be another macro for which it can be useful).

So, as the main interest of Paulo Abreu was for Bezier curves, it must be
his solution. We have just to say something like:

\psbezier[ArrowInside=->](2,3)(3,-1)(4,2)
or
\psbezier[ArrowInside=-|,ArrowInsidePos=0.2](-2,-3)(2,3)(4,-1)(2,2)

Look at the following examples. Seeing the last one, I have a doubt about
the correctness of the computation of the positions, but as it is clearly
correct for Bezier curves which generate a line, I don't see where could be
the problem...

D.G.

\documentclass{article}

\usepackage{pstricks}

\textheight=25cm

\pagestyle{empty}

\makeatletter

% DG addition begin - Dec. 18/19, 1997

% 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
/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
/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}

% Modified version of \begin at ClosedObj
\def\begin at ClosedObj{%
\leavevmode
\pst at killglue
\begingroup
\use at par
\solid at star
\ifpsdoubleline \pst at setdoublesep \fi
\init at pscode}

% 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 /Polygon macro to print the intermediate
% arrow on each segment of the line
\pst at def{Polygon}<{%
NArray
n 2 eq { 0 0 /n 3 def } if
n 3 lt
{ n { pop pop } repeat }
{ n 3 gt { CheckClosed } if
n 2 mul
-2 roll
/y0 ED
/x0 ED
/y1 ED
/x1 ED
/xx1 x1 def
/yy1 y1 def
x1 y1
/x1 x0 x1 add 2 div def
/y1 y0 y1 add 2 div def
x1 y1 moveto
/n n 2 sub def
n { 4 copy
/y11 ED
/x11 ED
/y12 ED
/x12 ED
x11
y11
x12 x11 sub \psk at ArrowInsidePos mul x11 add
y12 y11 sub \psk at ArrowInsidePos mul y11 add
ArrowInside pop pop pop pop Lineto
} repeat
x1 y1 x0 y0
6 4 roll
2 copy
/y11 ED
/x11 ED
x11
y11
x0 x11 sub \psk at ArrowInsidePos mul x11 add
y0 y11 sub \psk at ArrowInsidePos mul y11 add
ArrowInside pop pop pop pop Lineto
x0
y0
xx1 x0 sub \psk at ArrowInsidePos mul x0 add
yy1 y0 sub \psk at ArrowInsidePos mul y0 add
ArrowInside pop pop pop pop Lineto
pop pop
closepath } ifelse }>

% 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 t 0.99 mul 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 }>

% 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=-|]{|-|}(0,0)(2,1)
\end{pspicture}

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

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

\begin{pspicture}(0,-1)(10,2)
\psline[linestyle=none,ArrowInside=->,ArrowInsidePos=0.25]
{->}(0,0)(2,1)(3,-1)(5,-1)(10,2)
\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}

\begin{pspicture}(0,-1)(10,2)
\psset{ArrowInside=-*}
\psline(0,0)(2,1)(3,-1)(5,-1)(10,2)
\psset{linestyle=none}
\psline[ArrowInsidePos=0](0,0)(2,1)(3,-1)(5,-1)(10,2)
\psline[ArrowInsidePos=1](0,0)(2,1)(3,-1)(5,-1)(10,2)
\end{pspicture}

\psset{ArrowInside=-|}

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

\clearpage

% Polygons (\pspolygon macro)

\begin{pspicture}(6,3)
\pspolygon[ArrowInside=-|](0,0)(3,3)(6,3)(6,1)
\end{pspicture}
%
\begin{pspicture}(-1,0)(6,3)
\pspolygon[ArrowInside=->,ArrowInsidePos=0.25](0,0)(3,3)(6,3)(6,1)
\end{pspicture}

\begin{pspicture}(6,4)
\pspolygon[ArrowInside=-|](0,0)(3,3)(6,3)(6,1)
\psset{linestyle=none,ArrowInside=-*}
\pspolygon[ArrowInsidePos=0](0,0)(3,3)(6,3)(6,1)
\pspolygon[ArrowInsidePos=1](0,0)(3,3)(6,3)(6,1)
\psset{ArrowInside=-o}
\pspolygon[ArrowInsidePos=0.25](0,0)(3,3)(6,3)(6,1)
\pspolygon[ArrowInsidePos=0.75](0,0)(3,3)(6,3)(6,1)
\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}(0,-1)(4,3)
\psbezier(0,0)(2,3)(3,-1)(4,2)
\end{pspicture}
%
\begin{pspicture}(0,-1)(4,3)
\psbezier[ArrowInside=->]{->}(2,3)(3,-1)(4,2)
\end{pspicture}
%
\begin{pspicture}(0,-1)(4,3)
\psset{ArrowInside=-|}
\psbezier[ArrowInsidePos=0.25](2,3)(3,-1)(4,2)
\psset{linestyle=none}
\psbezier[ArrowInsidePos=0.75](2,3)(3,-1)(4,2)
\psset{ArrowInside=-*}
\psbezier[ArrowInsidePos=0](2,3)(3,-1)(4,2)
\psbezier[ArrowInsidePos=1](2,3)(3,-1)(4,2)
\end{pspicture}

\begin{pspicture}(0,-1)(6,3)
\psbezier[ArrowInside=->](0,-1)(3,2)(6,3)(5,0)
\psset{linestyle=none,ArrowInside=-<}
\psbezier[ArrowInsidePos=0.2](0,-1)(3,2)(6,3)(5,0)
\psbezier[ArrowInsidePos=0.4](0,-1)(3,2)(6,3)(5,0)
\psbezier[ArrowInsidePos=0.6](0,-1)(3,2)(6,3)(5,0)
\psbezier[ArrowInsidePos=0.8](0,-1)(3,2)(6,3)(5,0)
\psset{ArrowInside=-o}
\psbezier[ArrowInsidePos=0.1](0,-1)(3,2)(6,3)(5,0)
\psbezier[ArrowInsidePos=0.9](0,-1)(3,2)(6,3)(5,0)
\psset{ArrowInside=-*}
\psbezier[ArrowInsidePos=0.3](0,-1)(3,2)(6,3)(5,0)
\psbezier[ArrowInsidePos=0.7](0,-1)(3,2)(6,3)(5,0)
\end{pspicture}

\end{document}

-----------------------------------------------------------------------------
The list interface (subscription, information, access to the archives) is on:
http://www.tug.org/cgi-bin/lwgate/pstricks
Otherway to unsubscribe, send mail to pstricks-request at mail.tug.org
with a blank subject and in body the line unsubscribe <email-address>
-----------------------------------------------------------------------------