Crossing paths in TikZ without intersection

Once again, I'm preparing a new logic puzzle; Resuko to be precise.

For the race track, I would like to have a symbolized bridge/underbridge -|-. I searched this site, but only found this question: Intersection of 2 lines not really connected in TikZ

The answers there seem to indicate that there is no automatic solution for full paths. I'm quite sure, i have seen this, but maybe with PSTricks. Any ideas?

Edit:

Unfortunately, Frédéric's solution does not work after integration into logicpuzzle.sty. Some path construction must be supported, like trackpath in the following MWE:

\documentclass[border=5pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.pathreplacing}
\makeatletter
\tikzstyle{bridge path}=[rounded corners=10pt,decorate,decoration={show path construction,
lineto code={
\draw [white,line width = 4pt,double=red,double distance=4pt]
(\tikzinputsegmentfirst) -- (\tikzinputsegmentlast);},
curveto code={
\draw [red,line width = 4pt] (\tikzinputsegmentfirst) .. controls
(\tikzinputsegmentsupporta) and (\tikzinputsegmentsupportb)
..(\tikzinputsegmentlast);
}}]
\newcommand*\trackpath[3]%
{%
(#1.5,#2.5)%
\foreach \LP@direction in {#3}%
{%
\ifnum\LP@direction=1%
--++(-1,-1)%
\fi%
\ifnum\LP@direction=2%
--++(0,-1)%
\fi%
\ifnum\LP@direction=3%
--++(1,-1)%
\fi%
\ifnum\LP@direction=4%
--++(-1,0)%
\fi%
\ifnum\LP@direction=6%
--++(1,0)%
\fi%
\ifnum\LP@direction=7%
--++(-1,1)%
\fi%
\ifnum\LP@direction=8%
--++(0,1)%
\fi%
\ifnum\LP@direction=9%
--++(1,1)%
\fi%
};%
}%
%
\newcommand*\track[1]{
\draw[bridge path] #1;
}
\makeatother
\begin{document}
\begin{tikzpicture}
\track{\trackpath{0}{2}{6,2,2,4,8,6,6}}
\draw (0,0) grid[step=1] (3,3);
\end{tikzpicture}
\end{document}


Then, the decoration doesn't work any longer. :-( It works with a TikZ path, \trackpath seems to trigger the problem.

Any idea what's going wrong?

Edit2:

With Frédéric's idea to change the way how the path is constructed, we have a final solution:

\documentclass[border=5pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.pathreplacing}
\makeatletter
\tikzstyle{bridge path}=[rounded corners=10pt,decorate,decoration={show path construction,
lineto code={
\draw [white,line width = 4pt,double=red,double distance=4pt]
(\tikzinputsegmentfirst) -- (\tikzinputsegmentlast);},
curveto code={
\draw [red,line width = 4pt] (\tikzinputsegmentfirst) .. controls
(\tikzinputsegmentsupporta) and (\tikzinputsegmentsupportb)
..(\tikzinputsegmentlast);
}}]
\newcommand*\trackpath[3]%
{%
(#1.5,#2.5)%
\foreach \LP@dir/\LP@length in {#3}%
{%
\ifnum\LP@dir=2%
--++(0,-\LP@length)%
\fi%
\ifnum\LP@dir=4%
--++(-\LP@length,0)%
\fi%
\ifnum\LP@dir=6%
--++(\LP@length,0)%
\fi%
\ifnum\LP@dir=8%
--++(0,\LP@length)%
\fi%
};%
}%
%
\newcommand*\track[1]{
\draw[bridge path] #1;
}
\makeatother
\begin{document}
\begin{tikzpicture}
\track{\trackpath{0}{2}{6/1,2/2,4/1,8/1,6/2}}
\draw (0,0) grid[step=1] (3,3);
\end{tikzpicture}
\end{document}


• It seems to me that your picture would be best created by defining a series of individual 'tiles', called e.g. \curveNW, \curveSE, \straightWE, \straightNS, and so on, and then aligning these tiles in a grid. This would make your intersection problem go away, since you can just draw the bridge as three separate rectangles. – John Wickerson May 24 '13 at 13:04
• Yes, i already have these 'tiles'. They are needed as starters for the puzzle. Nevertheless, an automatic solution would be nice to have. – Josef May 24 '13 at 13:25

The basic idea is to use a double line, with a white border. The problem is the default way tikz draws this is to draw the path completely a first time (the white border) and then completely a second time. The way around this is to use a decoration, more specifically the "show path construction" decoration. This decorates the path piecewise.

The code is

\documentclass[border=5pt]{standalone}

\usepackage{tikz}
\usetikzlibrary{decorations.pathreplacing}

\tikzstyle{bridge path}=[rounded corners=10pt,decorate,decoration={show path construction,
lineto code={
\draw [white,line width = 4pt,double=red,double distance=4pt]
(\tikzinputsegmentfirst) -- (\tikzinputsegmentlast);},
curveto code={
\draw [red,line width = 4pt] (\tikzinputsegmentfirst) .. controls
(\tikzinputsegmentsupporta) and (\tikzinputsegmentsupportb)
..(\tikzinputsegmentlast);
}}]

\begin{document}

\begin{tikzpicture}

\draw[bridge path]
(0,2.5) -- (1.5,2.5) -- (1.5,0.5) -- (0.5,0.5)-- (0.5,1.5) -- (3,1.5);

\draw (0,0) grid[step=1] (3,3);

\end{tikzpicture}

\end{document}


The result is

Comment on Josef's comment that the code does not survive the integration into his style. From what I can tell, the problem occurs when one of the coordinates of the specified path is also one of the intersection points. I don't know why this occurs. As a quick fix, I would change the way the path is specified in Josef's edit: I would not say move left/right/up/down, but rather the give the coordinates of where the path curves (the corners). Maybe Andrew's code works better.

• Okay, I will try to integrate this in my code. – Josef May 24 '13 at 15:17
• Unfortunately, your solution doesn't survive the integration into logicpuzzle.sty. See my edit. – Josef May 24 '13 at 16:46
• Great analysis in your comment. After changing the way how the path is constructed everything works. As you know, the code should become part of logicpuzzle.sty. May I kindly ask you for a waiver based on the here used CC-Wiki to include your code and license it under LPPL? I will of course attribute you. – Josef May 25 '13 at 12:19
• You may use the code as you wish. – Frédéric May 25 '13 at 13:02
• No way! ;-) Thanks for your permission. – Josef May 25 '13 at 21:16

I was going to say that this is just what the knots TikZ library is for, except that in testing it then I found that it didn't cope well with rounded corners. Fortunately, it was a quick fix but it does mean you'd need the spath3.dtx file from TeX-SX Launchpad instead of CTAN (don't be fooled by the existence of knot.dtx or spath.dtx, you want spath3.dtx and no other).

\documentclass[border=5pt]{standalone}
%\url{http://tex.stackexchange.com/q/115923/86}
\usepackage{tikz}
\usetikzlibrary{knots}

\begin{document}

\begin{tikzpicture}
\begin{knot}[
consider self intersections=true,
flip crossing=1,
]
\strand[rounded corners=10pt,line width=4pt,red]
(0,2.5) -- (1.5,2.5) -- (1.5,0.5) -- (0.5,0.5)-- (0.5,1.5) -- (3,1.5);
\end{knot}
\draw (0,0) grid[step=1] (3,3);
\end{tikzpicture}
\end{document}


The underlying mechanism is similar to that in Frédéric's answer: to use the double option to draw the overlying line. However, rather than drawing the path in segments what this method does is to redraw the upper part in the vicinity of the intersection. This means that the rest of the path is drawn "whole" and so has to artefacts on the joins.

• Thanks for your effort, but as the code should become part of logicpuzzle.sty an off-CTAN package is no option. Of course it might be usefull for others. – Josef May 25 '13 at 12:21
• @Josef Fair enough, but the changes I made to make this work with my package seem reasonable ones to integrate into the package on CTAN so when I next upload an update then this will work with on-CTAN packages. – Loop Space May 27 '13 at 15:44