Modified /tikz/double that doesn't go all the way to the end of lines

I love using the double option to draw a line with a thicker, differently-coloured line underneath it.

However, quite often I have several of these lines meeting at a point. They are all separate lines, but then the thicker parts of the lines overlap the thinner parts and the effect is spoiled.

Ideally I'd like a modified version of the /tikz/double effect, which doesn't draw the thicker line at (say) the beginning and end 5% of the length of the curve. Is this possible? So the thinner, 'internal' line would be drawn as specified, but the thicker, 'underneath' line wouldn't be drawn for the entire length.

-
This should be possible by using a special arrow style where the "arrow heads" are just simple lines with the inner color. –  Martin Scharrer May 17 '11 at 18:56
So do arrow heads prevent the entire length of a line being drawn? I thought they were simply drawn on top of the line. –  Jamie Vicary May 17 '11 at 19:04
The line is shorten so that the arrow head fits in. It isn't simply drawn on top. There are also the shorten >/shorten < options to further shorten the line. There is the space arrow head which simply shortens the line. One problem I just figured out is that the arrow heads are drawn with the main color, not with the inner color. –  Martin Scharrer May 17 '11 at 19:10

An incomplete solution is as follows. It uses a preaction. There is a problem when the curve is not a collection of straight lines, but rather a bezier curve. In this case, the two lines that are drawn (preaction line and regular line) do not pass exactly by the same points (have a close look at the curved part of the picture below). The code is :

\documentclass{minimal}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}
\draw[red]
[preaction={draw,green,shorten >=2pt,shorten <=2pt,ultra thick}]
(0.5,0.5)--(0,1) -- (0,0) .. controls ++(1,0) and ++(0,-1) .. (1,1);
\end{tikzpicture}
\end{document}


The output is

-
Fantastic! Worked perfectly. In my scenario I have lots of Bezier curves, but the issue you describe seems minimal. –  Jamie Vicary May 17 '11 at 19:35
Actually, I can't see the issue you describe at all, not even in your example picture - can you post a bigger/thicker version? –  Jamie Vicary May 17 '11 at 19:36
@Jamie: If you exaggerate the shortening then you can see it (and it's clearer if you thicken the lines a bit as well). –  Andrew Stacey May 17 '11 at 20:22

Here's an alternative. It uses the same basic idea as Frederic's in that it replaces the doubling by a preaction (doubling really is just a preaction except for a little trickery to handle arrows). But instead of shortening the underlying path, it draws it on a background layer. The method of doing that is to encase the preaction path in a \pgfonlayer ... \endpgfonlayer sandwich. This requires a new key, which I've imaginatively called preaction on background layer. It has to go after the preaction has been defined as it encases the currently defined preaction in the appropriate commands - it can't act presumptively. Although I've put it in to its own style option, you'd want to be able to specify the colour and line width in a similar fashion to the double syntax. That wouldn't be hard to do.

Here's the code (with, for comparison, the original double, Frederic's version, and my version all in a row):

\documentclass{standalone}
\usepackage{tikz}

\pgfdeclarelayer{background}
\pgfsetlayers{background,main}

\makeatletter

\def\pgf@on@bglayer{\pgfonlayer{background}}

\tikzset{
preaction on background layer/.code={
\expandafter\def\expandafter\tikz@preactions\expandafter{\expandafter\pgf@on@bglayer\tikz@preactions\endpgfonlayer}
},
double behind/.style={
preaction={
draw,
red,
line width=8pt
},
preaction on background layer
}
}
\makeatother
\begin{document}
\begin{tikzpicture}
\foreach \ang in {45,90,...,360} {
\draw[line width=2pt,red,double=black,double distance=4pt] (0,0) -- (\ang:2);
}
\foreach \ang in {45,90,...,360} {
\draw[black,line width=4pt,preaction={line width=8pt,red,draw,shorten >=2pt,shorten <=2pt}] (5,0) -- ++(\ang:2);
}
\foreach \ang in {45,90,...,360} {
\draw[double behind,line width=4pt] (10,0) -- ++(\ang:2);
}
\end{tikzpicture}
\end{document}


And the result:

(Incidentally, Frederic's solution would have been my first choice as well, if it weren't for his remark about the curved lines being off.)

-