Conclusion: arrows in the middle of bezier curves

Paulo Abreu paulotex at geocities.com
Wed Dec 10 02:46:07 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.
-----------------------------------------------------------------------------

Thanks to all the answers. I learned a lot with them,
and I'd like to resume the information I got, in case
somebody as a similar problem to solve.

My problem was: I wanted a nice way to place arrows in
the middle of a bezier curve.

Here's what I learned:

1. If the 4 control points are known
=====================================

Let's call them (x_0, y_0), (x_1, y_1), (x_2, y_2) and
(x_3, y_3), where the curve goes from (x_0, y_0) to
(x_3, y_3). In that case, the curve is defined
parametrically by:
x(t) = a_x t^3 + b_x t^2 + c_x t + x_0
y(t) = a_y t^3 + b_y t^2 + c_y t + y_0,
where
0 <= t <= 1,
a_x = -x_0 + 3 x_1 - 3 x_2 + x_3,
b_x = 3 (x_2 - 2 x_1 + x_0),
c_x = 3 (x_1 - x_0),
a_y = -y_0 + 3 y_1 - 3 y_2 + y_3,
b_y = 3 (y_2 - 2 y_1 + y_0),
c_y = 3 (y_1 - y_0).

This means that you can have an arrow in the middle of a
bezier curve simply by writing:
\psset{arrows=->}
\parametricplot{0}{.5}{%
t t t mul mul a_x mul % a_x t^3
t t mul b_x mul add   % + b_x t^2
t c_x mul add         % + c_x t
x_0 add               % + x_0
t t t mul mul a_y mul % a_y t^3
t t mul b_y mul add   % + b_y t^2
t c_y mul add         % + c_y t
y_0 add               % + y_0
}
\psset{arrows=-}
\parametricplot{.5}{1}{%
t t t mul mul a_x mul % a_x t^3
t t mul b_x mul add   % + b_x t^2
t c_x mul add         % + c_x t
x_0 add               % + x_0
t t t mul mul a_y mul % a_y t^3
t t mul b_y mul add   % + b_y t^2
t c_y mul add         % + c_y t
y_0 add               % + y_0
}
The number .5 defines where in the curve the arrow appears
(in this case, in the middle). Breaking the curve in more
places allows for more arrows.

Complete example:

\documentclass{article}

\usepackage{pst-plot}

\pagestyle{empty}

\begin{document}

\psset{arrowsize=2mm}

\begin{pspicture}(4.5,3)
\psbezier(0,0)(4.5,0)(0,3)(4.5,3) % (x_0,y_0)...(x_3,y_3)
\end{pspicture}

\begin{pspicture}(4.5,3)
\psset{arrows=->}
\parametricplot{0}{.5}{%
t t t mul mul 18 mul % a_x=18
t t mul -27 mul add  % b_x=-27
t 13.5 mul add       % c_x=13.5, x_0=0
t t t mul mul -6 mul % a_y=-6
t t mul 9 mul add    % b_y=9, c_y=0, y_0=0
}
\psset{arrows=-}
\parametricplot{.5}{1}{%
% bellow is the same has above, but with no comments
t t t mul mul 18 mul t t mul -27 mul add t 13.5 mul add
t t t mul mul -6 mul t t mul   9 mul add
}
\end{pspicture}

\end{document}

Thanks to Denis Girou for the information on Bezier curves.

2. Only the first and last points are known
============================================

This was new to me, has I haven't study the part on nodes
of the manual yet (but it seems to be the right time now...).
So I'll just quote the two persons that gave suggestions
so far:

Denis Girou suggested the following:
-------------------Begin Quote---------------------------
Otherway, one partial solution could be to built a variation of the \pccurve
macro. The \pc.... macros allow to reference a position between the two points
defined using for instance the tpos parameter. So, we can position an arrow at
the distance chosen from the points.

There are at least two problem:

1/ In \pccurve, the Bezier curve is defined only by the two extremums and
the control points are automatically computed according to the value of the
ncurvA and ncurvB parameters. We can vary the curve changing these parameters,
but if you really want to fixe yourself the control points, you must built a
modified version of \pccurve which used four coordinates points as \psbezier.

2/ We can't have automatically in this way the good orientation of the
arrow. It must be adjusted by hand (which seems not too difficult after some
experiments).

\documentclass{article}

\usepackage{pst-plot}
\usepackage{pst-node}

\pagestyle{empty}

\begin{document}

\psset{arrowsize=3mm}

\begin{pspicture}(4.5,3)
\pccurve(0,0)(4,3)
\tvput{\pscustom{\arrows{->}\code{-30 -20 0 3 ArrowB}}}
\end{pspicture}
\begin{pspicture}(4.5,3)
\pccurve[ncurvA=-2,ncurvB=2](0,0)(4,3)
\tvput[tpos=0.25]{\pscustom{\arrows{->}\code{-30 -10 0 3 ArrowB}}}
\tvput[tpos=0.75]{\pscustom{\arrows{->}\code{-30 -10 0 3 ArrowB}}}
\end{pspicture}

\end{document}
-----------End Quote---------------------------------------
(Some lines of the example above were removed because they
were not of interest to the subject)

This example bombed on GhostView due to some \relax's in the
ps file (generated with dvips). After manually removing
the offending words, it worked fine.

And Jcrcremer suggested the following:

---------------Begin Quote-------------------------
\documentclass{article}
\usepackage{pstricks,pst-node}
\begin{document}
\begin{pspicture}(0,0)(6,2)
\pccurve[angleA=45,angleB=-90](0,0)(6,4)
\ncput[nrot=:U]{\psline[arrowsize=.5cm 2]{->}(-0.01,0)(0,0)}
\end{pspicture}
\end{document}

The \ncput type commands have lots of options that will let you position their
argument.
---------------------End Quote-----------------------
I haven't tried this example yet.

3. More control over arrows and curves
=======================================

The MetaPost package was suggested. This is a program that
converts commands written in a Metafont-like language into
instructions. It seems that some knowledge of metafont is
needed, so I didn't experiment further. It can be found in
CTAN/pub/tex/graphics/metapost

And now my conclusions:

1. I don't want to learn Metafont, so I'll leave MetaPost
alone for now.

2. The possibility to draw a bezier curve knowing only
the first and the last points and giving some more
intuitive parameters is very interesting and seems very
powerfull. The placement
of the arrow doesn't seem so complicated, but it needs
some trial. I need to study the part on nodes of the
manual.

3. If the 4 control points are known, then the parametric
plot seems the best solution to me. The calculations
to find the coeficients a_x,...,c_y are simple and the
placement of the arrow poses no problem. It has the
advantage of making the placement of several arrows
in the curve a very simple task.

Thanks to all for the help.

Paulo

-----------------------------------------------------------------------------
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>
-----------------------------------------------------------------------------