Draw a longitudinal wave in TikZ

It seems that if there isn't room for a complete loop, the path will be finished with a straight line. By making a slight change in the endpoint for the first path, the result is better. Also, to make the loop continous, and not turn around at the midpoint, you can make the amplitude negative for the second and third path.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{decorations.pathmorphing}
\begin{document} 

\begin{tikzpicture}[decoration={coil}]

\draw[decorate, decoration={aspect=0.3, segment length=3mm, amplitude=3mm}] (0,0) --(3.03,0);
\draw[decorate, decoration={aspect=0.3, segment length=0.5mm, amplitude=-3mm}] (3.03,0) -- (3.49,0); 
\draw[decorate, decoration={aspect=0.3, segment length=3mm, amplitude=-3mm}] (3.48,0) -- (4.98,0);

\end{tikzpicture}
\end{document}

enter image description here


Here's an alternative to using decorations which gives you a little more control (though I should say at the outset that I think that the more stylised version from the decoration actually looks neater). I recently found myself wanting to draw a helix and so adapted the code for arcs to allow for a transversal shift as it draws the arc. By varying the shift, I can get a longitudinal wave. The code looks a bit complicated, but it is a very simple adaptation of the code for arcs (and of course it could be hidden away in a package!).

Here's the result first:

longitudinal wave

If the horrible code were in a package, this is what you would write to get that:

\documentclass{standalone}
\usepackage{tikz}
\usepackage{helix}
\begin{document}
\def\gxhelix{0}
\begin{tikzpicture}
\foreach \sep in {0,10,...,360} {
\pgfmathsetmacro{\rsep}{3*cos(\sep)^2}
\helical[.3*\rsep]{\xhelix}{360}
\draw[blue,helix=.3*\rsep]
 (\gxhelix,0,0)
 arc[radius=1,
   start angle=90,
   delta angle=360,
   y={(0,1,0)},
   x={(0,0,-1)}];
\pgfmathsetmacro{\gxhelix}{\xhelix + \gxhelix}
\global\let\gxhelix=\gxhelix
}
\end{tikzpicture}
\end{document}

The helix key replaces the arc macro with the modified one and sets the shift factor in the helix. So by varying that, we can get the wave-like behaviour. The \helical macro is a shortcut for computing the shift factor so that each cycle starts at the right place from the previous.

The horrible code is the following:

