5

Starting from this link with this MWE

enter image description here

\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{perspective}
\makeatletter
\tikzset{recycle bounding box/.style={%
execute at end picture={%
\immediate\write\@mainaux{\xdef\string\tikz@bbox@figbb@#1{%
{\the\pgf@picminx,\the\pgf@picminy,\the\pgf@picmaxx,\the\pgf@picmaxy}}\relax}},
execute at begin picture={%
\ifcsname tikz@bbox@figbb@#1\endcsname
 \edef\figbb{\csname tikz@bbox@figbb@#1\endcsname}%
 \path ({\figbb[0]},{\figbb[1]})  ({\figbb[2]},{\figbb[3]});
\fi}}}  
\makeatother
\tikzset{pics/3d layer/.style={code={
 \def\pv##1{\pgfkeysvalueof{/tikz/3d layer/##1}}
 \tikzset{/tikz/3d layer/.cd,#1}
 \path[3d layer/all,3d layer/fore] (-\pv{x}/2,-\pv{y}/2,-\pv{z}/2)
    -- (\pv{x}/2,-\pv{y}/2,-\pv{z}/2)
    -- (\pv{x}/2,-\pv{y}/2,\pv{z}/2)
    -- (-\pv{x}/2,-\pv{y}/2,\pv{z}/2) -- cycle;
 \path[3d layer/all,3d layer/side] (\pv{x}/2,-\pv{y}/2,-\pv{z}/2)
    -- (\pv{x}/2,\pv{y}/2,-\pv{z}/2)
    -- (\pv{x}/2,\pv{y}/2,\pv{z}/2)
    -- (\pv{x}/2,-\pv{y}/2,\pv{z}/2) -- cycle;
 \path[3d layer/all,3d layer/top] (-\pv{x}/2,-\pv{y}/2,\pv{z}/2)
    -- (\pv{x}/2,-\pv{y}/2,\pv{z}/2)
    -- (\pv{x}/2,\pv{y}/2,\pv{z}/2)
    -- (-\pv{x}/2,\pv{y}/2,\pv{z}/2) -- cycle;
 }},
 3d layer/.cd,x/.initial=2,y/.initial=2,z/.initial=0.2,
 fore/.style={},
 side/.style={},
 top/.style={},
 all/.style={draw,fill=blue!20},
 }
\begin{document}
\foreach \Z in {1,...,40}
{\begin{tikzpicture}[line join=round,recycle bounding box=A]
\begin{scope}[3d view={30}{10},declare function={mu=1+\Z/20;
    zboundary=0.1;zfluid=0.2;}]
 \def\Nlayer{6} 
 \path pic{3d layer={all/.append style={fill=gray!60},z=zboundary}}
 foreach \Y in {0,...,\Nlayer}
 {(0.1*\Y/mu,0,zboundary+\Y*zfluid) pic{3d layer={z=zfluid}}}
 (0.1*\Nlayer/mu,0,\Nlayer*zfluid+zfluid) 
 pic{3d layer={all/.append style={fill=gray!60},z=zboundary}}
 ;
\end{scope} 
\end{tikzpicture}}
\end{document}

I would like the layers (or sections) of the fluid to be all light blue and less thick and the movement to be from left to right and not vice versa. I would also like there to be as per the first illustration the labels F (magenta vector), A, v (green vector) and the height. How is it possible to realize this? Thank you.

enter image description here

Sebastiano
  • 54,118
  • 1
    Aren't they already lightblue? Or do you mean the top and bottom section as well? Are they part of “fluid”? – Qrrbrbirlbel Sep 14 '23 at 14:10
  • @Qrrbrbirlbel Yes I meant the upper and lower sections with the same color because they were part of the same fluid. – Sebastiano Sep 14 '23 at 18:35
  • Ah, alright, then just remove the 3d layer/layer … definitions below. Though, the first two and the last two layers will stay stuck together, is that right? – Qrrbrbirlbel Sep 14 '23 at 20:29
  • @Qrrbrbirlbel Your code is perfect. I don't want to touch it. – Sebastiano Sep 14 '23 at 20:32

1 Answers1

8

The thickness of each layer is determined by the value /tikz/3d layer/z. Simply setting the initial value to 0.1 already makes the layers thinner.

I converted the stacking of the layers into one loop that goes through all sections, even the first and the last. Changing the look of one layer i can be controlled by the key 3d layer/layer i.

The layers now will be drawn between z = 0 and z = /tikz/3d layer/z. This means the bottom of the layer is at the specified coordinate of the pic. The top of the layer will be named pic name-top which we can reference for the next layer.
(This is also why I define a layer-1-top coordinate so that the layer 0 has a reference.)

I've reimplemented the bounding box spiel, it works very similar to my node families but uses the \AtEndDocument hook (instead of the execute at end picture) so that we

  • only write one entry
  • but the max one for the current compilation

into the AUX file.

Code

% arara: animate: {delay: 20, density: 600, options: ['-alpha', 'remove']}
\documentclass[tikz, border=3mm]{standalone}
\usetikzlibrary{3d, arrows.meta, bending, calc, perspective}
\makeatletter
\tikzset{
  max bounding box/.style={
    execute at end picture={%
      \pgfutil@IfUndefined{tikz@maxbb@#1@prev}{%
        \AtEndDocument{\immediate\write\pgfutil@auxout{%
          \noexpand\expandafter\gdef\noexpand\csname tikz@maxbb@#1@next\endcsname
            {\csname tikz@maxbb@#1@prev\endcsname}}}%
        \tikz@@maxbb@set{#1}%
      }{%
        \expandafter\expandafter\expandafter\tikz@@maxbb@get
          \csname tikz@maxbb@#1@prev\endcsname
        \tikz@@maxbb@set{#1}}%
      \pgfutil@IfUndefined{tikz@maxbb@#1@next}{}{%
        \expandafter\expandafter\expandafter\tikz@@maxbb@get
          \csname tikz@maxbb@#1@next\endcsname}}}}
\def\tikz@@maxbb@get#1#2#3#4{%
  \ifdim#1<\pgf@picminx\global\pgf@picminx#1\fi
  \ifdim#3>\pgf@picmaxx\global\pgf@picmaxx#3\fi
  \ifdim#2<\pgf@picminy\global\pgf@picminy#2\fi
  \ifdim#4>\pgf@picmaxy\global\pgf@picmaxy#4\fi}
\def\tikz@@maxbb@set#1{%
  \expandafter\xdef\csname tikz@maxbb@#1@prev\endcsname
      {{\the\pgf@picminx}{\the\pgf@picminy}{\the\pgf@picmaxx}{\the\pgf@picmaxy}}}%
\makeatother
\tikzset{% https://tex.stackexchange.com/a/688676
  Measure/.tip={>[round, scale=.65, sep=+0pt +.5]},
  dim line distance/.initial=.2cm, dim line all/.code=,
  % instead of the arrow tip Bar, we use a negative shorten
  % so that the arrow still looks acceptable after the transformation
  dim line delim/.style={dim line all, draw, shorten >=+-3\pgflinewidth},
  dim line style/.style={dim line all, -Measure},
  dim line text/.style={midway, auto=false},
  pics/dim line/.style args={#1--#2}{code={
    \path[path only] ($(#1)!\pgfkeysvalueof{/tikz/dim line distance}!90:(#2)$)
      coordinate(dim line@1) -- node[dim line text, style/.expand once=
        \tikzpictextoptions, alias=dim line@text] {\tikzpictext}
      ($(#2)!\pgfkeysvalueof{/tikz/dim line distance}!-90:(#1)$)
      coordinate (dim line@2);
    \draw[dim line delim, line to] (#1) to (dim line@1);
    \draw[dim line delim, line to] (#2) to (dim line@2);
    \path[line to] (dim line@text) edge[dim line style] (dim line@1)
                                   edge[dim line style] (dim line@2);}}}
\tikzset{
  3d layer/.pic={% • no argument, don't need it,
                 %   we can set keys directly in the options of the pic
                 % • define 3×4 + 1 coordinates:
                 %   better would be anchors but that's another topic:
                 %   https://tex.stackexchange.com/a/676090
                 % • z = 0 is at the bottom
      \def\pv##1{\pgfkeysvalueof{/tikz/3d layer/##1}}
      \path[3d layer/all, 3d layer/fore]
          (-\pv{x}/2, -\pv{y}/2,       0) coordinate (-foreBL)
       -- ( \pv{x}/2, -\pv{y}/2,       0) coordinate[alias=-sideBL] (-foreBR)
       -- ( \pv{x}/2, -\pv{y}/2,  \pv{z})
         coordinate[alias=-sideTL, alias=-topBR] (-foreTR)
       -- (-\pv{x}/2, -\pv{y}/2,  \pv{z}) coordinate[alias=-topBL] (-foreTL)
       -- cycle;
      \path[3d layer/all, 3d layer/side] (-sideBL)
       -- ( \pv{x}/2,  \pv{y}/2,       0) coordinate (-sideBR)
       -- ( \pv{x}/2,  \pv{y}/2,  \pv{z}) coordinate[alias=-topTR] (-sideTR)
       -- (-sideTL) -- cycle;
      \path[3d layer/all, 3d layer/top]  (-topBL) -- (-topBR) -- (-topTR)
       -- (-\pv{x}/2,  \pv{y}/2,  \pv{z}) coordinate (-topTL) -- cycle;
      \coordinate (-top) at (0, 0, \pv{z});},
 3d layer/.cd, x/.initial=2, y/.initial=2, z/.initial=0.1,
 fore/.code=, side/.code=, top/.code=, % no ops
 all/.style={draw=blue!80, fill=blue!20},
 top and bottom/.style={
   /tikz/3d layer/layer 0/.append style={3d layer/all/.append style={#1}},
   /tikz/3d layer/layer \totalLayers/.style={3d layer/all/.append style={#1}}}}
\begin{document}
\newcommand*\totalLayers{9}            % i.e. 10
\newcommand*\rightShiftPerPicture{0.005}%
\tikzset{
  3d layer/top and bottom={fill=gray!80},
%  3d layer/top and bottom={fill=blue!60},
  declare function={shiftInPic(\layer,\pic)=%
    (\layer>1 && \layer<\totalLayers)*\rightShiftPerPicture*\pic;},
}
\foreach \picture in {0, ..., 60}{
\begin{tikzpicture}[
  line join=round, line cap=round, >=Latex, arrows={[scale=.75]},
  max bounding box=fluids]
\begin{scope}[3d view={30}{10}] % scope not needed but okay
\coordinate (layer-1-top);
\foreach[count=\prevLayer from -1] \layer in {0, ..., \totalLayers}
  \pic[
    3d layer/layer \layer/.try,
    shift={({shiftInPic(\layer, \picture)}, 0, 0)},
  ] (layer\layer) at (layer\prevLayer-top) {3d layer};

% Apply transformation in the “fore” canvas, % the value (here 0) doesn't even matter because we always reference a fixed point \tikzset{canvas is xz plane at y=0, transform shape} % nodes as well \draw[->, thick, draw=green!75!black] (layer9-foreBR) -- +(right:2) node[below left]{$\mathbf v$}; \path % or: \coordinate (@) at ($(…-topBL)!.4!(…-topTL)$); with calc library (layer\totalLayers-topBL) -- (layer\totalLayers-topTL) coordinatepos=.4;

\draw[<-, thick, draw=red] (@) -- node[above]{$\mathbf F$} +(left:1); \node[below right] at (layer0-foreBR) {$\mathbf v = 0$};

\draw[<-] (layer\totalLayers-top) to[bend right] ++ (165:.4) to[bend left] ++(165:.4) node[above]{$A$};

\path[] (layer\totalLayers-foreBL) |- coordinate[midway] (@) (layer0-foreTL); \pic[ pic text=$L$, pic text options={fill opacity=.5, text opacity=1, fill=white, rounded corners=+3pt, inner sep=+.15em, outer sep=+.15em}, ] {dim line=@--layer\totalLayers-foreBL}; \end{scope} \end{tikzpicture}} \end{document}

Outputs

JamesT
  • 3,169
Qrrbrbirlbel
  • 119,821
  • 1
    This looks great! – AlexG Sep 14 '23 at 16:39
  • I thank you immensely for your work. I hope it can be appreciated by other users as well. Thank you very much. +1 Excellent. – Sebastiano Sep 14 '23 at 18:38
  • How to export LaTeX output to animated gif? – Sebastiano Sep 14 '23 at 18:41
  • 1
    @Sebastiano I'm using ImageMagick with the arara rule: % arara: animate: {delay: 20, density: 600, options: ['-alpha', 'remove']}. The -alpha remove makes for a better anti-aliasing since GIF doesn't support anti-aliasing with transparency. I haven't found a good way to convert it to a modern standard like webm – maybe via svg? – Qrrbrbirlbel Sep 14 '23 at 20:28
  • @Qrrbrbirlbel I thank you again for your clarification. I don't use ImageMagik because in the new computer I have I don't want to install new programs. But on the web is there anything that converts latex document to gif? – Sebastiano Sep 14 '23 at 20:30
  • I have tried but it creates a blank document for me with the tools on line. Could you please bold F, v, and re-enter a new animated gif? Thank you and sorry for the trouble. – Sebastiano Sep 14 '23 at 20:37
  • @Qrrbrbirlbel Your thoughts are correct. I would F, v in bold font. Can you provide to edit your answer and the image? Thanks. – Sebastiano Sep 14 '23 at 20:57
  • 2
    @Sebastiano The top and bottom layers are rigid walls, not liquid, and should therefore be filled with a different colour (gray as in OP would be good). Otherwise, the graphic is misleading. The no-slip condition of rigid walls is correctly captured, as the adjacent, liquid layers move at the same velocity as the walls. But the colour of the outer layers (walls) should definitely be changed. – AlexG Sep 15 '23 at 06:33
  • @AlexG Thank you for your advice. Can you change the color of the walls, please? – Sebastiano Sep 15 '23 at 07:53
  • Qrrbrbirlbel should better do this, as he is the post owner. – AlexG Sep 15 '23 at 07:57
  • @Qrrbrbirlbel Hi, can you change another your code, please :-(, after that you have read the comment of AlexG, Thank you very much. – Sebastiano Sep 15 '23 at 08:00
  • 2
    @Sebastiano See my update. I've just thought of manually adding slant=.1 to the arrow tips of the L measure but the difference is very small anyway. – Qrrbrbirlbel Sep 15 '23 at 17:13
  • 1
    @Qrrbrbirlbel Immensely grateful. – Sebastiano Sep 15 '23 at 18:31