7

I am trying to draw a cylindrical tank that has water in it, using tikz. Here is what I have so far:

\documentclass[a4paper, 12pt]{article}
    \usepackage{pgfplots}
    \pgfplotsset{compat=1.15}
    \usepgfplotslibrary{polar}
    \usepgflibrary{shapes.geometric}
    \usetikzlibrary{calc}

\begin{document}

\begin{figure}[ht]

\centering

\begin{tikzpicture}

\node[draw, cylinder, rotate=90, shape aspect=4, minimum height=4cm, minimum 
width=8cm, fill = blue, fill opacity = 0.2, blue] {};

\node[draw, cylinder, rotate=90, shape aspect=4, minimum height=6cm, minimum 
width=8cm, thick] (A) {};

\draw[dashed, thick]
    let \p1 = ($ (A.after bottom) - (A.before bottom) $),
        \n1 = {0.5*veclen(\x1,\y1)-\pgflinewidth},
        \p2 = ($ (A.bottom) - (A.after bottom)!.5!(A.before bottom) $),
        \n2 = {veclen(\x2,\y2)-\pgflinewidth}
  in
    ([xshift=-\pgflinewidth] A.before bottom) arc [start angle=0, end 
angle=180,
    x radius=\n1, y radius=\n2];

\end{tikzpicture}

\caption{The tank.}
\label{fig:tank}

\end{figure}

\end{document}

This is the result:

enter image description here

I want the blue part to be shifted down so that it is at the same level as the bottom of the black one.

Any suggestions to this solution, or to making my code more efficient, would be great!

7

I would use tikz-3dplot for it, in particular if you are considering adding more 3d-like elements. The following has 4 parameters, one view angle which is set to 100, a radius \R, the height of the water \HW and the height of the cylinder \HC.

\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{tikz-3dplot}
\usepgflibrary{shapes.geometric}
\usetikzlibrary{calc}
\begin{document}
\tdplotsetmaincoords{100}{0}
\begin{tikzpicture}[tdplot_main_coords]
\pgfmathsetmacro{\R}{4}
\pgfmathsetmacro{\HW}{4}
\pgfmathsetmacro{\HC}{6}
% water
\fill[blue!40] plot[variable=\x,domain=0:180,smooth] ({\R*cos(\x)},{\R*sin(\x)},0)
-- 
plot[variable=\x,domain=180:360,smooth] ({\R*cos(\x)},{\R*sin(\x)},\HW)
-- cycle;
\draw[blue] plot[variable=\x,domain=0:360,smooth,samples=51]
({\R*cos(\x)},{\R*sin(\x)},\HW);
% "invisible" lined
\draw[dashed] plot[variable=\x,domain=180:360,smooth]
({\R*cos(\x)},{\R*sin(\x)},0);
% visible cylinder lines
\draw plot[variable=\x,domain=0:180,smooth]
({\R*cos(\x)},{\R*sin(\x)},0) 
-- 
plot[variable=\x,domain=180:360,smooth]
({\R*cos(\x)},{\R*sin(\x)},\HC) -- cycle;
\draw plot[variable=\x,domain=0:180,smooth]
({\R*cos(\x)},{\R*sin(\x)},\HC); 
\end{tikzpicture}
\end{document}

enter image description here

The meaning of the view angle is illustrated by this animation.

\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{tikz-3dplot}
\usepgflibrary{shapes.geometric}
\usetikzlibrary{calc}
\begin{document}
\foreach \X in {0,10,...,350}
{\tdplotsetmaincoords{120+30*sin(\X)}{0}
\begin{tikzpicture}
\pgfmathsetmacro{\R}{4}
\pgfmathsetmacro{\HW}{4}
\pgfmathsetmacro{\HC}{6}
\path[use as bounding box] (-1.1*\R,-0.75*\HC) rectangle (1.1*\R,1.25*\HC);
\begin{scope}[tdplot_main_coords]
% water
\fill[blue!40] plot[variable=\x,domain=0:180,smooth] ({\R*cos(\x)},{\R*sin(\x)},0)
-- 
plot[variable=\x,domain=180:360,smooth] ({\R*cos(\x)},{\R*sin(\x)},\HW)
-- cycle;
\draw[blue] plot[variable=\x,domain=0:360,smooth,samples=51]
({\R*cos(\x)},{\R*sin(\x)},\HW);
% "invisible" lined
\draw[dashed] plot[variable=\x,domain=180:360,smooth]
({\R*cos(\x)},{\R*sin(\x)},0);
% visible cylinder lines
\draw plot[variable=\x,domain=0:180,smooth]
({\R*cos(\x)},{\R*sin(\x)},0) 
-- 
plot[variable=\x,domain=180:360,smooth]
({\R*cos(\x)},{\R*sin(\x)},\HC) -- cycle;
\draw plot[variable=\x,domain=0:180,smooth]
({\R*cos(\x)},{\R*sin(\x)},\HC); 
\end{scope}
\end{tikzpicture}}
\end{document}

enter image description here

6

you need to define anchors of your cylinders at their bottoms ...

\documentclass[a4paper, 12pt]{article}
    %\usepackage{pgfplots}
    %\pgfplotsset{compat=1.15}
    %\usepgfplotslibrary{polar}
    \usepackage{tikz}
    \usetikzlibrary{calc,
                    positioning, 
                    shapes.geometric}

\begin{document}
    \begin{figure}[ht]
    \centering
\begin{tikzpicture}[
   node distance = 0pt,
valj/.style args = {#1/#2}{draw, cylinder, shape aspect=4, shape border rotate=90,
                           fill=#2, fill opacity=0.2,
                           minimum height=#1, minimum width=8cm,
                           outer sep=0pt, anchor=bottom,    % <--- added
                           node contents={}
                           }
                    ]
\node (A) [valj=60mm/white];
\node (B) [valj=40mm/blue,
           above=of A.bottom];  % <--- positioning of cylinder
\draw[dashed]
    let \p1 = ($ (A.after bottom) - (A.before bottom) $),
        \n1 = {0.5*veclen(\x1,\y1)-\pgflinewidth},
        \p2 = ($ (A.bottom) - (A.after bottom)!.5!(A.before bottom) $),
        \n2 = {veclen(\x2,\y2)}
    in (A.before bottom) arc [start angle=0, end angle=180,
                              x radius=\n1, y radius=\n2];
\end{tikzpicture}
    \caption{The tank.}
\label{fig:tank}
    \end{figure}
\end{document}

enter image description here

2

I have figured out a solution. In the square brackets containing the parameters for the first cylinder (the one drawing the water), we need only add xshift = -0.75cm. Since the height of the outer cylinder is 6cm and the height of the inner is 4.5cm, so the difference in height is 1.5cm. Since both cylinders are centered at the same spot, the height of the gaps above and below the blue are 0.75cm each, so we just have to shift it down that distance. I was at first curious as to yshift did not work, but then I realized that the cylinder is rotated in the beginning by 90 degrees, so that is probably the reason.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.