[Tex/LaTex] Coil path decoration without straight segment

decorationspathstikz-pgf

When a path is decorated in TikZ, a straight line segment might be added at the end, depending on the length of the path. This is undesirable in some cases, and a very nice versatile resolution for the snake decoration has appeared in this question.

I would like get the same behavior for a coil decoration. That is, I would like TikZ to adjust the wavelength so that a straight line segment is avoided at the end of a coiled path. The option to start the path going in either direction would also be desirable.

My motivation is to avoid ugliness like the one in the gluon lines here.

Best Answer

Edit 2: Adapted code using \makeatletter and \makeatother to avoid the bad practice of midifying a package's file.

Edit: Changed code to make the coils end at the middle of the line.

If I understand correctly, you can get the result you are looking for by changing the predefined coil decoration. Although, the solution I propose is not prefect. The problem is that you need to change the segment length value a little bit to avoid too much (or too little) space at the end of the coil. Here are some examples, the blue coils correspond to the modified decoration:

enter image description here

\documentclass{article}

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

\makeatletter

% gluon decoration (based on the original coil decoration)

\pgfdeclaredecoration{gluon}{coil}
{
  \state{coil}[switch if less than=%
    0.5\pgfdecorationsegmentlength+%>
    \pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude+%
    \pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude to last,
               width=+\pgfdecorationsegmentlength]
  {
    \pgfpathcurveto
    {\pgfpoint@oncoil{0    }{ 0.555}{1}}
    {\pgfpoint@oncoil{0.445}{ 1    }{2}}
    {\pgfpoint@oncoil{1    }{ 1    }{3}}
    \pgfpathcurveto
    {\pgfpoint@oncoil{1.555}{ 1    }{4}}
    {\pgfpoint@oncoil{2    }{ 0.555}{5}}
    {\pgfpoint@oncoil{2    }{ 0    }{6}}
    \pgfpathcurveto
    {\pgfpoint@oncoil{2    }{-0.555}{7}}
    {\pgfpoint@oncoil{1.555}{-1    }{8}}
    {\pgfpoint@oncoil{1    }{-1    }{9}}
    \pgfpathcurveto
    {\pgfpoint@oncoil{0.445}{-1    }{10}}
    {\pgfpoint@oncoil{0    }{-0.555}{11}}
    {\pgfpoint@oncoil{0    }{ 0    }{12}}
  }
  \state{last}[next state=final]
  {
    \pgfpathcurveto
    {\pgfpoint@oncoil{0    }{ 0.555}{1}}
    {\pgfpoint@oncoil{0.445}{ 1    }{2}}
    {\pgfpoint@oncoil{1    }{ 1    }{3}}
    \pgfpathcurveto
    {\pgfpoint@oncoil{1.555}{ 1    }{4}}
    {\pgfpoint@oncoil{2    }{ 0.555}{5}}
    {\pgfpoint@oncoil{2    }{ 0    }{6}}
  }
  \state{final}{}
}

\def\pgfpoint@oncoil#1#2#3{%
  \pgf@x=#1\pgfdecorationsegmentamplitude%
  \pgf@x=\pgfdecorationsegmentaspect\pgf@x%
  \pgf@y=#2\pgfdecorationsegmentamplitude%
  \pgf@xa=0.083333333333\pgfdecorationsegmentlength%
  \advance\pgf@x by#3\pgf@xa%
}

\makeatother

\begin{document}

\begin{tikzpicture}
  \node (a) at (0,0) {A};
  \node (b) at (2,0) {B};
  \path (a) edge[decorate,decoration={coil, amplitude=4pt,
    segment length=5pt}] (b);
\end{tikzpicture}

\begin{tikzpicture}
  \node (a) at (0,0) {A};
  \node (b) at (2,0) {B};
  \path (a) edge[color=blue,decorate,decoration={gluon, amplitude=4pt,
    segment length=5.25pt}] (b);
\end{tikzpicture}

\begin{tikzpicture}
  \node (a) at (0,0) {A};
  \node (b) at (2,0) {B};
  \path (a) edge[decorate,decoration={coil, amplitude=4pt,
    segment length=5pt, aspect=0}] (b);
\end{tikzpicture}

\begin{tikzpicture}
  \node (a) at (0,0) {A};
  \node (b) at (2,0) {B};
  \path (a) edge[color=blue,decorate,decoration={gluon, amplitude=4pt,
    segment length=5.2pt, aspect=0}] (b);
\end{tikzpicture}

\begin{tikzpicture}
  \node (a) at (0,0) {A};
  \node (b) at (3.5,0) {B};
  \path (a) edge[decorate,decoration={coil, amplitude=4pt,
    segment length=5pt}] (b);
\end{tikzpicture}

\begin{tikzpicture}
  \node (a) at (0,0) {A};
  \node (b) at (3.5,0) {B};
  \path (a) edge[color=blue,decorate,decoration={gluon, amplitude=4pt,
    segment length=5.25pt}] (b);
\end{tikzpicture}

\begin{tikzpicture}
  \node (a) at (0,0) {A};
  \node (b) at (3.5,0) {B};
  \path (a) edge[decorate,decoration={coil, amplitude=4pt,
    segment length=5pt, aspect=0}] (b);
\end{tikzpicture}

\begin{tikzpicture}
  \node (a) at (0,0) {A};
  \node (b) at (3.5,0) {B};
  \path (a) edge[color=blue,decorate,decoration={gluon, amplitude=4pt,
    segment length=4.9pt, aspect=0}] (b);
\end{tikzpicture}

\end{document}