7

I am using tikz to draw multiple cubes. I want to achieve my expected result as bellow

enter image description here

However, the main difficulty is that locates cube inside and center of the cube and making a connection between them. Currently, I am using manually setting the coordination point. Could you help me to do it?

The online code at https://www.overleaf.com/8937330rhwcmbfhzdvx This is my modified code based on how to draw parallelepiped and cube with latex?

\documentclass[border=5pt, multi, tikz]{standalone}
\usetikzlibrary{quotes,arrows.meta}
\tikzset{
  annotated cuboid/.pic={
    \tikzset{%
      every edge quotes/.append style={midway, auto},
      /cuboid/.cd,
      #1
    }
    \draw [every edge/.append style={pic actions, densely dashed, opacity=.5}, pic actions]
    (0,0,0) coordinate (o) -- ++(-\cubescale*\cubex,0,0) coordinate (a) -- ++(0,-\cubescale*\cubey,0) coordinate (b) edge coordinate [pos=1] (g) ++(0,0,-\cubescale*\cubez)  -- ++(\cubescale*\cubex,0,0) coordinate (c) -- cycle
    (o) -- ++(0,0,-\cubescale*\cubez) coordinate (d) -- ++(0,-\cubescale*\cubey,0) coordinate (e) edge (g) -- (c) -- cycle
    (o) -- (a) -- ++(0,0,-\cubescale*\cubez) coordinate (f) edge (g) -- (d) -- cycle;   
    ;
  },
  /cuboid/.search also={/tikz},
  /cuboid/.cd,
  width/.store in=\cubex,
  height/.store in=\cubey,
  depth/.store in=\cubez,
  units/.store in=\cubeunits,
  scale/.store in=\cubescale,
  width=10,
  height=10,
  depth=10,
  units=cm,
  scale=.1,
}
\begin{document}
\begin{tikzpicture}

\pic [fill=gray!20, text=green!50!black, draw=black] at (4,-2) {annotated cuboid={width=6, height=20, depth=15, units=mm}};

\pic [fill=gray!20, text=green!50!black, draw=black] at (4,-2.7) {annotated cuboid={width=2, height=4, depth=3, units=m}};


\pic [fill=gray!20, text=green!50!black, draw=black] at (5,-2) {annotated cuboid={width=6, height=20, depth=15, units=mm}}; 

\pic [fill=gray!20, text=green!50!black, draw=black] at (4.8,-2.7) {annotated cuboid={width=2, height=2, depth=2, units=m}};

\pic [fill=gray!20, text=green!50!black, draw=black] at (5.5,-2.3) {annotated cuboid={width=3, height=10, depth=7, units=m}};

\end{tikzpicture}
\end{document}
10

Your code is good, you just need to label your coordinates for each cuboid, which do can do by adding a label to your pics. Once you have done this then you can draw between the vertices with draw commands like \draw (e-B) -- (a-D);.

EDIT You can make all of the lines of the cuboids dashed in a similar way: add a line argument to your annotated cuboid that defaults to draw and then set line=dashed when you want all of the lines to be dashed lines. Similarly, I have added a \cubeback that can be used to remove the dashed lines at the "back" of the cubes, as in the orange cube below.

I have coloured your cubes to make it clearer (to me), which cuboid is which:

enter image description here

Here is the full modified MWE:

  \documentclass[border=5pt, multi, tikz]{standalone}
  \usetikzlibrary{quotes,arrows.meta}
  \tikzset{
    annotated cuboid/.pic={
      \tikzset{%
        every edge quotes/.append style={midway, auto},
        /cuboid/.cd,
        #1
      }
      \draw [\cubeline,every edge/.append style={pic actions, \cubeback, opacity=.5}, pic actions]
      (0,0,0) coordinate (o-\cubelabel) -- ++(-\cubescale*\cubex,0,0) coordinate (a-\cubelabel) -- ++(0,-\cubescale*\cubey,0) coordinate (b-\cubelabel) edge coordinate [pos=1] (g-\cubelabel) ++(0,0,-\cubescale*\cubez)  -- ++(\cubescale*\cubex,0,0) coordinate (c-\cubelabel) -- cycle
      (o-\cubelabel) -- ++(0,0,-\cubescale*\cubez) coordinate (d-\cubelabel) -- ++(0,-\cubescale*\cubey,0) coordinate (e-\cubelabel) edge (g-\cubelabel) -- (c-\cubelabel) -- cycle
      (o-\cubelabel) -- (a-\cubelabel) -- ++(0,0,-\cubescale*\cubez) coordinate (f-\cubelabel) edge (g-\cubelabel) -- (d-\cubelabel) -- cycle;
      ;
    },
    /cuboid/.search also={/tikz},
    /cuboid/.cd,
    width/.store in=\cubex,
    height/.store in=\cubey,
    depth/.store in=\cubez,
    units/.store in=\cubeunits,
    scale/.store in=\cubescale,
    label/.store in=\cubelabel,
    line/.store in=\cubeline,
    backline/.store in=\cubeback,
    width=10,
    height=10,
    depth=10,
    units=cm,
    scale=.1,
    line=draw,
    backline=densely dashed,
  }
  \begin{document}
  \begin{tikzpicture}

  \pic [fill=gray!20, text=green!50!black, draw=black] at (4,-2) {annotated cuboid={label=A, width=6, height=20, depth=15, units=mm}};

  \pic [fill=red!20, text=green!50!black, draw=black] at (4,-2.7) {annotated cuboid={label=B, width=2, height=4, depth=3, units=m, line=dashed}};

  \pic [fill=blue!20, text=green!50!black, draw=black] at (5,-2) {annotated cuboid={label=C, width=6, height=20, depth=15, units=mm}};

  \pic [fill=green!20, text=green!50!black, draw=black] at (4.8,-2.7) {annotated cuboid={label=D, width=2, height=2, depth=2, units=m, line=dashed}};

  \pic [fill=orange!20, text=green!50!black, draw=black] at (5.5,-2.3) {annotated cuboid={label=E, width=3, height=10, depth=7, units=m, backline=draw}};

  \draw (e-B) -- (a-D);
  \end{tikzpicture}
  \end{document}

So all that I have done is added a label to your annotated cuboid, which gets stored in \cubelabelm and changed your coordinates ub the cuboid code to(o),(a),...,(g) to (o-\cubelabel),...,(g-\cubelabel). Then the annotated cuboid commnds are called with label=* and the \draw commands work.

  • Great. How to make the line of inside cube is the dash line – John Apr 5 '17 at 4:45
  • 1
    @user8264 I've updated the code to add another argument, line, that sets the "line style". Adding line=dashed will make the lines of the cuboid dashed lines, line=dotted will make dotted line etc. – Andrew Apr 5 '17 at 5:18
  • Thanks so much for your solution. I want to ask one more thing. In the case of pic definition. If I want to remove the dash line in the cube. Do I need to make a new pic or just add one more argument – John Apr 5 '17 at 5:25
  • By "remove the dash line" do mean the dashed lines at the back of the cubes? If so, then this is done by the densely dashed in the every edge command. You change these lines using a variable like \cubeline that defaults to draw (or densely dashed etc). – Andrew Apr 5 '17 at 5:43
  • 1
    To remove the line set backline equal to the fill colour. For example, backline=orange!20 will completely remove the lines from the orange cube. Sorry, I misunderstood and thought by "remove" you meant "remove the dashes" rather than "remove the line". Silly of me! (Btw, overleaf is pretty cool!) – Andrew Apr 5 '17 at 7:04

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.