# TikZ: Calculate “pre length” based on path length

I would like to automatically calculate the pre length value for a line decoration to be "centered". Let me explain it by this example:

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

\begin{document}
\begin{tikzpicture}[foo/.style={decorate,decoration={
shape backgrounds,shape=circle,shape sep=2.5cm,pre=moveto,pre length=#1}}]
\node at (0cm,0cm)  [label=below:0]  {};
\node at (5cm,0cm)  [label=below:5]  {};
\node at (9cm,0cm)  [label=below:9]  {};
\node at (10cm,0cm) [label=below:10] {};
\draw[foo=0cm]    (0cm,0cm) -- (10cm,0cm); % line 1
\draw[foo=0cm]    (0cm,5mm) -- ( 9cm,5mm); % line 2
\draw[foo=0.75cm] (0cm,1cm) -- ( 9cm,1cm); % line 3
\end{tikzpicture}
\end{document}


(How can I add a compiled version of the code? Do I have to manually compile and upload it as a image?)

• line 1 (bottom) is what I want: Circles from the start of the line (0,0) to its end (10,0).
• line 2 (middle) shows the problem: If the paths length is not a multiple of shape sep, the first circle is at the paths start and there is nothing between the last circle and the paths end.
• line 3 (top) shows how the problem should be handled: By setting pre length to the right value (or by some other method, if you have a better idea), the distance between the paths start and the first circle is the same as the distance between the last circle and the paths end.

Now my question is: How can I set pre length to (path length - shape sep)/2(path length - (number of circles - 1) * shape sep) / 2 (thanks to Altermundus for the correction)? Or is there a better solution to this?

-
Yes, you have to manually compile and upload as image. If you use the standalone documentclass the PDF will be trimmed to the size of the tikzpicture, and you can upload the PDF directly. (Note however that Imgur converts it to PNG, and the quality of the conversion isn't always that good, so converting yourself, or taking a screenshot, may be better.) –  Torbjørn T. Apr 23 '12 at 14:16
You can also make the decoration circles more sparse or dense depending on the path length. Would you discard that option completely? –  percusse Apr 23 '12 at 14:22
@percusse Thanks, but then the problem would be to calculate shape sep. I want to use the foo style for multiple lines with variable lengths. –  siegi Apr 23 '12 at 14:25
Both can be done, you need to choose as you can see from midtiby's answer :) –  percusse Apr 23 '12 at 15:15
@percusse I choose the adjustment of pre length, but thanks again for your suggestion! :-) –  siegi Apr 23 '12 at 20:48

I'm not sure of my formula but (path length - shape sep)/2is not very fine. You can use some values like \pgfmetadecoratedpathlength and \pgf@lib@shapedecoration@sep.

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

\begin{document}
\makeatletter
\begin{tikzpicture}%
[foo/.style={decorate,
decoration={shape backgrounds,
shape=circle,
shape sep=2.5cm,
pre=moveto,
\pgf@lib@shapedecoration@sep)/2}}]
\node at (0cm,0cm)  [label=below:0]  {};
\node at (5cm,0cm)  [label=below:5]  {};
\node at (9cm,0cm)  [label=below:9]  {};
\node at (10cm,0cm) [label=below:10] {};
\draw[foo] (0cm,1cm) -- ( 9cm,1cm);
\end{tikzpicture}
\end{document}


-
Thanks, exactly what I was looking for! Of course your formula is right, I forgot to include the number of shapes, silly me… :-P –  siegi Apr 23 '12 at 20:53

Some time ago I made the illustration below that places evenly spaced lipid molecules along a path.

The central part is the access to \pgfdecoratedpathlength from which the distance between neighbouring molecules is calculated.

\documentclass{article}
\usepackage{tikz}
\usepackage{tikz}
\usetikzlibrary{decorations,decorations.pathreplacing}

\begin{document}

% Define decoration
\pgfdeclaredecoration{lipidleaflet}{initial}
{
% Place as many segments as possible along the path to decorate
% the minimum distance between two segments is set to 7 pt.
\state{initial}[width=\pgfdecoratedpathlength/floor(\pgfdecoratedpathlength/7pt)]
{
% Draw the two acyl chains
\pgfpathmoveto{\pgfpoint{-1pt}{0pt}}
\pgfpathlineto{\pgfpoint{-1pt}{-10pt}}
\pgfpathmoveto{\pgfpoint{1pt}{0pt}}
\pgfpathlineto{\pgfpoint{1pt}{-10pt}}
\pgfpathmoveto{\pgfpoint{1pt}{0pt}}
\pgfpathcircle{\pgfpoint{0pt}{2pt}}{2.5pt}
}
\state{final}
{
\pgfpathmoveto{\pgfpointdecoratedpathlast}
}
}

% Draw a vesicle composed of two lipid layers
\begin{tikzpicture}
% Micelle
\draw[decorate, decoration={lipidleaflet, mirror}] (0, 3) circle (0.6cm);
\draw (0, 2) node {Micelle};

% Inverted micelle
\draw[decorate, decoration={lipidleaflet}] (0, 0) circle (0.45cm);
\draw (0, -1) node {Inverted micelle};

% Lipid bilayer
\draw[decorate, decoration={lipidleaflet, mirror}]
(-1, -2.8) -- (2, -2.8);
\draw[decorate, decoration={lipidleaflet}]
(-1, -2) -- (2, -2);
\draw (0, -3.5) node {Lipid bilayer};

% Vesicle
\draw[decorate, decoration={lipidleaflet}] (5, 0.5) circle (2.5cm);
\draw[decorate, decoration={lipidleaflet, mirror}] (5, 0.5) circle (3.3cm);
\draw (5, -3.5) node {Vesicle};

\end{tikzpicture}

\end{document}

-
Looks very impressive, pointed me in the right direction and is for sure helpful to others - thanks! –  siegi Apr 23 '12 at 20:59