10

I am attempting to make the following picture enter image description here But I would like some elements modified which I have done in the following pstricks image. I do not know how to center text, do multiline text for "material having\thermal conductivity $k$", color the boxes, and add a large curvey arrow. I would like the box labelled $T_2$ to be gray or dark gray and the box labelled $T_1$ to be white. I would like the middle box to be a gradient from gray to white. Also I would like to align the text to the xz plane but it does not seem to work for me.

Here is my code so far:

\documentclass[english]{article}
\usepackage[T1]{fontenc}

\makeatletter
\usepackage{pstricks}
\usepackage{pst-3dplot}

\makeatother

\usepackage{babel}
\begin{document}
\begin{pspicture}
\psset{Alpha=160,Beta=20}
\pstThreeDBox(0,0,0)(1,0,0)(0,4,0)(0,0,2) 
\pstThreeDBox(1,0.5,0.5)(6,0,0)(0,0,1)(0,3,0)
\pstThreeDBox(7,0,0)(1,0,0)(0,4,0)(0,0,2) 
\pstPlanePut[plane=xz](0.5,0,1){{$T_2$}} 
\pstPlanePut[plane=xz,planecorr=xzrot](7.5,0,1){{$T_1$}} 
\pstPlanePut[plane=xz,planecorr=xzrot](1,0,-0.5){{$x_1$}}
\pstPlanePut[plane=xz,planecorr=xzrot](7,0,-0.5){{$x_1$}} 
\pstThreeDSquare(4,0.5,0.5)(0,0,1)(0,3,0)
\pstThreeDLine(4,2,1)(6,2,3)
\pstPlanePut[plane=xz](6,2,3.2){{Area $A$}} 
\pstPlanePut[plane=xz](4,-0.5,0){\fbox{$T_2>T_1$}} 
\end{pspicture}
\end{document}

The code produces the following image: enter image description here

