# Moving a point along a “multi-node path”

I would like to create a gif (as explained in this answer) of a point moving along a crooked "multi-node path". I would like this path to be specified as below: a sequence of nodes connected by edges. In the iteration I would like to specify nodes along this "multi-node path" as in node[pos=\n, above] {x}.

I have a solution but it's not easily scalable: if I want more nodes along the path I have to change it by hand. Also there is a problem with the window shifting up and down as the point moves along the path.

I could do this by having as many for loops as there are edges, and placing the node[pos=\n, above] {x} on the relevant edge every time, but I'd like to have a more generic solution where I don't have to know in advance how long the "multi-node path" will be, something like the following (which doesn't work):

\documentclass[tikz]{standalone}
\usepackage{tikz}
\usetikzlibrary{intersections}
\begin{document}

\foreach \n in {0,0.05,...,1} {
\begin{tikzpicture}
\draw[name path=mypath]
(0,0)   -- ++ (1,2)
-- ++ (1,.5)
-- ++ (1,-1)
-- ++ (1,0)
-- ++ (1,-4);
\draw (mypath) node [draw=black, fill=red, circle] {}
node [pos=\n, above] {x};
\end{tikzpicture}
}

\end{document}


My current solution is ugly :( :

\documentclass[tikz, border=.5cm]{standalone}
\usepackage{tikz}
\begin{document}

\foreach \n in {0,0.1,...,.9} {
\begin{tikzpicture}
\draw
(0,0)   -- node [circle, fill=red, draw=black, pos=\n, inner sep = 0, minimum size = 4pt] {} node [pos=\n, above] {x} ++ (1,2)
-- ++ (1,.5)
-- ++ (1,-1)
-- ++ (1,0)
-- ++ (1,-4);
\end{tikzpicture}
}

\foreach \n in {0,0.1,...,.9} {
\begin{tikzpicture}
\draw
(0,0)   -- ++ (1,2)
-- node [circle, fill=red, draw=black, pos=\n, inner sep = 0, minimum size = 4pt] {} node [pos=\n, above] {x} ++ (1,.5)
-- ++ (1,-1)
-- ++ (1,0)
-- ++ (1,-4);
\end{tikzpicture}
}

\foreach \n in {0,0.1,...,.9} {
\begin{tikzpicture}
\draw
(0,0)   -- ++ (1,2)
-- ++ (1,.5)
-- node [circle, fill=red, draw=black, pos=\n, inner sep = 0, minimum size = 4pt] {} node [pos=\n, above] {x} ++ (1,-1)
-- ++ (1,0)
-- ++ (1,-4);
\end{tikzpicture}
}

\foreach \n in {0,0.1,...,.9} {
\begin{tikzpicture}
\draw
(0,0)   -- ++ (1,2)
-- ++ (1,.5)
-- ++ (1,-1)
-- node [circle, fill=red, draw=black, pos=\n, inner sep = 0, minimum size = 4pt] {} node [pos=\n, above] {x} ++ (1,0)
-- ++ (1,-4);
\end{tikzpicture}
}

\foreach \n in {0,0.1,...,.9} {
\begin{tikzpicture}
\draw
(0,0)   -- ++ (1,2)
-- ++ (1,.5)
-- ++ (1,-1)
-- ++ (1,0)
-- node [circle, fill=red, draw=black, pos=\n, inner sep = 0, minimum size = 4pt] {} node [pos=\n, above] {x} ++ (1,-4);
\end{tikzpicture}
}

\begin{tikzpicture}
\draw
(0,0)   -- ++ (1,2)
-- ++ (1,.5)
-- ++ (1,-1)
-- ++ (1,0)
-- node [circle, fill=red, draw=black, pos=1, inner sep = 0, minimum size = 4pt] {} node [pos=1, above] {x} ++ (1,-4);
\end{tikzpicture}

\end{document}


Use decorations.markings and the overlay option. The overlay option pretends that the object has zero size and therefore doesn't add to the bounding box. Because the nodes are now going outside the bounding box of the path, you have to add a border around the drawing so it doesn't fall off the page.

\documentclass[tikz,border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.markings}
\begin{document}

\foreach \n in {0,0.05,...,1} {
\begin{tikzpicture}
\draw
[postaction=decorate,
decoration={
markings,
mark=at position \n with {
\draw [overlay, draw=black, fill=red] circle (2pt);
\node [overlay, above] {x};
}
}]
(0,0)   -- ++ (1,2)
-- ++ (1,.5)
-- ++ (1,-1)
-- ++ (1,0)
-- ++ (1,-4);
\end{tikzpicture}
}

\end{document}


Very similar to Henri Menke's great answer with a small tilt: the bounding box gets recorded and the maximal bounding box of all iterations gets applied. You need to compile twice that it works. The code is more complex but the bounding box gets only increased in the directions in which it is needed. This code is somewhat similar to this nice answer which addresses a similar problem.

\documentclass[tikz]{standalone}
\usetikzlibrary{decorations.markings,calc}
\begin{document}
\pgfmathsetmacro{\xmin}{0}
\pgfmathsetmacro{\xmax}{0}
\pgfmathsetmacro{\ymin}{0}
\pgfmathsetmacro{\ymax}{0}
\foreach \X in {0,0.05,...,1} {
\begin{tikzpicture}
\ifdefined\figbb\relax
\path \figbb;
\fi
\draw
[postaction=decorate,
decoration={
markings,
mark=at position \X with {
\node [circle,inner sep=2pt,draw,fill=red,label=above:$x$]{};
}
}]
(0,0)   -- ++ (1,2)
-- ++ (1,.5)
-- ++ (1,-1)
-- ++ (1,0)
-- ++ (1,-4);
\path let \p1=(current bounding box.south west),
\p2=(current bounding box.north east)
in \pgfextra{%
\pgfmathsetmacro{\xmin}{min(\x1,\xmin)}
\pgfmathsetmacro{\xmax}{max(\x2,\xmax)}
\pgfmathsetmacro{\ymin}{min(\y1,\ymin)}
\pgfmathsetmacro{\ymax}{max(\y2,\ymax)}
\xdef\xmin{\xmin pt}
\xdef\xmax{\xmax pt}
\xdef\ymin{\ymin pt}
\xdef\ymax{\ymax pt}
};
\end{tikzpicture}
}
\makeatletter
\edef\figbb{(\xmin,\ymin) rectangle (\xmax,\ymax)}
\immediate\write\@mainaux{\xdef\string\figbb{\figbb}\relax}
\makeatother
\end{document}