答案1
欢迎!它做了类似的事情。参数存储在 pgf 键中,波形存储在名为 的函数中wv
。
\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{3d,fadings}
\tikzfading[name=fade left,
left color=transparent!100, right color=transparent!0]
\begin{document}
\begin{tikzpicture}[x={(1cm,0cm)},y={(60:1cm)},z={(0cm,1cm)},
line cap=round,line join=round,font=\sffamily,
declare function={wv(\x)=-1*ifthenelse(\x<\pgfkeysvalueof{/tikz/wave/xcrit},1,0)*\pgfkeysvalueof{/tikz/wave/amplitude}*sin(\x*\pgfkeysvalueof{/tikz/wave/omega});},
pics/pln/.style={code={
\tikzset{wave/.cd,#1}
\def\pv##1{\pgfkeysvalueof{/tikz/wave/##1}}
\pgfmathsetmacro{\nextX}{\pv{xmin}+\pv{step}}
\pgfmathsetmacro{\nextY}{\pv{ymin}+\pv{step}}
\draw[fill=\pv{fill}] (0,0) rectangle (\pv{xmax},\pv{ymax});
\draw foreach \Y in {\pv{ymin},\nextY,...,\pv{ymax}}
{(0,\Y) -- (\pv{xmax},\Y)}
foreach \X in {\pv{xmin},\nextX,...,\pv{xmax}}
{({\X+wv(\X)},0) --
({\X+wv(\X)},\pv{ymax})};
}},wave/.cd,xmin/.initial=0,xmax/.initial=1,xcrit/.initial=1,
ymin/.initial=0,ymax/.initial=1,
step/.initial=0.2,omega/.initial=150,amplitude/.initial=0.15,
fill/.initial=none
]
\path (0,0,0.5) node[left=1em,node font=\large]{P wave};
\begin{scope}[canvas is xy plane at z=1]
\pic[transform shape,fill=orange]{pln={xmax=9,xcrit=6,fill=orange!50}};
\end{scope}
\begin{scope}[canvas is xz plane at y=0]
\pic[transform shape,fill=orange]{pln={xmax=9,xcrit=6,fill=orange}};
\end{scope}
\begin{scope}[canvas is yz plane at x=9]
\pic[transform shape,fill=orange]{pln={xcrit=0,fill=orange!50}};
\end{scope}
\draw (12/5,1,1) -- ++ (0,0,0.3) -- node[fill=white] {Compressions}
(24/5,1,1.3) -- ++ (0,0,-0.3);
\draw (18/5,0,0) -- ++ (0,0,-0.3) -- node[fill=white] {Dilations}
(30/5,0,-0.3) -- ++ (0,0,0.3);
%
\path (0,0,-1) coordinate (L1) (7,0,-1) coordinate (R1);
\begin{scope}[yshift=-2.5cm,wave/.cd,xcrit=6]
\path (0,0,-0.5) node[left=1em,node font=\large]{S wave};
\draw[fill=orange!50]
plot[domain=0:9,samples=101,smooth] (\x,0,{wv(\x)}) --
plot[domain=9:0,samples=101,smooth] (\x,1,{wv(\x)}) -- cycle;
\foreach \Y in {0.2,0.4,0.6,0.8}
{\draw
plot[domain=0:9,samples=101,smooth] (\x,\Y,{wv(\x)});}
\foreach \X in {0.2,0.4,...,8.8}
{\draw (\X,0,{wv(\X)}) -- (\X,1,{wv(\X)});}
%
\draw[fill=orange]
plot[domain=0:9,samples=101,smooth] (\x,0,{-1+wv(\x)}) --
plot[domain=9:0,samples=101,smooth] (\x,0,{+wv(\x)}) -- cycle;
\foreach \Z in {0.2,0.4,0.6,0.8}
{\draw
plot[domain=0:9,samples=101,smooth] (\x,0,{-1+\Z+wv(\x)});}
\foreach \X in {0.2,0.4,...,8.8}
{\draw (\X,0,{-1+wv(\X)}) -- (\X,0,{wv(\X)});}
%
\begin{scope}[canvas is yz plane at x=9,yshift=-1cm]
\pic[transform shape,fill=orange]{pln={xcrit=0,fill=orange!50}};
\end{scope}
\draw (15/5,0,{-1+wv(15/5)}) coordinate (auxtl)-- ++ (0,0,-0.8) coordinate (auxbl)
(27/5,0,{-1+wv(27/5)}) coordinate (auxtr) -- ++ (0,0,-0.8) coordinate (auxbr)
node[pos=0.5,left,inner ysep=1pt](amp) {Amplitude};
\draw[densely dashed] (auxtl) -- (auxtr);
\draw[stealth-stealth] (21/5,0,{-1+wv(21/5)}) -- coordinate(aux) (21/5,0,{-1+wv(27/5)});
\draw[-] (aux) -- (amp);
\draw[stealth-stealth] ([yshift=1mm]auxbl) -- node[below]{Wavelength}
([yshift=1mm]auxbr);
\path (2,0,-3.5) coordinate (L2) (9,0,-3.5) coordinate (R2);
\end{scope}
%
\begin{scope}[canvas is xy plane at z=0]
\pgflowlevelsynccm
\draw[blue!50,line width=4pt,-stealth,path fading=fade left] (L1) -- (R1);
\draw[blue!50,line width=4pt,-stealth,path fading=fade left] (L2) -- (R2);
\end{scope}
\end{tikzpicture}
\end{document}
如果您希望平滑过渡,这也是可行的。但是,如果您想使用简单的平滑函数来tanh
实现此目的,则可能需要该fpu
库。
\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{3d,fadings,fpu}
\pgfmathdeclarefunction{wv}{1}{%
\begingroup%
\pgfkeys{/pgf/fpu,/pgf/fpu/output format=fixed}%
\pgfmathparse{(tanh(2*(#1-\pgfkeysvalueof{/tikz/wave/xcrit}))-1)*%
\pgfkeysvalueof{/tikz/wave/amplitude}*sin(#1*\pgfkeysvalueof{/tikz/wave/omega})}%
\pgfmathsmuggle\pgfmathresult\endgroup%
}
\tikzfading[name=fade left,
left color=transparent!100, right color=transparent!0]
\begin{document}
\begin{tikzpicture}[x={(1cm,0cm)},y={(60:1cm)},z={(0cm,1cm)},
line cap=round,line join=round,font=\sffamily,
pics/pln/.style={code={
\tikzset{wave/.cd,#1}
\def\pv##1{\pgfkeysvalueof{/tikz/wave/##1}}
\pgfmathsetmacro{\nextX}{\pv{xmin}+\pv{step}}
\pgfmathsetmacro{\nextY}{\pv{ymin}+\pv{step}}
\draw[fill=\pv{fill}] (0,0) rectangle (\pv{xmax},\pv{ymax});
\draw foreach \Y in {\pv{ymin},\nextY,...,\pv{ymax}}
{(0,\Y) -- (\pv{xmax},\Y)}
foreach \X in {\pv{xmin},\nextX,...,\pv{xmax}}
{({\X+wv(\X)},0) --
({\X+wv(\X)},\pv{ymax})};
}},wave/.cd,xmin/.initial=0,xmax/.initial=1,xcrit/.initial=1,
ymin/.initial=0,ymax/.initial=1,
step/.initial=0.2,omega/.initial=150,amplitude/.initial=0.1,
fill/.initial=none
]
\path (0,0,0.5) node[left=1em,node font=\large]{P wave};
\begin{scope}[canvas is xy plane at z=1]
\pic[transform shape,fill=orange]{pln={xmax=9,xcrit=6,fill=orange!50}};
\end{scope}
\begin{scope}[canvas is xz plane at y=0]
\pic[transform shape,fill=orange]{pln={xmax=9,xcrit=6,fill=orange}};
\end{scope}
\begin{scope}[canvas is yz plane at x=9]
\pic[transform shape,fill=orange]{pln={xcrit=0,fill=orange!50}};
\end{scope}
\draw (12/5,1,1) -- ++ (0,0,0.3) -- node[fill=white] {Compressions}
(24/5,1,1.3) -- ++ (0,0,-0.3);
\draw (18/5,0,0) -- ++ (0,0,-0.3) -- node[fill=white] {Dilations}
(30/5,0,-0.3) -- ++ (0,0,0.3);
\draw (6,1,1) -- ++ (0,0,0.1) node[above right] {Undisturbed medium};
%
\path (0,0,-1) coordinate (L1) (7,0,-1) coordinate (R1);
\begin{scope}[yshift=-2.5cm,wave/.cd,xcrit=6,amplitude=0.15]
\path (0,0,-0.5) node[left=1em,node font=\large]{S wave};
\draw[fill=orange!50]
plot[domain=0:9,samples=101,smooth] (\x,0,{wv(\x)}) --
plot[domain=9:0,samples=101,smooth] (\x,1,{wv(\x)}) -- cycle;
\foreach \Y in {0.2,0.4,0.6,0.8}
{\draw
plot[domain=0:9,samples=101,smooth] (\x,\Y,{wv(\x)});}
\foreach \X in {0.2,0.4,...,8.8}
{\draw (\X,0,{wv(\X)}) -- (\X,1,{wv(\X)});}
%
\draw[fill=orange]
plot[domain=0:9,samples=101,smooth] (\x,0,{-1+wv(\x)}) --
plot[domain=9:0,samples=101,smooth] (\x,0,{+wv(\x)}) -- cycle;
\foreach \Z in {0.2,0.4,0.6,0.8}
{\draw
plot[domain=0:9,samples=101,smooth] (\x,0,{-1+\Z+wv(\x)});}
\foreach \X in {0.2,0.4,...,8.8}
{\draw (\X,0,{-1+wv(\X)}) -- (\X,0,{wv(\X)});}
%
\begin{scope}[canvas is yz plane at x=9,yshift=-1cm]
\pic[transform shape,fill=orange]{pln={xcrit=0,fill=orange!50}};
\end{scope}
\draw (15/5,0,{-1+wv(15/5)}) coordinate (auxtl)-- ++ (0,0,-0.8) coordinate (auxbl)
(27/5,0,{-1+wv(27/5)}) coordinate (auxtr) -- ++ (0,0,-0.8) coordinate (auxbr)
node[pos=0.5,left,inner ysep=1pt](amp) {Amplitude};
\draw[densely dashed] (auxtl) -- (auxtr);
\draw[stealth-stealth] (21/5,0,{-1+wv(21/5)}) -- coordinate(aux) (21/5,0,{-1+wv(27/5)});
\draw[-] (aux) -- (amp);
\draw[stealth-stealth] ([yshift=1mm]auxbl) -- node[below]{Wavelength}
([yshift=1mm]auxbr);
\path (2,0,-3.5) coordinate (L2) (9,0,-3.5) coordinate (R2);
\end{scope}
%
\begin{scope}[canvas is xy plane at z=0,sharp corners]
\pgflowlevelsynccm
\draw[blue!50,line width=4pt,-stealth,path fading=fade left] (L1) -- (R1);
\draw[blue!50,line width=4pt,-stealth,path fading=fade left] (L2) -- (R2);
\end{scope}
\end{tikzpicture}
\end{document}
这个流畅版本在动画时看起来也更好。
\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{3d,fadings,fpu}
\pgfmathdeclarefunction{wv}{1}{%
\begingroup%
\pgfkeys{/pgf/fpu,/pgf/fpu/output format=fixed}%
\pgfmathparse{(tanh(2*(#1-\pgfkeysvalueof{/tikz/wave/xcrit}))-1)*%
\pgfkeysvalueof{/tikz/wave/amplitude}*sin(#1*\pgfkeysvalueof{/tikz/wave/omega}+\pgfkeysvalueof{/tikz/wave/phase})}%
\pgfmathsmuggle\pgfmathresult\endgroup%
}
\tikzset{pics/pln/.style={code={
\tikzset{wave/.cd,#1}
\def\pv##1{\pgfkeysvalueof{/tikz/wave/##1}}
\pgfmathsetmacro{\nextX}{\pv{xmin}+\pv{step}}
\pgfmathsetmacro{\nextY}{\pv{ymin}+\pv{step}}
\draw[fill=\pv{fill}] (0,0) rectangle (\pv{xmax},\pv{ymax});
\clip (0,0) rectangle (\pv{xmax},\pv{ymax});
\draw foreach \Y in {\pv{ymin},\nextY,...,\pv{ymax}}
{(0,\Y) -- (\pv{xmax},\Y)}
foreach \X in {\pv{xmin},\nextX,...,\pv{xmax}}
{({\X+wv(\X)},0) --
({\X+wv(\X)},\pv{ymax})};
}},wave/.cd,xmin/.initial=0,xmax/.initial=1,xcrit/.initial=1,
ymin/.initial=0,ymax/.initial=1,
step/.initial=0.2,omega/.initial=150,amplitude/.initial=0.1,
fill/.initial=none,phase/.initial=0}
\tikzfading[name=fade left,
left color=transparent!100, right color=transparent!0]
\begin{document}
\foreach \Phase in {0,20,...,340}
{\begin{tikzpicture}[x={(1cm,0cm)},y={(60:1cm)},z={(0cm,1cm)},
line cap=round,line join=round,font=\sffamily,wave/phase=\Phase]
\path (0,0,0.5) node[left=1em,node font=\large]{P wave};
\begin{scope}[canvas is xy plane at z=1]
\pic[transform shape,fill=orange]{pln={xmax=9,xcrit=6,fill=orange!50}};
\end{scope}
\begin{scope}[canvas is xz plane at y=0]
\pic[transform shape,fill=orange]{pln={xmax=9,xcrit=6,fill=orange}};
\end{scope}
\begin{scope}[canvas is yz plane at x=9,wave/phase=0]
\pic[transform shape,fill=orange]{pln={xcrit=0,fill=orange!50}};
\end{scope}
%
\path (0,0,-1) coordinate (L1) (7,0,-1) coordinate (R1);
\begin{scope}[yshift=-2.5cm,wave/.cd,xcrit=6,amplitude=0.15]
\path (0,0,-0.5) node[left=1em,node font=\large]{S wave};
\draw[fill=orange!50]
plot[domain=0:9,samples=101,smooth] (\x,0,{wv(\x)}) --
plot[domain=9:0,samples=101,smooth] (\x,1,{wv(\x)}) -- cycle;
\foreach \Y in {0.2,0.4,0.6,0.8}
{\draw
plot[domain=0:9,samples=101,smooth] (\x,\Y,{wv(\x)});}
\foreach \X in {0.2,0.4,...,8.8}
{\draw (\X,0,{wv(\X)}) -- (\X,1,{wv(\X)});}
%
\draw[fill=orange]
plot[domain=0:9,samples=101,smooth] (\x,0,{-1+wv(\x)}) --
plot[domain=9:0,samples=101,smooth] (\x,0,{+wv(\x)}) -- cycle;
\foreach \Z in {0.2,0.4,0.6,0.8}
{\draw
plot[domain=0:9,samples=101,smooth] (\x,0,{-1+\Z+wv(\x)});}
\foreach \X in {0.2,0.4,...,8.8}
{\draw (\X,0,{-1+wv(\X)}) -- (\X,0,{wv(\X)});}
%
\begin{scope}[canvas is yz plane at x=9,yshift=-1cm,wave/phase=0]
\pic[transform shape,fill=orange]{pln={xcrit=0,fill=orange!50}};
\end{scope}
\path (2,0,-3.5) coordinate (L2) (9,0,-3.5) coordinate (R2);
\end{scope}
%
\begin{scope}[canvas is xy plane at z=0,sharp corners]
\pgflowlevelsynccm
\draw[blue!50,line width=4pt,-stealth,path fading=fade left] (L1) -- (R1);
\draw[blue!50,line width=4pt,-stealth,path fading=fade left] (L2) -- (R2);
\end{scope}
\end{tikzpicture}}
\end{document}