我需要在 3D 表面下绘制有限数量的立方体。因此我需要嵌套循环。以下代码接近我想要的,只是我想修改参数的 z 限制以使\k
所有立方体都在表面图下。基本上,我想使用\fun{\i}{\j}-\dl
而不是\fun{\i}{\j}
:
\documentclass[tikz]{standalone}
\usepackage{pgfplots}
\usetikzlibrary{calc}
\pgfplotsset{compat=1.16}
\begin{document}
\newcommand{\fun}[2]{{4*((#1/(#1+1))*(#2/(#2+1))+0.5)}}
\tikzset{
mycube/.pic={
\pgfmathsetmacro\size{{#1}}
\draw[fill=gray!20] (0,0,\size) -- ++(0,\size,0) -- ++(\size,0,0) -- ++(0,-\size,0) -- cycle; % top
\draw[fill=gray!10] (0,0,0) --++(\size,0,0)-- ++ (0,0,\size)--++(-\size,0,0) -- cycle; % front
\draw[fill=gray!40] (\size,0,0) --++(0,\size,0)-- ++ (0,0,\size)--++(0,-\size,0) -- cycle; %side
}
}
\begin{tikzpicture}
\def\dl{1}
\begin{axis}[xlabel = $x$, ylabel = $y$, zlabel = {$z$},
xmin=0, xmax=5,
ymin=0, ymax = 5,
zmin=0,
clip=false]
% WORKING but not satisfactory
\pgfplotsforeachungrouped \i in {0,0+\dl,...,5-\dl}{
\pgfplotsforeachungrouped \j in {5-\dl,5-(2*\dl),...,0}{
\pgfplotsforeachungrouped \k in {0,0+\dl,...,int(\fun{\i}{\j})}{
\edef\temp{\noexpand \draw (\i,\j,\k) pic{mycube={\dl}};}\temp
}
}
}
% NOT working
% \pgfplotsforeachungrouped \i in {0,0+\dl,...,5-\dl}{
% \pgfplotsforeachungrouped \j in {5-\dl,5-(2*\dl),...,0}{
% \pgfplotsforeachungrouped \k in {0,0+\dl,...,int(\fun{\i}{\j}-\dl)}{
% \edef\temp{\noexpand \draw (\i,\j,\k) pic{mycube={\dl}};}\temp
% }
% }
% }
% NOT working
% \pgfplotsforeachungrouped \i in {0,0+\dl,...,5-\dl}{
% \pgfplotsforeachungrouped \j [evaluate=\j as \klim using {int(\fun{\i}{\j})}] in {5-\dl,5-(2*\dl),...,0}{
% \pgfplotsforeachungrouped \k in {0,0+\dl,...,\klim}{
% \edef\temp{\noexpand \draw (\i,\j,\k) pic{mycube={\dl}};}\temp
% }
% }
% }
\addplot3[surf,domain=0:5,y domain=0:5,fill opacity = 0.3] {\fun{x}{y}};
\end{axis}
\end{tikzpicture}
\end{document}
我尝试了几种方法来降低这个 z 限制,但都不起作用。任何帮助都将不胜感激!
附加问题:
- 我不确定将表面函数定义为单独的宏是否是最好的方法。如何以更简洁的方式做到这一点?
int( )
为什么循环中必须要使用\k
参数呢?
多谢。
答案1
尝试理解“降低 z 限制”的含义,我最终猜测 OP 希望将盒子在 z 方向上向下移动,同时保持函数不变,以使盒子不超过函数。
我将\k
循环索引调整为
\pgfplotsforeachungrouped \k in {0,0+\dl,...,(int(\fun{\i}{\j}) - 1.5)}
为什么-1.5
?因为\k
开始绘制于 0,并且零绘制延伸至z=1
,因此需要减去 1。然后,我发现如果我\z
手动将 的上限设置为 ,例如 ,2.5
它会将其四舍五入,就像它是 一样,3
并且实际上绘制的框最多为z=4
。因此,实际函数(z=2.5)和堆叠的 z 框(到 z=4)之间的差异可能很大,为 4 - 2.5 = 1.5。这就是为什么必须从总数中减去 1.5 的原因,以确保框高度永远不会超过函数高度。
\documentclass[tikz]{standalone}
\usepackage{pgfplots}
\usetikzlibrary{calc}
\pgfplotsset{compat=1.16}
\begin{document}
\newcommand{\fun}[2]{{4*((#1/(#1+1))*(#2/(#2+1))+0.5)}}
\tikzset{
mycube/.pic={
\pgfmathsetmacro\size{{#1}}
\draw[fill=gray!20] (0,0,\size) -- ++(0,\size,0) -- ++(\size,0,0) -- ++(0,-\size,0) -- cycle; % top
\draw[fill=gray!10] (0,0,0) --++(\size,0,0)-- ++ (0,0,\size)--++(-\size,0,0) -- cycle; % front
\draw[fill=gray!40] (\size,0,0) --++(0,\size,0)-- ++ (0,0,\size)--++(0,-\size,0) -- cycle; %side
}
}
\begin{tikzpicture}
\def\dl{1}
\begin{axis}[xlabel = $x$, ylabel = $y$, zlabel = {$z$},
xmin=0, xmax=5,
ymin=0, ymax = 5,
zmin=0,
clip=false]
% WORKING but not satisfactory
\pgfplotsforeachungrouped \i in {0,0+\dl,...,5-\dl}{
\pgfplotsforeachungrouped \j in {5-\dl,5-(2*\dl),...,0}{
\pgfplotsforeachungrouped \k in {0,0+\dl,...,(int(\fun{\i}{\j}) - 1.5)}{
\edef\temp{\noexpand \draw (\i,\j,\k) pic{mycube={\dl}};}\temp
}
}
}
\addplot3[surf,domain=0:5,y domain=0:5,fill opacity = 0.3] {\fun{x}{y}};
\end{axis}
\end{tikzpicture}
\end{document}