\makeatletter
\pgfutil@tempdima=1cm
\pgfmathsetmacro{\pgf@helix@factor}{\the\pgfutil@tempdima}
\pgfkeys{
  /tikz/helix/.default={1},
  /tikz/helix/.code={
    \let\pgf@arc=\pgf@helix
    \pgfmathsetmacro{\pgf@helix@st}{#1*\pgf@helix@factor/360}
  }
}

% convert an angle into a helical distance
\newcommand{\helical}[3][1]{%
  \pgfmathsetmacro{#2}{#1*(#3)/360}%
}

\newdimen\pgf@helix@len
\def\pgf@helix{%
  {%
  \pgfutil@tempdima=\pgf@arc@radius@a pt%
  \pgfutil@tempdimb=\pgf@arc@radius@b pt%
  %
  \pgf@xa=\pgf@arc@local@angle@a\relax% 
  \pgf@xb=\pgf@arc@local@angle@b\relax%
  \advance\pgf@xb by-\pgf@xa\relax%
  \ifdim\pgf@xb<0pt\relax%
    \pgf@xb=-\pgf@xb\relax%
  \fi%
  \ifdim\pgf@xb=90.0pt%
    \def\pgfmathresult{0.55228475}%
  \else%
    \pgfmathparse{1.333333333*tan(.25*\pgf@sys@tonumber{\pgf@xb})}% many thanks to Ken Starks
  \fi%
    \pgf@helix@len=\pgf@helix@st\pgf@xb\relax
  \pgfutil@tempdima=\pgfmathresult\pgfutil@tempdima%
  \pgfutil@tempdimb=\pgfmathresult\pgfutil@tempdimb%
  %.. controls +(\pgf@xa+90:\pgfutil@tempdima) and +(\pgf@xb-90:\pgfutil@tempdima) .. +(-(#1:#3)+(#2:#3))%
  % store first support vector in xa/ya:
  \pgf@xa=\pgf@arc@local@angle@a\relax%
  \ifdim\pgf@arc@local@angle@b>\pgf@arc@local@angle@a\relax%
    \advance\pgf@xa by 90pt\relax%
  \else%
    \advance\pgf@xa by -90pt\relax%
  \fi%
  \edef\pgf@arc@angle{\pgf@sys@tonumber{\pgf@xa}}%  
  \pgfpointtransformed{\pgfpointpolar{\pgf@arc@angle}{\pgfutil@tempdima and \pgfutil@tempdimb}}%
  \advance\pgf@x by-\pgf@pt@x%
  \advance\pgf@y by-\pgf@pt@y%
  \pgf@xa=\pgf@path@lastx%
  \pgf@ya=\pgf@path@lasty%
  \advance\pgf@xa by \pgf@x%
  \advance\pgf@ya by \pgf@y%
  % store target in xb/yb:
  \pgfpointtransformed{\pgfpointpolar{\pgf@sys@tonumber{\pgf@arc@local@angle@a}}{\pgf@arc@radius@a pt and \pgf@arc@radius@b pt}}%
  \pgf@xb=\pgf@path@lastx%
  \pgf@yb=\pgf@path@lasty%
  \advance\pgf@xb by -\pgf@x%
  \advance\pgf@yb by -\pgf@y%
  \pgfpointtransformed{\pgfpointpolar{\pgf@sys@tonumber{\pgf@arc@local@angle@b}}{\pgf@arc@radius@a pt and \pgf@arc@radius@b pt}}%
  \advance\pgf@xb by \pgf@x%
  \advance\pgf@yb by \pgf@y%
  % store second support xc/yc:
  \ifdim\pgf@arc@local@angle@b>\pgf@arc@local@angle@a\relax%
    \advance\pgf@arc@local@angle@b by -90pt\relax%
  \else%
    \advance\pgf@arc@local@angle@b by 90pt\relax%
  \fi%
  \pgfpointtransformed{\pgfpointpolar{\pgf@sys@tonumber{\pgf@arc@local@angle@b}}{\pgfutil@tempdima and \pgfutil@tempdimb}}%
  \advance\pgf@x by-\pgf@pt@x%
  \advance\pgf@y by-\pgf@pt@y%
  \pgf@xc=\pgf@xb\relax%
  \pgf@yc=\pgf@yb\relax%
  \advance \pgf@xc by \pgf@x\relax%
  \advance \pgf@yc by \pgf@y\relax%
    \advance\pgf@xa by .3333333\pgf@helix@len\relax
    \advance\pgf@xc by .6666666\pgf@helix@len\relax
    \advance\pgf@xb by \pgf@helix@len\relax
  \pgfsyssoftpath@curveto{\the\pgf@xa}{\the\pgf@ya}{\the\pgf@xc}{\the\pgf@yc}{\the\pgf@xb}{\the\pgf@yb}%
  \global\pgf@path@lastx=\pgf@xb%
  \global\pgf@path@lasty=\pgf@yb%
  \pgf@protocolsizes{\pgf@xa}{\pgf@ya}%
  \pgf@protocolsizes{\pgf@xb}{\pgf@yb}%
  \pgf@protocolsizes{\pgf@xc}{\pgf@yc}%
  }%
}
\makeatother

This question can be generalized to the question

How can one deform an existing decoration?

One answer is

As usual, i.e. with nonlinear transformations.

Example (using the \flagtransformation with the roles of x and y reversed):

\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{decorations.pathmorphing}
\usepgfmodule{nonlineartransformations}
\makeatletter
\def\nltrafo{%
\pgfmathsetmacro{\myx}{\pgf@x+7*sin(\pgf@x*3.6)}%
\pgf@x=\myx pt}
\makeatother
\begin{document}  
\begin{tikzpicture}
\begin{scope}[transform shape nonlinear=true]
 \pgftransformnonlinear{\nltrafo}
 \draw[decorate, decoration={coil,aspect=0.3, segment length=2mm, amplitude=3mm}]
 (0,0) --(10,0);
 \draw[decorate, decoration={coil,aspect=0, segment length=2mm, amplitude=3mm}]
 (0,-2) --(10,-2);
\end{scope}
\end{tikzpicture}
\end{document}

enter image description here

As you can see, this works for arbitrary transformations, and the change of frequencies is a smooth function (\pgf@x+7*sin(\pgf@x*3.6)).

A more fancy example using the 3d coil decoration (actually this is a version that works but got deleted; if you want to know why it got deleted you need to ask someone else; this code is lengthy because the 3d coil definitions, the deformation is very short):

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{decorations.pathmorphing}
\usepgfmodule{nonlineartransformations}
\makeatletter
\def\nltrafo{%
\pgfmathsetmacro{\myx}{\pgf@x+7*sin(\pgf@x*3.6)}%
\pgf@x=\myx pt}
\newif\ifcoil@closed
\pgfkeys{%
/pgf/decoration/.cd,
3d coil color/.store in=\TDCoilColor, 
3d coil color/.initial=black,
3d coil color=black,
3d coil width/.store in=\TDCoilWidth, 
3d coil width/.initial=0.4pt,
3d coil width=0.4pt,
3d coil dist/.store in=\TDCoilDist, 
3d coil dist/.initial=0.6pt,
3d coil dist=0.6pt,
3d coil opacity/.store in=\TDCoilOpacity, 
3d coil opacity/.initial=1,
3d coil opacity=1,
3d coil closed/.code=\coil@closedtrue
}

 % https://tex.stackexchange.com/a/219088/121799
\tikzset{get stroke color/.code={%
    \expandafter\global% Jump over, now we have \global
    \expandafter\let% Jump over now we have \global\let
    \expandafter\pgfsavedstrokecolor% Jump we have \global\let\pgf...
    \csname\string\color@pgfstrokecolor\endcsname% Finally expand this and put it at the end 
    },                                           % \global\let\pgf...{} in expanded form 
    restore stroke color/.code={\pgf@setstrokecolor#1},
}
\def\pgfpoint@onthreedcoil#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%
  \advance\pgf@x by-\generaloffset pt%
}

% coil decoration
%
% Parameters: \pgfdecorationsegmentamplitude, \pgfdecorationsegmentlength,

\pgfdeclaredecoration{3d complete coil}{initial}
{ 
    \state{initial}[width=0.5*\pgfdecorationsegmentlength,
    next state=coil, persistent precomputation={% from https://tex.stackexchange.com/a/25689/121799
    \pgfmathsetmacro\matchinglength{\pgfdecoratedinputsegmentlength / int(\pgfdecoratedinputsegmentlength/\pgfdecorationsegmentlength)}
    \setlength{\pgfdecorationsegmentlength}{\matchinglength pt}
    \tikzset{get stroke color}
    \pgfmathsetmacro{\generaloffset}{\pgfdecorationsegmentlength}
    \pgfmathsetmacro{\initialoffset}{1.5*\pgfdecorationsegmentlength}
    \pgfmathsetmacro{\auxoffset}{2.5*\pgfdecorationsegmentlength}
  }]    { 
    % line in the back
    %
    \pgfsetstrokecolor{\TDCoilColor}
    \pgfsetfillcolor{\TDCoilColor}
    \pgfsetstrokeopacity{\TDCoilOpacity}
    \pgfsetlinewidth{\TDCoilWidth}     
    \ifcoil@closed
     \begingroup
      \def\generaloffset{\auxoffset}
      \pgfpathmoveto{\pgfpoint@onthreedcoil{1    }{ 1    }{15}}
      \pgfpathcurveto
      {\pgfpoint@onthreedcoil{1.555}{ 1    }{16}}
      {\pgfpoint@onthreedcoil{2    }{ 0.555}{17}}
      {\pgfpoint@onthreedcoil{2    }{ 0    }{18}}
      \pgfcoordinate{TD@coilast}{\pgfpoint@onthreedcoil{2    }{ 0    }{18}}
      \pgfcoordinate{TD@coilfirst}{\pgfpoint@onthreedcoil{1    }{ 1    }{15}}
      \pgfusepath{stroke} 
      \pgfsetstrokecolor{\TDCoilColor}
     \endgroup
    \fi
    \begingroup %
    \def\generaloffset{\initialoffset}
    \ifcoil@closed
     \pgfpathmoveto{\pgfpointanchor{TD@coilast}{center}}
    \else
     \pgfpathmoveto{\pgfpointorigin}
    \fi
    \pgfpathcurveto
    {\pgfpoint@onthreedcoil{2    }{-0.555}{7}}
    {\pgfpoint@onthreedcoil{1.555}{-1    }{8}}
    {\pgfpoint@onthreedcoil{1    }{-1    }{9}}
    \pgfusepath{stroke} 
    %
    % white background for front thick part
    %
    \pgfsetstrokeopacity{1}
    \pgfsetstrokecolor{white}
    \pgfsetfillcolor{white}
    \pgfsetlinewidth{1.5*\TDCoilWidth+1.5*\TDCoilDist}
    \pgfpathmoveto{\pgfpoint@onthreedcoil{1    }{-1    }{9}}
    % draw forward
    \pgfpathcurveto
    {\pgfpoint@onthreedcoil{0.445}{-1    }{10}}
    {\pgfpoint@onthreedcoil{0    }{-0.555}{11.25}}
    {\pgfpoint@onthreedcoil{0    }{ 0    }{12.5}}
    \pgfpathcurveto
    {\pgfpoint@onthreedcoil{0    }{ 0.555}{13.25}}
    {\pgfpoint@onthreedcoil{0.445}{ 1    }{14.25}}
    {\pgfpoint@onthreedcoil{1    }{ 1    }{15}}
    % draw the curve back
    \pgfpathcurveto
    {\pgfpoint@onthreedcoil{0.445}{ 1    }{14}}
    {\pgfpoint@onthreedcoil{0    }{ 0.555}{12.75}}
    {\pgfpoint@onthreedcoil{0    }{ 0    }{11.5}}
    \pgfpathcurveto
    {\pgfpoint@onthreedcoil{0    }{-0.555}{10.75}}
    {\pgfpoint@onthreedcoil{0.445}{-1    }{10}}
    {\pgfpoint@onthreedcoil{1    }{-1    }{9}}
    \pgfusepath{stroke,fill} 
    % 
    % draw the thick foreground path
    %
    \pgfsetstrokecolor{\TDCoilColor}
    \pgfsetfillcolor{\TDCoilColor}
    \pgfsetstrokeopacity{\TDCoilOpacity}
    \pgfpathmoveto{\pgfpoint@onthreedcoil{1    }{ 1    }{3}}
    \pgfsetlinewidth{\TDCoilWidth} 
    % forward shifted +
    \pgfpathmoveto{\pgfpoint@onthreedcoil{1    }{-1    }{9}}
    \pgfpathcurveto
    {\pgfpoint@onthreedcoil{0.445}{-1    }{10}}
    {\pgfpoint@onthreedcoil{0    }{-0.555}{11.25}}
    {\pgfpoint@onthreedcoil{0    }{ 0    }{12.5}}
    \pgfpathcurveto
    {\pgfpoint@onthreedcoil{0    }{ 0.555}{13.25}}
    {\pgfpoint@onthreedcoil{0.445}{ 1    }{14.25}}
    {\pgfpoint@onthreedcoil{1    }{ 1    }{15}}
    % draw the curve back shfted -
    \pgfpathcurveto
    {\pgfpoint@onthreedcoil{0.445}{ 1    }{14}}
    {\pgfpoint@onthreedcoil{0    }{ 0.555}{12.75}}
    {\pgfpoint@onthreedcoil{0    }{ 0    }{11.5}}
    \pgfpathcurveto
    {\pgfpoint@onthreedcoil{0    }{-0.555}{10.75}}
    {\pgfpoint@onthreedcoil{0.445}{-1    }{10}}
    {\pgfpoint@onthreedcoil{1    }{-1    }{9}}
    \pgfusepath{stroke,fill} 
    \pgfpathmoveto{\pgfpoint@onthreedcoil{1    }{ 1    }{15}}
    \pgfpathcurveto
    {\pgfpoint@onthreedcoil{1.555}{ 1    }{16}}
    {\pgfpoint@onthreedcoil{2    }{ 0.555}{17}}
    {\pgfpoint@onthreedcoil{2    }{ 0    }{18}}
    \pgfcoordinate{TD@coilast}{\pgfpoint@onthreedcoil{2    }{ 0    }{18}} 
    \pgfusepath{stroke}     
    \endgroup
  }
  \state{coil}[switch if less than=%
    1.9*\pgfdecorationsegmentlength  to last,
               width=+\pgfdecorationsegmentlength]
    { % line in the back
    %
    \pgfsetstrokecolor{\TDCoilColor}
    \pgfsetfillcolor{\TDCoilColor}
    \pgfsetstrokeopacity{\TDCoilOpacity}
    \pgfpathmoveto{\pgfpointanchor{TD@coilast}{center}}
    \pgfsetlinewidth{\TDCoilWidth} 
    \pgfpathcurveto
    {\pgfpoint@onthreedcoil{2    }{-0.555}{7}}
    {\pgfpoint@onthreedcoil{1.555}{-1    }{8}}
    {\pgfpoint@onthreedcoil{1    }{-1    }{9}}
    \pgfusepath{stroke} 
    %
    % white background for front thick part
    %
    \pgfsetstrokeopacity{1}
    \pgfsetstrokecolor{white}
    \pgfsetfillcolor{white}
    \pgfsetlinewidth{1.5*\TDCoilWidth+1.5*\TDCoilDist}
    \pgfpathmoveto{\pgfpoint@onthreedcoil{1    }{ 1    }{3}}
    \pgfpathmoveto{\pgfpoint@onthreedcoil{1    }{-1    }{9}}
    % draw forward
    \pgfpathcurveto
    {\pgfpoint@onthreedcoil{0.445}{-1    }{10}}
    {\pgfpoint@onthreedcoil{0    }{-0.555}{11.25}}
    {\pgfpoint@onthreedcoil{0    }{ 0    }{12.5}}
    \pgfpathcurveto
    {\pgfpoint@onthreedcoil{0    }{ 0.555}{13.25}}
    {\pgfpoint@onthreedcoil{0.445}{ 1    }{14.25}}
    {\pgfpoint@onthreedcoil{1    }{ 1    }{15}}
    % draw the curve back
    \pgfpathcurveto
    {\pgfpoint@onthreedcoil{0.445}{ 1    }{14}}
    {\pgfpoint@onthreedcoil{0    }{ 0.555}{12.75}}
    {\pgfpoint@onthreedcoil{0    }{ 0    }{11.5}}
    \pgfpathcurveto
    {\pgfpoint@onthreedcoil{0    }{-0.555}{10.75}}
    {\pgfpoint@onthreedcoil{0.445}{-1    }{10}}
    {\pgfpoint@onthreedcoil{1    }{-1    }{9}}
    \pgfusepath{stroke,fill} 
    % 
    % draw the thick foreground path
    %
    \pgfsetstrokecolor{\TDCoilColor}
    \pgfsetfillcolor{\TDCoilColor}
    \pgfsetstrokeopacity{\TDCoilOpacity}
    \pgfpathmoveto{\pgfpoint@onthreedcoil{1    }{ 1    }{3}}
    \pgfsetlinewidth{\TDCoilWidth} 
    % forward shifted +
    \pgfpathmoveto{\pgfpoint@onthreedcoil{1    }{-1    }{9}}
    \pgfpathcurveto
    {\pgfpoint@onthreedcoil{0.445}{-1    }{10}}
    {\pgfpoint@onthreedcoil{0    }{-0.555}{11.25}}
    {\pgfpoint@onthreedcoil{0    }{ 0    }{12.5}}
    \pgfpathcurveto
    {\pgfpoint@onthreedcoil{0    }{ 0.555}{13.25}}
    {\pgfpoint@onthreedcoil{0.445}{ 1    }{14.25}}
    {\pgfpoint@onthreedcoil{1    }{ 1    }{15}}
    % draw the curve back shfted -
    \pgfpathcurveto
    {\pgfpoint@onthreedcoil{0.445}{ 1    }{14}}
    {\pgfpoint@onthreedcoil{0    }{ 0.555}{12.75}}
    {\pgfpoint@onthreedcoil{0    }{ 0    }{11.5}}
    \pgfpathcurveto
    {\pgfpoint@onthreedcoil{0    }{-0.555}{10.75}}
    {\pgfpoint@onthreedcoil{0.445}{-1    }{10}}
    {\pgfpoint@onthreedcoil{1    }{-1    }{9}}
    \pgfusepath{stroke,fill} 
    \pgfpathmoveto{\pgfpoint@onthreedcoil{1    }{ 1    }{15}}
    \pgfpathcurveto
    {\pgfpoint@onthreedcoil{1.555}{ 1    }{16}}
    {\pgfpoint@onthreedcoil{2    }{ 0.555}{17}}
    {\pgfpoint@onthreedcoil{2    }{ 0    }{18}}
    \pgfusepath{stroke} 
    \pgfcoordinate{TD@coilast}{\pgfpoint@onthreedcoil{2    }{ 0    }{18}} 
  }
  \state{last}[next state=final]
    { % line in the back
    %
    \pgfsetstrokecolor{\TDCoilColor}
    \pgfsetfillcolor{\TDCoilColor}
    \pgfsetstrokeopacity{\TDCoilOpacity}
    \pgfpathmoveto{\pgfpointanchor{TD@coilast}{center}}
    \pgfsetlinewidth{\TDCoilWidth} 
    \pgfpathcurveto
    {\pgfpoint@onthreedcoil{2    }{-0.555}{7}}
    {\pgfpoint@onthreedcoil{1.555}{-1    }{8}}
    {\pgfpoint@onthreedcoil{1    }{-1    }{9}}
    \pgfusepath{stroke} 
    % 
    % draw the thick foreground path
    %
    \ifcoil@closed %\pgfpointanchor{TD@coilfirst}{center}
     %
     % white background for front thick part
     %
     \pgfsetstrokeopacity{1}
     \pgfsetstrokecolor{white}
     \pgfsetfillcolor{white}
     \pgfsetlinewidth{1.5*\TDCoilWidth+1.5*\TDCoilDist}
     \pgfpathmoveto{\pgfpoint@onthreedcoil{1    }{ 1    }{3}}
     \pgfpathmoveto{\pgfpoint@onthreedcoil{1    }{-1    }{9}}
     % draw forward
     \pgfpathcurveto
     {\pgfpoint@onthreedcoil{0.445}{-1    }{10}}
     {\pgfpoint@onthreedcoil{0    }{-0.555}{11.25}}
     {\pgfpoint@onthreedcoil{0    }{ 0    }{12.5}}
     \pgfpathcurveto
     {\pgfpoint@onthreedcoil{0    }{ 0.555}{13.25}}
     {\pgfpoint@onthreedcoil{0.445}{ 1    }{14.25}}
     {\pgfpointanchor{TD@coilfirst}{center}}
     % draw the curve back
     \pgfpathcurveto
     {\pgfpoint@onthreedcoil{0.445}{ 1    }{14}}
     {\pgfpoint@onthreedcoil{0    }{ 0.555}{12.75}}
     {\pgfpoint@onthreedcoil{0    }{ 0    }{11.5}}
     \pgfpathcurveto
     {\pgfpoint@onthreedcoil{0    }{-0.555}{10.75}}
     {\pgfpoint@onthreedcoil{0.445}{-1    }{10}}
     {\pgfpoint@onthreedcoil{1    }{-1    }{9}}
     \pgfusepath{stroke,fill} 
     \pgfsetstrokecolor{\TDCoilColor}
     \pgfsetfillcolor{\TDCoilColor}
     \pgfsetstrokeopacity{\TDCoilOpacity}
     \pgfpathmoveto{\pgfpoint@onthreedcoil{1    }{ 1    }{3}}
     \pgfsetlinewidth{\TDCoilWidth} 
     % forward shifted +
     \pgfpathmoveto{\pgfpoint@onthreedcoil{1    }{-1    }{9}}
     \pgfpathcurveto
     {\pgfpoint@onthreedcoil{0.445}{-1    }{10}}
     {\pgfpoint@onthreedcoil{0    }{-0.555}{11.25}}
     {\pgfpoint@onthreedcoil{0    }{ 0    }{12.5}}
     \pgfpathcurveto
     {\pgfpoint@onthreedcoil{0    }{ 0.555}{13.25}}
     {\pgfpoint@onthreedcoil{0.445}{ 1    }{14.25}}
     {\pgfpointanchor{TD@coilfirst}{center}}
     % draw the curve back shifted 
     \pgfpathcurveto
     {\pgfpoint@onthreedcoil{0.445}{ 1    }{14}}
     {\pgfpoint@onthreedcoil{0    }{ 0.555}{12.75}}
     {\pgfpoint@onthreedcoil{0    }{ 0    }{11.5}}
     \pgfpathcurveto
     {\pgfpoint@onthreedcoil{0    }{-0.555}{10.75}}
     {\pgfpoint@onthreedcoil{0.445}{-1    }{10}}
     {\pgfpoint@onthreedcoil{1    }{-1    }{9}}
     \pgfusepath{stroke,fill} 
    \else
     %
     % white background for front thick part
     %
     \pgfsetstrokeopacity{1}
     \pgfsetstrokecolor{white}
     \pgfsetfillcolor{white}
     \pgfsetlinewidth{1.5*\TDCoilWidth+1.5*\TDCoilDist}
     \pgfpathmoveto{\pgfpoint@onthreedcoil{1    }{ 1    }{3}}
     \pgfpathmoveto{\pgfpoint@onthreedcoil{1    }{-1    }{9}}
     % draw forward
     \pgfpathcurveto
     {\pgfpoint@onthreedcoil{0.445}{-1    }{10}}
     {\pgfpoint@onthreedcoil{0    }{-0.555}{11.25}}
     {\pgfpoint@onthreedcoil{0    }{ 0    }{12.5}}
     \pgfpathcurveto
     {\pgfpoint@onthreedcoil{0    }{ 0.555}{13.25}}
     {\pgfpoint@onthreedcoil{0.445}{ 1    }{14.25}}
     {\pgfpoint@onthreedcoil{1    }{ 1    }{15}}
     % draw the curve back
     \pgfpathcurveto
     {\pgfpoint@onthreedcoil{0.445}{ 1    }{14}}
     {\pgfpoint@onthreedcoil{0    }{ 0.555}{12.75}}
     {\pgfpoint@onthreedcoil{0    }{ 0    }{11.5}}
     \pgfpathcurveto
     {\pgfpoint@onthreedcoil{0    }{-0.555}{10.75}}
     {\pgfpoint@onthreedcoil{0.445}{-1    }{10}}
     {\pgfpoint@onthreedcoil{1    }{-1    }{9}}
     \pgfusepath{stroke,fill} 
     \pgfsetstrokecolor{\TDCoilColor}
     \pgfsetfillcolor{\TDCoilColor}
     \pgfsetstrokeopacity{\TDCoilOpacity}
     \pgfpathmoveto{\pgfpoint@onthreedcoil{1    }{ 1    }{3}}
     \pgfsetlinewidth{\TDCoilWidth} 
     % forward shifted +
     \pgfpathmoveto{\pgfpoint@onthreedcoil{1    }{-1    }{9}}
     \pgfpathcurveto
     {\pgfpoint@onthreedcoil{0.445}{-1    }{10}}
     {\pgfpoint@onthreedcoil{0    }{-0.555}{11.25}}
     {\pgfpoint@onthreedcoil{0    }{ 0    }{12.5}}
     \pgfpathcurveto
     {\pgfpoint@onthreedcoil{0    }{ 0.555}{13.25}}
     {\pgfpoint@onthreedcoil{0.445}{ 1    }{14.25}}
     {\pgfpoint@onthreedcoil{1    }{ 1    }{15}}
     % draw the curve back shifted 
     \pgfpathcurveto
     {\pgfpoint@onthreedcoil{0.445}{ 1    }{14}}
     {\pgfpoint@onthreedcoil{0    }{ 0.555}{12.75}}
     {\pgfpoint@onthreedcoil{0    }{ 0    }{11.5}}
     \pgfpathcurveto
     {\pgfpoint@onthreedcoil{0    }{-0.555}{10.75}}
     {\pgfpoint@onthreedcoil{0.445}{-1    }{10}}
     {\pgfpoint@onthreedcoil{1    }{-1    }{9}}
     \pgfusepath{stroke,fill} 
    \fi
    \pgfpathmoveto{\pgfpoint@onthreedcoil{1    }{ 1    }{15}}
    \ifcoil@closed %TD@coilfirst
    \else
     \pgfpathcurveto
     {\pgfpoint@onthreedcoil{1.555}{ 1    }{16}}
     {\pgfpoint@onthreedcoil{2    }{ 0.555}{17}}
     {\pgfpoint@onthreedcoil{2    }{ 0    }{18}}
    \fi
    \pgfusepath{stroke} 
    %\pgfcoordinate{TD@coilast}{\pgfpoint@onthreedcoil{2    }{ 0    }{18}} 
  }
  \state{final}
  {
    \pgfpathmoveto{\pgfpointdecoratedpathlast}
    \tikzset{restore stroke color/.expand once=\pgfsavedstrokecolor}
  }
}
\makeatother

\begin{document}
\begin{tikzpicture}
\begin{scope}[transform shape nonlinear=true]
 \pgftransformnonlinear{\nltrafo}
 \draw[decoration={3d coil color=blue,aspect=0.35, segment length=2.1mm,
 amplitude=3mm,3d complete coil}, decorate] (0,0) -- (12,0);
\end{scope}  
\end{tikzpicture}
\end{document}

enter image description here Of course, one can also draw a coil by plotting a coil.

\documentclass[tikz,border=3mm]{standalone} 
\begin{document} 
\begin{tikzpicture}[font=\sffamily] 
 \begin{scope}[z={(70:1)},y={(110:1)},local bounding box=coil] 
  \draw plot[domain=0:14400,variable=\t,samples=1441,smooth] 
  ({\t/1200+0.1*pi*sin(\t/20)},{-0.5*sin(\t)},{0.5*cos(\t)}); 
 \end{scope} 
 \path (coil.south west) -- (coil.south east) 
 node[pos=0.25,below]{Compression} node[pos=0.5,below]{Rarefraction}; 
 \draw[very thick,red,stealth-stealth] 
  ([yshift=2mm]coil.north) -- ([yshift=2mm]coil.north east)
  node[midway,above]{$\lambda$}; 
\end{tikzpicture} 
\end{document}

enter image description here

Or more 3d-like.

\documentclass[tikz,border=3mm]{standalone} 
\usetikzlibrary{decorations.pathreplacing}
\begin{document} 
\begin{tikzpicture}[font=\sffamily,
rubout/.style={/utils/exec=\tikzset{rubout/.cd,#1},
 decoration={show path construction,
      curveto code={
       \draw [white,line width=\pgfkeysvalueof{/tikz/rubout/line width}+2*\pgfkeysvalueof{/tikz/rubout/halo}] 
        (\tikzinputsegmentfirst) .. controls
        (\tikzinputsegmentsupporta) and (\tikzinputsegmentsupportb)  ..(\tikzinputsegmentlast); 
       \draw [line width=\pgfkeysvalueof{/tikz/rubout/line width},shorten <=-0.1pt,shorten >=-0.1pt] (\tikzinputsegmentfirst) .. controls
        (\tikzinputsegmentsupporta) and (\tikzinputsegmentsupportb) ..(\tikzinputsegmentlast);  
      }}},rubout/.cd,line width/.initial=0.7pt,halo/.initial=0.8pt]
 \begin{scope}[z={(70:1)},y={(110:1)},local bounding box=coil] 
  \draw[rubout,decorate] plot[domain=0:14400,variable=\t,samples=1441,smooth] 
  ({\t/1200+0.1*pi*sin(\t/20)},{-0.5*sin(\t)},{0.5*cos(\t)}); 
 \end{scope} 
 \path (coil.south west) -- (coil.south east) 
 node[pos=0.25,below]{Compression} node[pos=0.5,below]{Rarefraction}; 
 \draw[very thick,red,stealth-stealth] 
  ([yshift=2mm]coil.north) -- ([yshift=2mm]coil.north east)
  node[midway,above]{$\lambda$}; 
\end{tikzpicture} 
\end{document}

enter image description here

Tags:

Tikz Pgf