7

I use TikZ to draw a Bézier curve and place 4 circles (nodes) on that curve using pos=0.25 etc. (see MWE below). The curve has an arrow at the end. I would like to use >=latex to get LaTeX-style arrow heads.

This is where I run into a problem: without >=latex, the node placement is fine, i.e. the curve runs through the center of the node. With >=latex, the last node before the arrow is placed too low (see images below), i.e. the curve doesn't run through the center of the node.

Is this behavior intended? Is there any way around it?

MWE:

\documentclass{article}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}[>=latex]
    \draw[->] (0,0) .. controls (2,0) and (2,6)  .. (4,4)
    \foreach \t in {0,0.25,0.5,0.75}
        { node[pos=\t,circle,draw,fill] {} };
\end{tikzpicture}

\begin{tikzpicture}
    \draw[->] (0,0) .. controls (2,0) and (2,6)  .. (4,4)
    \foreach \t in {0,0.25,0.5,0.75}
        { node[pos=\t,circle,draw,fill] {} };
\end{tikzpicture}

\end{document}

Output: (upper: with >=latex, lower: without >=latex)

Output of MWE

6

The problem comes because arrow tips shorten the path. I don't know how TiKZ does it, but it seems that it internally computes the complete path without arrow and decides where pos corresponds over it, and finally it draws a path with arrow tip which is different from the previous one.

Here you have an example

enter image description here

and a detail

enter image description here

\documentclass[border=3mm]{standalone}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}
    \draw[green, thick, shorten >=3.8pt] (0,0) .. controls (2,0) and (2,6)  .. (4,4)
    \foreach \t in {0,0.25,0.5,0.75}
        { node[pos=\t,circle,draw] {} };

    \draw[-latex] (0,0) .. controls (2,0) and (2,6)  .. (4,4)
    \foreach \t in {0,0.25,0.5,0.75}
        { node[pos=\t,circle,draw] {} };

    \draw[->,red, thick] (0,0) .. controls (2,0) and (2,6)  .. (4,4)
    \foreach \t in {0,0.25,0.5,0.75}
        { node[pos=\t,circle,draw=red] {} };

    \draw[-|,blue] (0,0) .. controls (2,0) and (2,6)  .. (4,4)
    \foreach \t in {0,0.25,0.5,0.75}
        { node[pos=\t,circle,draw=blue] {} };
\end{tikzpicture}

\end{document}

As you can see all except the green line has been defined with (0,0) .. controls (2,0) and (2,6) .. (4,4) but with different arrow tips and all three show a different curve but with equally placed circles (blue and red circles cover green and black).

The green line doesn't have arrow tip but it's shortened some points. It almost equals the black line with latex tip.

A workaround could be to use a mark at the end of the path:

\documentclass[border=3mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.markings}

\begin{document}
\begin{tikzpicture}[decoration={markings, mark=at position 0.9999 with {\arrow{latex}}}]

    \draw[postaction={decorate}] (0,0) .. controls (2,0) and (2,6)  .. (4,4)
    \foreach \t in {0,0.25,0.5,0.75}
        { node[pos=\t,circle,draw, fill] {} };

\end{tikzpicture}
\end{document}

enter image description here

  • Thank you for the great explanation! Though I am not really happy with the workaround: When you look at the arrow in detail, you'll see that the curve continues for some points after the arrow. When you make the curve thick this gets even more extreme. – hbaderts Feb 28 '15 at 9:51
2

Based on the answer by @Ignasi, I found another work-around. By setting the shorten option to a negative value (-3.8pt works fine here, thanks to @Ignasi), the curve is made longer and is drawn correctly. The downside to this is that the arrow head goes further than the specified point ((4,4) in this example), so this work-around only works if the arrow doesn't have to end at a specific point, i.e. it goes into empty space.

\documentclass[border=3mm]{standalone}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}
    \draw[thick,-latex] (0,0) .. controls (2,0) and (2,6)  .. (4,4)
    \foreach \t in {0,0.25,0.5,0.75}
        { node[pos=\t,circle,draw] {} };

   \draw[->,red, thick] (0,0) .. controls (2,0) and (2,6)  .. (4,4)
    \foreach \t in {0,0.25,0.5,0.75}
        { node[pos=\t,circle,draw=red] {} };

    \draw[-|,blue] (0,0) .. controls (2,0) and (2,6)  .. (4,4)
    \foreach \t in {0,0.25,0.5,0.75}
        { node[pos=\t,circle,draw=blue] {} };

    \draw[green,shorten >=-3.8pt,-latex] (0,0) .. controls (2,0) and (2,6)  .. (4,4)
    \foreach \t in {0,0.25,0.5,0.75}
        { node[pos=\t,circle,draw] {} };

\end{tikzpicture}

\end{document}

Result:

Result

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.