[Tex/LaTex] TikZ: double line, one dashed

tikz-pgf

I'd like to draw a double line between two nodes; one of the two lines in the double should be solid and one dashed. I'd prefer not to have to manually shift one of the lines, but maybe this is the only way? If so, is there an easy way to do that, without some tedious angle calculations?

Best Answer

Double line with clipping

The following example draws first a dashed double line between the nodes. Then it clips the lower part and draws a solid double line overprinting the lower dashed line. Since my PDF viewer shows some artifacts at some zoom levels, the inner area is filled with white again.

\documentclass{article}
\usepackage{tikz}

\begin{document}
  \begin{tikzpicture}
    \node (A) at (0, 0) {A};
    \node (B) at (3, 1) {B};
    \draw[double, dashed] (A) -- (B);
    \begin{scope}
      \clip (current bounding box.south west) --
            (A.center) -- (B.center) --
            (current bounding box.south east) -- cycle;
      \draw[double] (A) -- (B);
    \end{scope}
    \draw[
      white,
      line width=0.6pt, % default double distance
      shorten <=-.1pt,
      shorten >=-.1pt,
    ] (A) -- (B);
    % removes some leftover artifacts in the middle
  \end{tikzpicture}
\end{document}

Result

Decoration

The following example implements the double line via the decoration interface. It's one of my first tries, thus there are some restrictions:

  • Only straight unconnected line segments are supported.
  • cycle does not work.
  • The line segments should not be too short.

But is also implements a feature for dashed lines, AFAIK missing in TikZ:

  • The dashed lines start and ends with the solid phase.

Example file:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{decorations}

\pgfdeclaredecoration{dashsoliddouble}{initial}{
  \state{initial}[width=\pgfdecoratedinputsegmentlength]{
    \pgfmathsetlengthmacro\lw{.3pt+.5\pgflinewidth}
    \begin{pgfscope}
      \pgfpathmoveto{\pgfpoint{0pt}{\lw}}%
      \pgfpathlineto{\pgfpoint{\pgfdecoratedinputsegmentlength}{\lw}}%
      \pgfmathtruncatemacro\dashnum{%
        round((\pgfdecoratedinputsegmentlength-3pt)/6pt)
      }
      \pgfmathsetmacro\dashscale{%
        \pgfdecoratedinputsegmentlength/(\dashnum*6pt + 3pt)
      }
      \pgfmathsetlengthmacro\dashunit{3pt*\dashscale}
      \pgfsetdash{{\dashunit}{\dashunit}}{0pt}
      \pgfusepath{stroke}
      \pgfsetdash{}{0pt}
      \pgfpathmoveto{\pgfpoint{0pt}{-\lw}}%
      \pgfpathlineto{\pgfpoint{\pgfdecoratedinputsegmentlength}{-\lw}}%     
      \pgfusepath{stroke}
    \end{pgfscope}
  }
}

\begin{document}
  \begin{tikzpicture}
    \node (A) at (0, 0) {A};
    \node (B) at (3, 1) {B};
    \node (C) at (3, 2) {C};
    \node (D) at (1, 2) {D};
    \draw[decoration={dashsoliddouble}, decorate]
      (A) -- (B) -- (C) -- (D) -- (A)
    ;
  \end{tikzpicture}
\end{document}

Result