12

Until I upgraded to TeX Live 2021, I was very happy with Mark Wibrow's train tracks. However, under TeX Live 2021, I get very strange behavior; the code from his answer now typesets as the following.

Broken railway tracks

I get similarly strange behavior with cfr's version of the tracks.

Different broken railway tracks

I've tested the tracks on both TeX Live 2019 and 2020, and they are fine. How can I update this code to work with TeX Live 2021?

3
  • 1
    Looks like the first example has strange behavior with xelatex in TeX Live 2018, 2019, 2020, and 2021.
    – citsahcots
    Jul 10, 2021 at 16:03
  • 5
    It seems Mark Wibrow's code relied on a typo in pgf's driver, which has been fixed since v3.1.6a (Sep 29, 2020). On the other way, I found the problem is that, in env tikzfadingfrompicture,\pgfsetpath\pgfdecoratedpath gets the last, not the "current" path. Jul 10, 2021 at 17:01
  • A nitpick: railroad ties don't cross like that on a junction. Instead, unifying wider ties should be used near the junction point.
    – andselisk
    Jul 11, 2021 at 7:11

1 Answer 1

13

As mentioned in the comment of muzimushi the old code depended on a typo which forced pgf to resave the fadings. You can get a similar effect by using a counter:

\documentclass[tikz, border=5]{standalone}
\usetikzlibrary{decorations,fit,fadings}
\newcounter{tracks}
% Layers
\pgfdeclarelayer{sleeper}
\pgfdeclarelayer{rail}
\pgfsetlayers{sleeper,rail,main}

\pgfdeclaredecoration{tracks}{final}{%
\state{final}{%
  \pgftransformreset% <- I think is possibly vital.
  %
  % Get bounding box of decorated path as a node.
  % Must do it this way using basic layer.
  \pgftransformshift{\pgfpointanchor{current path bounding box}{south west}}%
  \pgfcoordinate{@1}\pgfpointorigin%
  \pgftransformshift{\pgfpointanchor{current path bounding box}{north east}}%
  \pgfcoordinate{@2}\pgfpointorigin%
  \node [fit=(@1)(@2), inner sep=\railsep+2*\railwidth] (@@) {};
  %
  % Create a fading for the track.
  \pgfinterruptpicture%
    \stepcounter{tracks}% 
    \begin{tikzfadingfrompicture}[name=tracks\thetracks]
    \path[draw=transparent!0, line width=\railsep+2*\railwidth,
     postaction={draw=transparent!100, line width=\railsep}]
      \pgfextra{\pgfsetpath\pgfdecoratedpath};
    \useasboundingbox (@@.south west) (@@.north east);
  \end{tikzfadingfrompicture}%
  \endpgfinterruptpicture
  %
  % Draw sleepers.
  \ifx\sleeperlayer\emptylayer\else\pgfonlayer{\sleeperlayer}\fi%
  \draw [draw=\sleepercolor,line width=\sleeperlength, dash pattern=on \sleeperwidth off \sleepersep, every sleeper/.try]
    \pgfextra{\pgfsetpath\pgfdecoratedpath};
  \ifx\sleeperlayer\emptylayer\else\endpgfonlayer\fi%
  %
  % Draw the track
  \ifx\raillayer\emptylayer\else\pgfonlayer{\raillayer}\fi%
  \fill [path fading=tracks\thetracks, fit fading=false,
    fading transform={shift=(@@.center)}, fill=\railcolor]
   (@@.south west) rectangle (@@.north east);
   \ifx\raillayer\emptylayer\else\endpgfonlayer\fi%
}
}
\def\emptylayer{}
\tikzset{%
  track/.style={
    decoration=tracks, decorate
  },
  decorations/.cd,
    rail sep/.store in=\railsep,
    rail width/.store in=\railwidth,
    rail color/.store in=\railcolor,
    rail layer/.store in=\raillayer,
    sleeper sep/.store in=\sleepersep,
    sleeper width/.store in=\sleeperwidth,
    sleeper length/.store in=\sleeperlength,
    sleeper color/.store in=\sleepercolor,
    sleeper layer/.store in=\sleeperlayer,
    rail sep=4pt,
    rail width=1pt,
    rail color=black,
    rail layer=rail,
    sleeper sep=6pt,
    sleeper width=1pt,
    sleeper length=10pt,
    sleeper color=gray,
    sleeper layer=sleeper,
}
\begin{document}
\begin{tikzpicture}
\draw [track] (-2,5) to (0,5) to[out=  0,in=270] (2,8);
\draw [track] (6,5) to (4,5) to[out=180,in=270] (2,8) to (2,10);
\end{tikzpicture}
\end{document} 

enter image description here

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.