# How to draw a cube completely filled with water, the other with water by half and the last leave it empty?

I want to draw 3 cubes, one filled with water, a full half full and another completely empty. I can draw them, but I can't do the impression of three forms: full, empty and half full.

\documentclass{article}
\usepackage{tikz}
\usepackage{xcolor}
\begin{document}
\newcommand{\Depth}{2}
\newcommand{\Height}{2}
\newcommand{\Width}{2}
\begin{tikzpicture}
\coordinate (O) at (0,0,0);
\coordinate (A) at (0,\Width,0);
\coordinate (B) at (0,\Width,\Height);
\coordinate (C) at (0,0,\Height);
\coordinate (D) at (\Depth,0,0);
\coordinate (E) at (\Depth,\Width,0);
\coordinate (F) at (\Depth,\Width,\Height);
\coordinate (G) at (\Depth,0,\Height);
\draw[blue,fill=gray!20] (O) -- (C) -- (G) -- (D) -- cycle;
\draw[blue,fill=gray!20] (O) -- (A) -- (E) -- (D) -- cycle;
\draw[blue,fill=gray!10] (O) -- (A) -- (B) -- (C) -- cycle;
\draw[gray,fill=gray20,opacity=0.4] (D) -- (E) -- (F) -- (G) -- cycle;
\draw[blue,fill=gray!20,opacity=0.6] (C) -- (B) -- (F) -- (G) -- cycle;
\draw[blue,fill=gray!20,opacity=0.8] (A) -- (B) -- (F) -- (E) -- cycle;
\end{tikzpicture}
\begin{tikzpicture}
\coordinate (O) at (0,0,0);
\coordinate (A) at (0,\Width,0);
\coordinate (B) at (0,\Width,\Height);
\coordinate (C) at (0,0,\Height);
\coordinate (D) at (\Depth,0,0);
\coordinate (E) at (\Depth,\Width,0);
\coordinate (F) at (\Depth,\Width,\Height);
\coordinate (G) at (\Depth,0,\Height);
\draw[fill=whitegray!20] (O) -- (C) -- (G) -- (D) -- cycle;
\draw[fill=gray!20] (O) -- (A) -- (E) -- (D) -- cycle;
\draw[fill=gray!10] (O) -- (A) -- (B) -- (C) -- cycle;
\draw[fill=gray20,opacity=0.4] (D) -- (E) -- (F) -- (G) -- cycle;
\draw[fill=gray!5,opacity=0.6] (C) -- (B) -- (F) -- (G) -- cycle;
\draw[fill=gray!5,opacity=0.8] (A) -- (B) -- (F) -- (E) -- cycle;
\end{tikzpicture}
\begin{tikzpicture}
\coordinate (O) at (0,0,0);
\coordinate (A) at (0,\Width,0);
\coordinate (B) at (0,\Width,\Height);
\coordinate (C) at (0,0,\Height);
\coordinate (D) at (\Depth,0,0);
\coordinate (E) at (\Depth,\Width,0);
\coordinate (F) at (\Depth,\Width,\Height);
\coordinate (G) at (\Depth,0,\Height);
\draw[fill=whitegray!20] (O) -- (C) -- (G) -- (D) -- cycle;
\draw[fill=gray!20] (O) -- (A) -- (E) -- (D) -- cycle;
\draw[fill=gray!10] (O) -- (A) -- (B) -- (C) -- cycle;
\draw[fill=gray20,opacity=0.4] (D) -- (E) -- (F) -- (G) -- cycle;
\draw[fill=gray!5,opacity=0.6] (C) -- (B) -- (F) -- (G) -- cycle;
\draw[fill=gray!5,opacity=0.8] (A) -- (B) -- (F) -- (E) -- cycle;
\end{tikzpicture}
\end{document}


• I've taken the liberty of indenting all lines of code by four spaces, to let the site's software pretty-print them as computer code. – Mico Jul 20 '15 at 22:40
• @Mico did you do this by hand? or using {} in toolsbar? – touhami Jul 20 '15 at 22:59

Something like this?

I defined a command \FillCube with an optional argument taking values between 1 and 0, controlling up to where the cube is filled. The default is 1, meaning full (0 means empty).

The code:

\documentclass[varwidth=50cm,border=5pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}

\newcommand{\Depth}{2}
\newcommand{\Height}{2}
\newcommand{\Width}{2}

