我正在尝试使用 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
这个问题可以推广到
如何才能使现有的装饰变形?
一个答案是
与往常一样,即采用非线性变换。
示例(使用\flagtransformation
x
和的角色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}