(I wouldn't mind a tikz/tikz-3d solution either)

sab hoque
  • 2,627

1 Answers1

16

It is not too difficult to write commands that work in TikZ but are somewhat reminiscent of the PSTricks commands you are using. Note, however, at present these only work for view angles close to what you seem to want.

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{3d,arrows.meta,positioning}
\pgfkeys{tikz/.cd,
box color/.code={\xdef\tkzThreedBoxColor{#1}},
box color=white
}
\def\parsexy(#1,#2,#3){(#1,#2)}
\def\parsexz(#1,#2,#3){(#1,#3)}
\def\parseyz(#1,#2,#3){(#2,#3)}
\def\parsex(#1,#2,#3){#1}
\def\parsey(#1,#2,#3){#2}
\def\parsez(#1,#2,#3){#3}

\newcommand{\tkzThreeDBox}[5][white]{\tikzset{#1}
\edef\temp{%
\noexpand\filldraw[#1,fill=\tkzThreedBoxColor!40,canvas is yz plane at x=\parsex#3+\parsex#2] 
\parseyz#2 rectangle (\parsey#4+\parsey#2,\parsez#5+\parsez#2);
\noexpand\filldraw[#1,fill=\tkzThreedBoxColor!30,canvas is xz plane at y=\parsey#4+\parsey#2] 
\parsexz#2 rectangle (\parsex#3+\parsex#2,\parsez#5+\parsez#2);
\noexpand\filldraw[#1,fill=\tkzThreedBoxColor!50,canvas is xy plane at z=\parsez#5+\parsez#2] 
\parsexy#2 rectangle (\parsex#3+\parsex#2,\parsey#4+\parsey#2);
}
\temp
}
\begin{document}
\begin{tikzpicture}[x={(1,0)},z={(-1/3,-1/4)},y={(0,1)},font=\sffamily]
\tkzThreeDBox[box color=orange,draw=none]{(0,0,0)}{(1,0,0)}{(0,2,0)}{(0,0,4)}
\fill[orange!80,canvas is yz plane at x=1] (0.5,0.5) coordinate(X) rectangle ++(1,3);
\shade[opacity=0.7,left color=orange!80,right color=blue!50!cyan!60!white,canvas is xy plane at z=0.5]
 (1,0.5) rectangle ++(6,1);
\shade[opacity=0.7,left color=orange!80,right color=blue!50!cyan!60!white,canvas is xz plane at y=0.5]
 (1,0.5) rectangle ++(6,3);
\shadedraw[draw=red!50,left color=orange!15,right color=orange!40] 
(1.5,0.5,1) --  (1.5,1,1) -- plot[variable=\x,domain=0:1.5,samples=60] 
(\x+1.5,{1+0.1*sin(720*\x/1.5)},1) --++(0,0.25,0) -- ++(0.5,-0.5,0)
-- ++(-0.5,-0.5,0) --++(0,0.25,0)
 -- plot[variable=\x,domain=1.5:0,samples=60] 
(\x+1.5,{0.5+0.1*sin(720*\x/1.5)},1) -- cycle;
\draw[dashed,draw=orange!20,thick] (X) -- ++(6,0,0);
\fill[blue!50!cyan!60!white,opacity=0.6,canvas is yz plane at x=4] (0.5,0.5) rectangle ++(1,3);
\tkzThreeDBox[box color=white,fill opacity=0,draw=orange!20,thick]{(1,0.5,0.5)}{(6,0,0)}{(0,1,0)}{(0,0,3)}
\tkzThreeDBox[box color=cyan,draw=none]{(7,0,0)}{(1,0,0)}{(0,2,0)}{(0,0,4)}
\node at (0.5,1,4) {$T_2$};
\node at (1,0.9,2) {$Q$};
\node at (7.5,1,4) {$T_1$};
\draw[{Bar}{Latex}-{Latex}{Bar}] (1,0,4) -- (7,0,4)
node[midway,fill=white](d){$d$};
\node[below=1pt of d,draw] {$T_2>T_1$};
\node[anchor=south,align=center] (mat) at (2,2.2,0) {Material having\\ thermal
conductivity $k$};
\node[anchor=south,align=center] (area) at (5,2.2,0) {Area 51};
\path (mat) -- (2.5,1,1) coordinate (x3) coordinate[pos=1/3] (x1) coordinate[pos=2/3] (x2);
\draw[-Latex] (mat) to[out=-90,in=70] (x1) to[out=-110,in=90] (x2)
to[out=-90,in=100] (x3);
\draw[-Latex] (area) to[out=-90,in=30] (4,1,0.5);
\end{tikzpicture}
\end{document}

enter image description here

Here is a slightly different way to draw the thing. (I also don't know why there are so many \ifnums in, if you rotate the thing too much it does not look good at all, so please don't ;-) And as usual one has to do an animation.

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{3d,arrows.meta,positioning,calc}
\pgfkeys{tikz/.cd,
box color/.code={\xdef\tkzThreedBoxColor{#1}},
box color=white
}
\makeatletter
%from https://tex.stackexchange.com/a/375604/121799
% spherical coordinates along y axis
\define@key{y sphericalkeys}{radius}{\def\myradius{#1}}
\define@key{y sphericalkeys}{theta}{\def\mytheta{#1}}
\define@key{y sphericalkeys}{phi}{\def\myphi{#1}}
\tikzdeclarecoordinatesystem{y spherical}{% 
    \setkeys{y sphericalkeys}{#1}%
    \pgfpointxyz{\myradius*sin(\mytheta)*cos(\myphi)}{\myradius*cos(\mytheta)}{\myradius*sin(\mytheta)*sin(\myphi)}}
\makeatother
% https://tex.stackexchange.com/a/438695/121799
\tikzset{rotate axes about y axis/.code={
\path (y spherical cs:radius=1,theta=90,phi=0+#1) coordinate(xpp)
(y spherical cs:radius=1,theta=00,phi=90+#1) coordinate(ypp) 
(y spherical cs:radius=1,theta=90,phi=90+#1) coordinate(zpp);
},
pitch/.style={rotate axes about y axis=#1,x={(xpp)},y={(ypp)},z={(zpp)}}}
\def\parsexy(#1,#2,#3){(#1,#2)}
\def\parsexz(#1,#2,#3){(#1,#3)}
\def\parseyz(#1,#2,#3){(#2,#3)}
\def\parsex(#1,#2,#3){#1}
\def\parsey(#1,#2,#3){#2}
\def\parsez(#1,#2,#3){#3}

\newcommand{\tkzThreeDBox}[5][white]{\tikzset{#1}
\path let \p1=(0,0,1) in \pgfextra{\pgfmathtruncatemacro{\zxproj}{sign(\x1)}
\pgfmathtruncatemacro{\zyproj}{sign(\y1)}
\xdef\zxproj{\zxproj}\xdef\zyproj{\zyproj}
};
\path let \p1=(1,0,0) in \pgfextra{\pgfmathtruncatemacro{\xxproj}{sign(\x1)}
\pgfmathtruncatemacro{\xyproj}{sign(\y1)}
\xdef\xxproj{\xxproj}\xdef\xyproj{\xyproj}
};
\ifnum\zyproj=1
% front
\filldraw[#1,fill=\tkzThreedBoxColor!20] 
#2 -- ++ #3 -- ++ #4 -- ++ ($-1*#3$) -- cycle;
\else
% back
\filldraw[#1,fill=\tkzThreedBoxColor!20] 
($#2+#5$) -- ++ #3 -- ++ #4 -- ++ ($-1*#3$) -- cycle;
\fi
\ifnum\zxproj=1
% bottom
\filldraw[#1,fill=\tkzThreedBoxColor!30] 
#2 -- ++ #3 -- ++ #5 -- ++ ($-1*#3$) -- cycle;
\ifnum\xxproj=1
% right
\filldraw[#1,fill=\tkzThreedBoxColor!40] 
($#2+#3$) -- ++ #4 -- ++ #5 -- ++ ($-1*#4$) -- cycle;
% left
\filldraw[#1,fill=\tkzThreedBoxColor!40] 
#2 -- ++ #4 -- ++ #5 -- ++ ($-1*#4$) -- cycle;
\else
% left
\filldraw[#1,fill=\tkzThreedBoxColor!40] 
#2 -- ++ #4 -- ++ #5 -- ++ ($-1*#4$) -- cycle;
% right
\filldraw[#1,fill=\tkzThreedBoxColor!40] 
($#2+#3$) -- ++ #4 -- ++ #5 -- ++ ($-1*#4$) -- cycle;
\fi
% top
\filldraw[#1,fill=\tkzThreedBoxColor!30] 
($#2+#4$) -- ++ #3 -- ++ #5 -- ++ ($-1*#3$) -- cycle;
\else
% bottom
\filldraw[#1,fill=\tkzThreedBoxColor!30] 
#2 -- ++ #3 -- ++ #5 -- ++ ($-1*#3$) -- cycle;
% left
\filldraw[#1,fill=\tkzThreedBoxColor!40] 
#2 -- ++ #4 -- ++ #5 -- ++ ($-1*#4$) -- cycle;
% right
\filldraw[#1,fill=\tkzThreedBoxColor!40] 
($#2+#3$) -- ++ #4 -- ++ #5 -- ++ ($-1*#4$) -- cycle;
% top
\filldraw[#1,fill=\tkzThreedBoxColor!30] 
($#2+#4$) -- ++ #3 -- ++ #5 -- ++ ($-1*#3$) -- cycle;
\fi
\ifnum\zyproj=1
% back
\filldraw[#1,fill=\tkzThreedBoxColor!20] 
#2 -- ++ #3 -- ++ #4 -- ++ ($-1*#3$) -- cycle;
\else
% front
\filldraw[#1,fill=\tkzThreedBoxColor!20] 
($#2+#5$) -- ++ #3 -- ++ #4 -- ++ ($-1*#3$) -- cycle;
\fi
}
\begin{document}
\foreach \X in {0,10,...,350}
{\begin{tikzpicture}
\path[use as bounding box] (-2,-4) rectangle (8.5,4);
\pgfmathsetmacro{\tmpangle}{10*sin(\X)}
\begin{scope}[pitch=\tmpangle,transform shape] % \X is *not* the rotation angle
\path let \p1=(0,0,1) in \pgfextra{\pgfmathtruncatemacro{\zxproj}{sign(\x1)}
\pgfmathtruncatemacro{\zyproj}{sign(\y1)}
\xdef\zxproj{\zxproj}\xdef\zyproj{\zyproj}
};
\tkzThreeDBox[box color=orange,draw=none]{(0,0,0)}{(1,0,0)}{(0,2,0)}{(0,0,4)}
\fill[orange!80,canvas is yz plane at x=1] (0.5,0.5) coordinate(X) rectangle ++(1,3);
\shade[opacity=0.7,left color=orange!80,right color=blue!50!cyan!60!white,canvas is xy plane at z=0.5]
 (1,0.5) -- ++(6,0) -- ++ (0,1) -- ++(-6,0) -- cycle;
\shade[opacity=0.7,left color=orange!80,right color=blue!50!cyan!60!white,canvas is xz plane at y=0.5]
 (1,0.5) -- ++(6,0) -- ++ (0,3) -- ++(-6,0) -- cycle;
\shadedraw[draw=red!50,left color=orange!15,right color=orange!40] 
(1.5,0.5,1) --  (1.5,1,1) -- plot[variable=\x,domain=0:1.5,samples=60] 
(\x+1.5,{1+0.1*sin(720*\x/1.5)},1) --++(0,0.25,0) -- ++(0.5,-0.5,0)
-- ++(-0.5,-0.5,0) --++(0,0.25,0)
 -- plot[variable=\x,domain=1.5:0,samples=60] 
(\x+1.5,{0.5+0.1*sin(720*\x/1.5)},1) -- cycle;
\draw[dashed,draw=orange!20,thick] (X) -- ++(6,0,0);
\fill[blue!50!cyan!60!white,opacity=0.6,canvas is yz plane at x=4] (0.5,0.5) rectangle ++(1,3);
\tkzThreeDBox[box color=white,fill opacity=0,draw=orange!20,thick]{(1,0.5,0.5)}{(6,0,0)}{(0,1,0)}{(0,0,3)}
\tkzThreeDBox[box color=cyan,draw=none]{(7,0,0)}{(1,0,0)}{(0,2,0)}{(0,0,4)}
\node at (0.5,1,4) {$T_2$};
\node at (1,0.9,2) {$Q$};
\node at (7.5,1,4) {$T_1$};
\draw[{Bar}{Latex}-{Latex}{Bar}] (1,0,4) -- (7,0,4)
node[midway,fill=white](d){$d$};
\node[below=1pt of d,draw] {$T_2>T_1$};
\node[anchor=south,align=center] (mat) at (2,2.2,0) {Material having\\ thermal
conductivity $k$};
\node[anchor=south,align=center] (area) at (5,2.2,0) {Area 51};
\path (mat) -- (2.5,1,1) coordinate (x3) coordinate[pos=1/3] (x1) coordinate[pos=2/3] (x2);
\draw[-Latex] (mat) to[out=-90,in=70] (x1) to[out=-110,in=90] (x2)
to[out=-90,in=100] (x3);
\draw[-Latex] (area) to[out=-90,in=30] (4,1,0.5);
\end{scope}
\end{tikzpicture}}
\end{document}

enter image description here

  • 1
    Haha Area 51. Thank you so much, everything seems easier to do in TikZ. – sab hoque Aug 11 '18 at 15:01
  • 1
    I like how we try to achieve 3D as realistically as possible in other questions, but for graphics as these this sort of semi-3D seems to look better and more clearly shows what's happening. – Max Aug 11 '18 at 16:51
  • 1
    @MaxSnippe I agree with you. One could of course make the thing look more "realistic" by adjusting x, y, z, potentially loading the tikz-3dplot package, and using you nice routines (which IMHO should be added to that package). Even then these things will not even be asymptotically realistic, simply because parallel lines don't meet at infinity. One could try to improve, re-discover z buffer=sort like things but I don't think it will be straightforward to come somewhere close to asymptote, so I'll content myself with cartoons. ;-) –  Aug 12 '18 at 02:08
  • 1
    @marmot That animation is honestly one of the most visually stunning things I've seen done with TikZ. I would upvote this 100x if I could! – Milo Aug 12 '18 at 02:19
  • 2
    @Milo Then you seem not to know the tikzmarmots package. That is clearly the best package ever. ;-) –  Aug 12 '18 at 02:31