\newcommand\FillCube[1][1]{
\coordinate (O) at (0,0,0);
\coordinate (A) at (0,\Width,0);
\coordinate (B) at (0,\Width,\Height);
\coordinate (C) at (0,0,\Height);
\coordinate (D) at (\Depth,0,0);
\coordinate (E) at (\Depth,\Width,0);
\coordinate (F) at (\Depth,\Width,\Height);
\coordinate (G) at (\Depth,0,\Height);
\ifx#10\relax
\else
\draw[fill=blue!40] (O) -- (C) -- (G) -- (D) -- cycle;
\fi
\draw[fill=gray!20,opacity=0.5] (O) -- (C) -- (G) -- (D) -- cycle;
\draw[fill=gray!20] (O) -- (A) -- (E) -- (D) -- cycle;
\draw[fill=blue!40] (O) -- ( $(O)!#1!(A)$ ) -- ( $(D)!#1!(E)$ ) -- (D) -- cycle;
\draw[fill=gray!20] (O) -- (A) -- (B) -- (C) -- cycle;
\draw[fill=blue!40] (O) -- ( $(O)!#1!(A)$ ) -- ( $(C)!#1!(B)$ ) -- (C) -- cycle;
\draw[fill=gray!20,opacity=0.4] (D) -- (E) -- (F) -- (G) -- cycle;
\draw[fill=blue!40,opacity=0.4] (D) -- ( $(D)!#1!(E)$ ) -- ( $(G)!#1!(F)$ ) -- (G) -- cycle;
\draw[fill=gray!20,opacity=0.6] (C) -- (B) -- (F) -- (G) -- cycle;
\draw[fill=blue!40,opacity=0.6] (C) -- ( $(C)!#1!(B)$ ) -- ( $(G)!#1!(F)$ ) -- (G) -- cycle;
\if#10\relax
\else
\draw[fill=blue!40,opacity=0.6] ( $(O)!#1!(A)$ ) -- ( $(C)!#1!(B)$ ) -- ( $(G)!#1!(F)$ ) -- ( $(D)!#1!(E)$ ) -- cycle;
\fi
}
\begin{document}

\begin{tikzpicture}
\foreach[count=\xi] \Valor in {1,0.8,...,0.2,0}
{
\begin{scope}[xshift=\xi*3cm]
\FillCube[\Valor]
\end{scope}
}
\end{tikzpicture}\par\bigskip

\begin{tikzpicture}
\FillCube
\begin{scope}[xshift=3cm]
\FillCube[0.5]
\end{scope}
\begin{scope}[xshift=6cm]
\FillCube[0]
\end{scope}
\end{tikzpicture}

\end{document}


An animation:

The code for the animation:

\documentclass{beamer}
\usepackage{tikz}
\usetikzlibrary{calc}

\newcommand{\Depth}{2}
\newcommand{\Height}{2}
\newcommand{\Width}{2}

\newcommand<>\FillCube[1][1]{
\only#2{\coordinate (O) at (0,0,0);
\coordinate (A) at (0,\Width,0);
\coordinate (B) at (0,\Width,\Height);
\coordinate (C) at (0,0,\Height);
\coordinate (D) at (\Depth,0,0);
\coordinate (E) at (\Depth,\Width,0);
\coordinate (F) at (\Depth,\Width,\Height);
\coordinate (G) at (\Depth,0,\Height);
\ifx#10\relax
\else
\draw[fill=blue!40] (O) -- (C) -- (G) -- (D) -- cycle;
\fi
\draw[fill=gray!20,opacity=0.5] (O) -- (C) -- (G) -- (D) -- cycle;
\draw[fill=gray!20] (O) -- (A) -- (E) -- (D) -- cycle;
\draw[fill=blue!40] (O) -- ( $(O)!#1!(A)$ ) -- ( $(D)!#1!(E)$ ) -- (D) -- cycle;
\draw[fill=gray!20] (O) -- (A) -- (B) -- (C) -- cycle;
\draw[fill=blue!40] (O) -- ( $(O)!#1!(A)$ ) -- ( $(C)!#1!(B)$ ) -- (C) -- cycle;
\draw[fill=gray!20,opacity=0.4] (D) -- (E) -- (F) -- (G) -- cycle;
\draw[fill=blue!40,opacity=0.4] (D) -- ( $(D)!#1!(E)$ ) -- ( $(G)!#1!(F)$ ) -- (G) -- cycle;
\draw[fill=gray!20,opacity=0.6] (C) -- (B) -- (F) -- (G) -- cycle;
\draw[fill=blue!40,opacity=0.6] (C) -- ( $(C)!#1!(B)$ ) -- ( $(G)!#1!(F)$ ) -- (G) -- cycle;
\if#10\relax
\else
\draw[fill=blue!40,opacity=0.6] ( $(O)!#1!(A)$ ) -- ( $(C)!#1!(B)$ ) -- ( $(G)!#1!(F)$ ) -- ( $(D)!#1!(E)$ ) -- cycle;
\fi}
}

\begin{document}

\begin{frame}
\centering
\begin{tikzpicture}
\foreach[count=\xi] \Valor in {1,0.975,...,0.025,0}
{\FillCube<\xi>[\Valor]}
\end{tikzpicture}
\end{frame}

\end{document}


On a terminal (using ImageMagick):

convert -verbose -delay 12 -loop 0 -density 300 a.pdf a.gif

• Nice. The pictures are even prettier if the cube is standing on a vertex (long diagonal vertical) while being filled (not what the OP has asked for ...). – Ethan Bolker Jul 20 '15 at 23:55
• @EthanBolker Thanks. Good idea. I'll give it a try tomorrow. – Gonzalo Medina Jul 21 '15 at 1:23
• @EthanBolker Not very practical, though... – cfr Jul 21 '15 at 1:24
• @cfr Since I'm a mathematician, that's the best reason to do it :-) – Gonzalo Medina Jul 21 '15 at 1:25
• @WChargin It's beamer syntax allowing to define commands (there's a similar syntax for environments) which are overlay-aware. Further details in the beamer documentation under \newcommand. – Gonzalo Medina Jul 21 '15 at 17:06