我在 stackexchange 上找到了以下解决方案。它得到了完美的回答这里来自@Jake。
\documentclass[border=5mm]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.8}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
set layers=standard,
domain=0:10,
samples y=1,
view={40}{20},
hide axis,
unit vector ratio*=1 2 1,
xtick=\empty, ytick=\empty, ztick=\empty,
clip=false
]
\def\sumcurve{0}
\pgfplotsinvokeforeach{0.5,1.5,...,5.5}{
\draw [on layer=background, gray!20] (axis cs:0,#1,0) -- (axis cs:10,#1,0);
\addplot3 [on layer=main, blue!30, smooth, samples=101] (x,#1,{sin(#1*x*157))/(#1*2)});
\addplot3 [on layer=axis foreground, very thick, blue,ycomb, samples=2] (10.5,#1,{1/(#1*2)});
\xdef\sumcurve{\sumcurve + sin(#1*x*(157))/(#1*2)}
}
\addplot3 [red, samples=200] (x,0,{\sumcurve});
\draw [on layer=axis foreground] (axis cs:0,0,0) -- (axis cs:10,0,0);
\draw (axis cs:10.5,0.25,0) -- (axis cs:10.5,5.5,0);
\end{axis}
\end{tikzpicture}
\end{document}
我真的很喜欢这个解决方案。如果有人能解释一下代码中用到的以下特性,我将不胜感激,这样我就可以学习并在将来使用它。
\pgfplotsinvokeforeach
:我读了手册,但还是看不出它与 的区别\foreach
。为什么我们不使用foreach
?\addplot3 (x,#1,{sin(#1*x*(157))/(#1*2)});
:这行代码中x
和有什么区别?会取什么值?#1
x
\def\sumcurve{0}
:这个定义了y=0
曲线吗?- 我对代码中的层有点困惑。我们为什么需要这些层?
unit vector ratio*=1 2 1
:这是否用于模拟如图所示的漂亮三维图形这里?
答案1
\pgfplotsinvokeforeach
不同于\foreach
。 首先\foreach
引入了作用域,\pgfplotsinvokeforeach
则没有。 比较:
\documentclass[border=5mm]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.8}
\def\myvalueA{0}
\def\myvalueB{0}
\begin{document}
\begin{tikzpicture}
\node[anchor=east] at (0,0) {foreach:};
\foreach \myn in {1,2,3,4,5}
{
\edef\myvalueA{\number\numexpr\myvalueA+\myn}
\node at (\myn,0) {\myvalueA};
}
\node at (6,0) {\myvalueA};
\node[anchor=east] at (0,2) {pgfplotsinvokeforeach:};
\pgfplotsinvokeforeach{1,2,3,4,5}
{
\edef\myvalueB{\number\numexpr\myvalueB+#1\relax}
\node at (#1,2) {\myvalueB};
}
\node at (6,2) {\myvalueB};
\end{tikzpicture}
\end{document}
由于范围界定由 引入\foreach
, 的新值\myvalueA
在每次迭代后都会丢失。\foreach
循环完成后,\myvalueA
恢复其初始化时的值。为了通过循环解决这个问题\foreach
,您必须使用\xdef
而不是\edef
。
\pgfplotsinvokeforeach
不引入这样的作用域。因此,的新\myvalueB
值为记得之间相互作用。
使用\addplot3 (x,#1,{sin(#1*x*(157))/(#1*2)});
,x
范围涵盖声明中定义的域axis
,范围涵盖其第一个参数中#1
传递的值。\pgfplotsinvokeforeach
\def\sumcurve{0}
仅将初始化\sumcurve
为第一次迭代中的
\xdef\sumcurve{\sumcurve + sin(#1*x*(157))/(#1*2)}
定义\sumcurve
中的 有一个要添加的值。否则在第一次迭代中,\sumcurve
将是一个未定义的控制序列。
如果您在编译时不使用,layers
则轴将会显示在图形的顶部:这很可能不是您想要的,特别是为了保持 3-d 的视觉效果。
unit vector ratio*=1 2 1
仅为轴创建一个漂亮的比例。