11

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

enter image description here

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}

MWE

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}

enter image description here

2
  • 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. May 24, 2013 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, 2013 at 13:25

2 Answers 2

14

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

enter image description here

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.

5
  • Okay, I will try to integrate this in my code.
    – Josef
    May 24, 2013 at 15:17
  • Unfortunately, your solution doesn't survive the integration into logicpuzzle.sty. See my edit.
    – Josef
    May 24, 2013 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, 2013 at 12:19
  • You may use the code as you wish.
    – Frédéric
    May 25, 2013 at 13:02
  • No way! ;-) Thanks for your permission.
    – Josef
    May 25, 2013 at 21:16
12

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 (which is now on CTAN).

\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 no artefacts on the joins.

self intersecting lines

2
  • 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, 2013 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. May 27, 2013 at 15:44

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .