Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

Standalone example:

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes}

\begin{document}
\begin{tikzpicture}
  \draw[black, very thick] plot[smooth] coordinates {(4,1) (2,2) (1,3) (2,4) (4,3)};

  \node[fill=green!60, inner sep=3pt, circle, draw] at (4, 1) {};
  \node[fill=green!60, inner sep=3pt, circle, draw] at (2, 2) {};
  \node[fill=green!60, inner sep=3pt, circle, draw] at (1, 3) {};
  \node[fill=green!60, inner sep=3pt, circle, draw] at (2, 4) {};
  \node[fill=green!60, inner sep=3pt, circle, draw] at (4, 3) {};
\end{tikzpicture}
\end{document}

Result:

enter image description here

What I want:

enter image description here

I like to have arrows before each node point at the node on all nodes in the path. How do I achieve this?

share|improve this question
    
Possible duplicate: TikZ: How to draw an arrow in the middle of the line? –  Paul Gaborit Oct 3 '12 at 20:02
    
No, I do not think this is a duplicate. Here it is a complete curve which passes behind the nodes. I also tried with path between nodes (it also works) but then you lose the effect of the curve. –  madit Oct 3 '12 at 20:12
add comment

3 Answers

up vote 5 down vote accepted

Based on my own answer to this question, I got the following result:

arrow before nodes

Positioning of the arrows is done automatically according to the list of points that appears at the beginning of the code. Here we go:

\documentclass{standalone}

\usepackage{etoolbox}

\usepackage{tikz}
\usetikzlibrary{shapes}
\usetikzlibrary{intersections}
\usetikzlibrary{decorations.markings}

