在 TikZ 中绘制纵波

在 TikZ 中绘制纵波

我正在尝试使用 TikZ 获取这个纵波:

在此处输入图片描述

这是我的代码

\documentclass{article}
\usepackage{tikz}

\begin{document}  

\usetikzlibrary{decorations.pathmorphing}

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

\draw[decorate, decoration={aspect=0.3, segment length=3mm, amplitude=3mm}] (0,0) --(3,0);
\draw[decorate, decoration={aspect=0.3, segment length=0.5mm, amplitude=3mm}] (3,0) -- (3.5,0); 
\draw[decorate, decoration={aspect=0.3, segment length=3mm, amplitude=3mm}] (3.5,0) -- (5,0);

\end{tikzpicture}
\end{document}

但是,一条线和另一条线之间的连接会中断线圈的连续性。如何改善它?

答案1

看起来,如果没有空间形成完整的循环,路径将以直线结束。通过对第一条路径的端点进行轻微更改,结果会更好。此外,为了使循环连续,而不是在中点转弯,您可以将第二条和第三条路径的振幅设为负值。

\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}

在此处输入图片描述

答案2

这是使用装饰的替代方法,它可以让您获得更多控制权(尽管我应该在一开始就说,我认为装饰的更风格化的版本实际上看起来更整洁)。我最近发现自己想画一个螺旋线,因此修改了弧线代码,以便在绘制弧线时允许横向移动。通过改变偏移,我可以获得纵波。代码看起来有点复杂,但它是对弧线代码的一个非常简单的改编(当然它可以隐藏在包中!)。

首先是结果:

纵波

如果这段可怕的代码在一个包中,那么你需要这样写才能得到它:

\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}

关键helix是将弧形宏替换为修改后的宏,并设置螺旋中的移位因子。因此,通过改变它,我们可以获得波浪状行为。宏\helical是计算移位因子的快捷方式,以便每个循环都从上一个循环的正确位置开始。

可怕的代码如下:

\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

答案3

这个问题可以推广到

如何才能使现有的装饰变形?

一个答案是

与往常一样,即采用非线性变换。

示例(使用\flagtransformationx和的角色y互换):

\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}

在此处输入图片描述

如您所见,这适用于任意变换,并且频率的变化是一个平滑函数(\pgf@x+7*sin(\pgf@x*3.6))。

一个更奇特的例子使用三维线圈装饰(实际上这是一个可以工作但被删除的版本;如果你想知道为什么它被删除,你需要问别人;这个代码很长,因为定义3d coil、变形都很短):

\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}

在此处输入图片描述 当然,也可以通过绘制线圈来绘制线圈。

\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}

在此处输入图片描述

或者更像 3d。

\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}

在此处输入图片描述

相关内容