I need to draw a finite number of cubes below a 3D surface. Thus I need nested loops. The following code is close to what I want, except that I want to modify the z limit for the \k
parameter to have all the cubes under the surface plot. Basically, I would like to use \fun{\i}{\j}-\dl
instead of \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}
I tried several trick to lower this z-limit but nothing works here. Any help would be appreciated!
Bonus questions:
- I'm not sure that defining my surface function as a separate macro is the best way to do. How to do it in a cleaner way?
- Why is it necessary to use
int( )
in the\k
loop parameters?
Thanks a lot.
int
in{0,0+\dl,...,int(\fun{\i}{\j})}
, it is because the first two items are integers 0,1. Thus, to make sense, the last item must be an integer.int
makes sure it is. However, I still do not really understand the question, what it is that needs fixing. What does "lower the z limit" mean?\dl
, including non integers. So I wonder if an alternative to{0,0+\dl,...,int(\fun{\i}{\j})}
could be to use point values such as `{0.0,0.0+\dl,...,\fun{\i}{\j}}. Do I understand it right?