\newcounter{counter}
\newcommand\getpoint[1]{\csuse{point#1}}
\def\pointlist{}
\newcommand\setpoint[2]{
    \node (point#1) at #2 {};
    \csxdef{point#1}{#2} 
    \edef\pointlist{\pointlist \getpoint{#1}}
}
\newcommand\addpoint[1]{\stepcounter{counter} \setpoint{\thecounter}{#1}}

\newcounter{anothercounter}
\newcommand\getanotherpoint[1]{\csuse{anotherpoint#1}}
\def\anotherpointlist{}
\newcommand\setanotherpoint[2]{
    \csxdef{anotherpoint#1}{#2} 
    \edef\anotherpointlist{\anotherpointlist \getanotherpoint{#1}}
}
\newcommand\addanotherpoint[1]{\stepcounter{anothercounter} \setpoint{\theanothercounter}{#1}}

\begin{document}
    \begin{tikzpicture}

        \addpoint{(4,1)}
        \addpoint{(2,2)}
        \addpoint{(1,3)}
        \addpoint{(2,4)}
        \addpoint{(4,3)}

        \draw [name path = curve 1, black, very thick] plot [smooth] coordinates {\pointlist};
        \path [name intersections={of=curve 1 and curve 1, name=i, total=\t, sort by = curve 1}] node {\xdef\totalone{\t}};

        \edef\mypath{}
        \pgfmathsetmacro{\lastbutone}{\totalone - 1}
        \foreach \k in {1, ..., \lastbutone}
        {
            \xdef\mypath{\mypath (i-\k) -- }
        }
        \edef\mypath{\mypath (i-\totalone)}

        \newdimen\xone
        \newdimen\yone
        \newdimen\xtwo
        \newdimen\ytwo

        \foreach \q in {1, ..., \thecounter}
        {
            \pgfextractx{\xtwo}{\pgfpointanchor{point\q}{center}}
            \pgfextracty{\ytwo}{\pgfpointanchor{point\q}{center}}

            \foreach \p in {1, ..., \totalone}
            {
                \pgfextractx{\xone}{\pgfpointanchor{i-\p}{center}}
                \pgfextracty{\yone}{\pgfpointanchor{i-\p}{center}}

                \ifboolexpr{
                    test {\ifdimless{\xtwo - 0.6pt}{\xone}} and test {\ifdimless{\xone}{\xtwo + 0.6pt}}
                    and
                    test {\ifdimless{\ytwo - 0.6pt}{\yone}} and test {\ifdimless{\yone}{\ytwo + 0.6pt}}
                }{
                    \setanotherpoint{\q}{\p}
                }{
                }
            }
        }

        \foreach \k in {1, ..., \thecounter}
        {
            \node [
                circle
                , fill = green!60
                , inner sep = 3pt
            ] (thepoint \k) at (i-\getanotherpoint{\k}) {};
        }

        \foreach \k in {2, ..., \thecounter}
        {
            \pgfmathtruncatemacro{\lastpoint}{\getanotherpoint{\k} - 5}
            \draw [decorate, decoration = {markings, mark = at position -0.01pt with {
                \node [
                    single arrow
                    , fill = red
                    , anchor = east
                    , minimum size = 2mm
                    , inner sep = 1pt
                    , single arrow head extend = 2pt
                    , transform shape
                ]{};
            }}] (i-\lastpoint) -- (thepoint \k) {};
        }
    \end{tikzpicture}
\end{document}

EDIT

OBS: I changed the style of the arrow just to be more like the provided example.

Well, just to complete my answer, now I will give a little more detail. Tripplet said there was a space between the arrow and cículo and he was right, as can be seen here:

Separation between circle and arrow

The distance between the circle and the arrow was given by the contour line, which was not being drawn. This is easily fixed as you can see:

\foreach \k in {1, ..., \thecounter} {
    \node [
        circle
        , draw = green      % added
        , fill = green!50
        , inner sep = 3pt
    ] (thepoint \k) at (i-\getanotherpoint{\k}) {};
}

And the result is

Circle with border drawn

But, if desired the arrow gets further into the circle, one can make the following changes:

\foreach \k in {1, ..., \thecounter} {
    \node [
        circle
        , inner sep = 2.75pt
    ] (thepoint \k) at (i-\getanotherpoint{\k}) {};
    \node [
        circle
        , draw = green
        , fill = green!50
        , inner sep = 3pt
    ] at (i-\getanotherpoint{\k}) {};
}

And you will get:

Arrow futher into circle

share|improve this answer
    
I don't like the point, that the arrows are not curved and look a little out of place. –  tripplet Oct 11 '12 at 12:43
    
@tripplet: Could you explain a little better? What do you mean by out of place? The arrows are being placed along the path. The distance is calculated directly by Tikz. I have no influence in this point. –  tecepe Oct 11 '12 at 17:12
    
To me the arrows don't look like they are part of the path and separately put over it. Maybe thats just a personal thing, the solution is just as good as the other, but I personally just like the look of madit's solution a little more ;) –  tripplet Oct 12 '12 at 11:30
    
@tripplet, take another look. ;) –  tecepe Oct 12 '12 at 14:18
    
awesome thats exactly what I wanted, thanks @tecepe. I didn't expect this to end this in so much code, good I asked, I would have never figured this out myself. –  tripplet Oct 15 '12 at 12:58
add comment

Here a "solution" derived from my answer to TikZ: How to draw an arrow in the middle of the line?.

The result is correct but with errors during compilation. Without smooth, there is no error.

enter image description here

The code:

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.pathreplacing,decorations.markings}
\tikzset{
  % style to apply some styles to each segment of a path
  on each segment/.style={
    decorate,
    decoration={
      show path construction,
      moveto code={
      },
      lineto code={
        \path [#1]
        (\tikzinputsegmentfirst) -- (\tikzinputsegmentlast);
      },
      curveto code={
        \path [#1] (\tikzinputsegmentfirst)
        .. controls
        (\tikzinputsegmentsupporta) and (\tikzinputsegmentsupportb)
        ..
        (\tikzinputsegmentlast);
      },
      closepath code={
        \path [#1]
        (\tikzinputsegmentfirst) -- (\tikzinputsegmentlast);
      },
    },
  },
  % style to add an arrow
  mid arrow/.style={decorate,decoration={
      markings,
      mark=at position .93 with {\arrow[#1]{stealth}},
    },
  },
  % style to add a circle
  point/.style={decorate,decoration={
      markings,
      mark=at position .99 with {\node[#1,thin,circle,inner sep=2pt]{};},
    },
  },
}

\begin{document}
\begin{tikzpicture}
  \draw[black, very thick,
  postaction={on each segment={mid arrow={fill=red,line width=3pt}}},
  postaction={on each segment={point={fill=lime,draw=green!50!black}}},
  ]
  plot[smooth] coordinates {(4,1) (2,2) (1,3) (2,4) (4,3)};
\end{tikzpicture}
\end{document}
share|improve this answer
    
Is Dimension too large the compile error you are referring to? That's what I get if the smooth option is left in there. –  Peter Grill Oct 3 '12 at 23:50
    
@PeterGrill Exact. I'm pretty sure it comes from the markings library... –  Paul Gaborit Oct 4 '12 at 0:28
    
The smooth option is pretty important to me so not the best solution, but good suggestion. –  tripplet Oct 11 '12 at 12:40
    
@tripplet The bug with smooth option and markings library can and must be fixed. I just need time... ;-) –  Paul Gaborit Oct 11 '12 at 13:06
add comment

Try with

\documentclass[border=2mm,tikz]{standalone}
\usetikzlibrary{shapes}
\usetikzlibrary{decorations.markings,arrows}


\begin{document}
\begin{tikzpicture}[decoration={markings,% 
 mark=at position .270  with {\arrow[red,line width=3pt]{>}},%
 mark=at position .470  with {\arrow[red,line width=3pt]{>}},%
 mark=at position .680  with {\arrow[red,line width=3pt]{>}},%
 mark=at position .980  with {\arrow[red,line width=3pt]{>}},%
 }]
  \draw[
     black, thick,postaction={decorate} ]%
     plot[smooth] coordinates {(4,1) (2,2) (1,3) (2,4) (4,3)};

  \node[fill=green!60, inner sep=3pt, circle, draw] at (4, 1) {};
  \node[fill=green!60, inner sep=3pt, circle, draw] at (2, 2) {};
  \node[fill=green!60, inner sep=3pt, circle, draw] at (1, 3) {};
  \node[fill=green!60, inner sep=3pt, circle, draw] at (2, 4) {};
  \node[fill=green!60, inner sep=3pt, circle, draw] at (4, 3) {};
\end{tikzpicture}
\end{document}

enter image description here

It works home with pdftex. I havent any trick to find the correct position ... except try and error ;-)

share|improve this answer
    
Seems to be the best looking solution so far, except the fact, that I have to position the arrows by try and error. Maybe someone knows a solution to this? –  tripplet Oct 11 '12 at 12:41
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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