Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I'm trying to find the easiest way to draw a 3D cube (it's for my UML diagram) with TikZ. Could you please give an example?

Like this: enter image description here

share|improve this question
    
Depends a bit on what you want the cube to look like. There's a really nice one at TeXample: texample.net/tikz/examples/sudoku-3d-cube but that might not be what you want. Can you sketch a picture? –  Loop Space Feb 25 '11 at 9:38
    
@Andrew see the picture above :) –  yegor256 Feb 25 '11 at 9:44
    
Another example, already published here on TeX.sx: http://tex.stackexchange.com/a/35289/7417 –  Count Zero Jun 2 '12 at 18:53
add comment

6 Answers 6

up vote 20 down vote accepted

I'm sure that there are better ways, but here's one:

\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\pgfmathsetmacro{\cubex}{2}
\pgfmathsetmacro{\cubey}{1}
\pgfmathsetmacro{\cubez}{1}
\draw[red,fill=yellow] (0,0,0) -- ++(-\cubex,0,0) -- ++(0,-\cubey,0) -- ++(\cubex,0,0) -- cycle;
\draw[red,fill=yellow] (0,0,0) -- ++(0,0,-\cubez) -- ++(0,-\cubey,0) -- ++(0,0,\cubez) -- cycle;
\draw[red,fill=yellow] (0,0,0) -- ++(-\cubex,0,0) -- ++(0,0,-\cubez) -- ++(\cubex,0,0) -- cycle;
\end{tikzpicture}
\end{document}

enter image description here

share|improve this answer
    
Any particular reason you're using minimal? If not, I'd suggest replacing it by a standard document class, as we generally want to discourage usage of minimal –  doncherry Mar 21 '12 at 10:19
3  
@doncherry Because the question tex.stackexchange.com/q/42114/86 hadn't been asked when I wrote that! I was young, I was naive, I didn't know what I was doing. Now I'm old and grumpy and can say, "You want it changed? You know where the 'edit' button is!". (Seriously, you should feel free to make changes like that.) –  Loop Space Mar 21 '12 at 10:22
1  
Good response :). Well, I guess concerning people like you I could just edit it, but then again I think "He knows a lot more about that stuff than I do, perhaps there's a reason he used minimal". When coming across newer users using it, I usually point them to the question you mentioned. –  doncherry Mar 21 '12 at 10:30
    
A quick grep shows that I've used it 45 times in answers (subject to rounding errors). If you come across any others, feel free to edit. –  Loop Space Mar 21 '12 at 10:32
    
I shall :). Perhaps they'll introduce a gold version of the Archaeologist badge some time ... –  doncherry Mar 21 '12 at 10:39
add comment

Since you want to use this for UML diagrams, I think a custom node shape is the right way to go here. It's a lot more overhead and requires getting under PGF's hood/bonnet, but the payoff is that it the drawing code looks just like any other TikZ code:

\documentclass{article}
\usepackage{tikz}

\makeatletter
\pgfkeys{/pgf/.cd,
  parallelepiped offset x/.initial=2mm,
  parallelepiped offset y/.initial=2mm
}
\pgfdeclareshape{parallelepiped}
{
  \inheritsavedanchors[from=rectangle] % this is nearly a rectangle
  \inheritanchorborder[from=rectangle]
  \inheritanchor[from=rectangle]{north}
  \inheritanchor[from=rectangle]{north west}
  \inheritanchor[from=rectangle]{north east}
  \inheritanchor[from=rectangle]{center}
  \inheritanchor[from=rectangle]{west}
  \inheritanchor[from=rectangle]{east}
  \inheritanchor[from=rectangle]{mid}
  \inheritanchor[from=rectangle]{mid west}
  \inheritanchor[from=rectangle]{mid east}
  \inheritanchor[from=rectangle]{base}
  \inheritanchor[from=rectangle]{base west}
  \inheritanchor[from=rectangle]{base east}
  \inheritanchor[from=rectangle]{south}
  \inheritanchor[from=rectangle]{south west}
  \inheritanchor[from=rectangle]{south east}
  \backgroundpath{
    % store lower right in xa/ya and upper right in xb/yb
    \southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
    \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
    \pgfmathsetlength\pgfutil@tempdima{\pgfkeysvalueof{/pgf/parallelepiped offset x}}
    \pgfmathsetlength\pgfutil@tempdimb{\pgfkeysvalueof{/pgf/parallelepiped offset y}}
    \def\ppd@offset{\pgfpoint{\pgfutil@tempdima}{\pgfutil@tempdimb}}
    \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@ya}}
    \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@ya}}
    \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@yb}}
    \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@yb}}
    \pgfpathclose
    \pgfpathmoveto{\pgfqpoint{\pgf@xb}{\pgf@ya}}
    \pgfpathlineto{\pgfpointadd{\pgfpoint{\pgf@xb}{\pgf@ya}}{\ppd@offset}}
    \pgfpathlineto{\pgfpointadd{\pgfpoint{\pgf@xb}{\pgf@yb}}{\ppd@offset}}
    \pgfpathlineto{\pgfpointadd{\pgfpoint{\pgf@xa}{\pgf@yb}}{\ppd@offset}}
    \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@yb}}
    \pgfpathmoveto{\pgfqpoint{\pgf@xb}{\pgf@yb}}
    \pgfpathlineto{\pgfpointadd{\pgfpoint{\pgf@xb}{\pgf@yb}}{\ppd@offset}}
  }
}
\makeatother

\begin{document}
\begin{tikzpicture}
\node[parallelepiped,draw=red,fill=yellow,
  minimum width=2.5cm,minimum height=1.5cm] (1) {Node One};
\node[parallelepiped,draw=blue,fill=green,
  minimum height=2.5cm,minimum width=1.5cm,parallelepiped offset x=4mm] (2)
 at (6,0) {Node Two};
 \draw[ultra thick, ->] (1) -- (2);
\end{tikzpicture}
\end{document}

sample code output

Take a look at the files pgflibraryshapes.*.code.tex in the PGF distribution to learn how to do this kind of thing. I started with a copy of the cross out node which, like this one, inherits from the rectangle node. A further enhancement would be to add anchors to the right/top faces/edges, but as you can guess I have spent enough time on this already. :-D

share|improve this answer
    
Very nice! Plus the text should be in the actual middle of the cube and be a bit faded so that it looked as though it were inside ... –  Loop Space Feb 25 '11 at 14:58
    
@Andrew: yes, if what is desired is a cube with text in the center. But I looked up UML diagrams like the OP is trying to create and they put it on the front of the cube/parallelipiped. See “UML Deployment Diagrams” –  Matthew Leingang Feb 25 '11 at 15:10
1  
Since when has doing what the spec says stopped you from doing what is right?? You are a mathematician after all. –  Loop Space Feb 25 '11 at 15:22
1  
Sometimes doing what is asked and nothing more is wise... (especially for a mathematician who should be writing his book). –  Matthew Leingang Feb 25 '11 at 16:57
    
@Matthew: It's spelled parallelepiped. See en.wikipedia.org/wiki/Parallelepiped –  Faheem Mitha Feb 25 '11 at 21:20
show 2 more comments

Drawing a cube seems to be a fairly common task! There are a few other questions here that involve drawing cubes. It's not always right to merge them, but I thought it worth doing a little more than just linking. So this answer is a Community Wiki (so almost anyone can update it) list of the other cubical questions here. The intent is to include at least one representative picture from the answers.

  1. Need help creating a 3D cube from a 2D set of nodes in TikZ

    Tom Bombadil's answer here is well on the way to being a package, showing that he has mastery over cubes as well as rings.

    cubes

  2. How to draw a cube with TikZ where all faces have a distinct color?

    The accepted answer yields the first image, and the second is a another from the same question:

    enter image description here transparent cube

  3. Is there a way to draw TikZ lines on the "inside" or "outside" of a path?

    Although not obviously about cubes, the motivation was to draw a cube and get the corners right.

    cube with corners

share|improve this answer
    
+1 for a new package :-) –  ℝaphink Oct 3 '11 at 8:37
add comment

I know that this is not what the question was about, but it is an attempt of a 3D cube, with perspective. I don't know how to do it with grids like Stefan's example, but with coordinate calculations and intersections, one can do something like this. It is not mathematically correct, but I think it looks pretty good.

\documentclass[]{article}
\usepackage{tikz}  
\usetikzlibrary{calc,intersections}
\begin{document}
\begin{tikzpicture}
   \clip (-3,-3) rectangle (3,3);
   \coordinate (tf) at (0,0);
   \coordinate (bf) at (0,-3);
   \coordinate (tr) at (15:2.5cm);
   \coordinate (tl) at (165:2.5cm);

   % You can change the perspective by playing with the 5, 5, 15:
   \coordinate (fr) at ($ (tf)!5!(tr) $);
   \coordinate (fl) at ($ (tf)!5!(tl) $);
   \coordinate (fb) at ($ (tf)!15!(bf) $);

   \path[name path=brpath] (bf) -- (fr);
   \path[name path=rbpath] (tr) -- (fb);
   \path[name path=blpath] (bf) -- (fl);
   \path[name path=lbpath] (tl) -- (fb);
   \path[name path=trpath] (tl) -- (fr);
   \path[name path=tlpath] (tr) -- (fl);

   \draw[name intersections={of=brpath and rbpath}] (intersection-1)coordinate (br){}; 
   \draw[name intersections={of=blpath and lbpath}] (intersection-1)coordinate (bl){}; 
   \draw[name intersections={of=trpath and tlpath}] (intersection-1)coordinate (tb){}; 

   \shade[right color=gray!10, left color=black!50, shading angle=105] (tf) -- (bf) -- (bl) -- (tl) -- cycle;
   \shade[left color=gray!10, right color=black!50, shading angle=75] (tf) -- (bf) -- (br) -- (tr) -- cycle;

   \begin{scope}
      \clip (tf) -- (tr) -- (tb) -- (tl) -- cycle;
      \shade[inner color = gray!5, outer color=black!50, shading=radial] (tf) ellipse (3cm and 1.5cm);
   \end{scope}

   \draw (tf) -- (bf);
   \draw (tf) -- (tr);
   \draw (tf) -- (tl);
   \draw (tr) -- (br);
   \draw (bf) -- (br);
   \draw (tl) -- (bl);
   \draw (bf) -- (bl);
   \draw (tb) -- (tr);
   \draw (tb) -- (tl);

   %set the sizes of the little cubes:
   \def\tone{.4}\def\ttwo{.75}\def\fone{.36}\def\ftwo{.70}
   \draw ($ (bf)!\tone!(br) $) -- ($ (tf)!\tone!(tr) $) -- ($ (tl)!\tone!(tb) $);
   \draw ($ (bf)!\ttwo!(br) $) -- ($ (tf)!\ttwo!(tr) $) -- ($ (tl)!\ttwo!(tb) $);
   \draw ($ (bf)!\tone!(bl) $) -- ($ (tf)!\tone!(tl) $) -- ($ (tr)!\tone!(tb) $);
   \draw ($ (bf)!\ttwo!(bl) $) -- ($ (tf)!\ttwo!(tl) $) -- ($ (tr)!\ttwo!(tb) $);
   \draw ($ (tl)!\fone!(bl) $) -- ($ (tf)!\fone!(bf) $) -- ($ (tr)!\fone!(br) $);
   \draw ($ (tl)!\ftwo!(bl) $) -- ($ (tf)!\ftwo!(bf) $) -- ($ (tr)!\ftwo!(br) $);
\end{tikzpicture}
\end{document}

enter image description here

share|improve this answer
    
I learned something new: name path. Thanks Jan! –  Matthew Leingang Feb 25 '11 at 19:29
    
Nice! And anyone else coming here looking for how to draw a cube will now have a feast of answers to choose from. –  Loop Space Feb 25 '11 at 19:51
add comment

Here's an example for a shaded 3D cube with TikZ:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}[on grid]
  \shade[yslant=-0.5,right color=gray!10, left color=black!50]
    (0,0) rectangle +(3,3);
  \draw[yslant=-0.5] (0,0) grid (3,3);
  \shade[yslant=0.5,right color=gray!70,left color=gray!10]
    (3,-3) rectangle +(3,3);
  \draw[yslant=0.5] (3,-3) grid (6,0);
  \shade[yslant=0.5,xslant=-1,bottom color=gray!10,
    top color=black!80] (6,3) rectangle +(-3,-3);
  \draw[yslant=0.5,xslant=-1] (3,0) grid (6,3);
\end{tikzpicture}
\end{document}

Shaded 3D cube

I used on on my blog.

share|improve this answer
    
The cube is nice, but the shading doesn't give a good 3D-effect IMHO. –  Hendrik Vogt Feb 25 '11 at 9:42
    
@Hendrik: quick and easy simulating kind of light which should lead a bit to an optical 3D appearance though it's of course 2D. For an oblique view one could modify it. My answer points to an easy way, as desired. –  Stefan Kottwitz Feb 25 '11 at 9:45
    
As now there's a picture in the question, showing a different requested style, I consider to remove the answer. –  Stefan Kottwitz Feb 25 '11 at 9:50
2  
(Voting for it not to be removed as it's a really nice example.) What destroys the 3D effect for me is not the shading but the perspective - or lack of it. –  Loop Space Feb 25 '11 at 9:56
    
@Andrew: I've been too lazy :-) if you know how to easily add perspective, you're welcome to modify. We could bring that enhancement to TeXample.net afterwards. –  Stefan Kottwitz Feb 25 '11 at 10:25
show 1 more comment

There is already a lot of nice answers to this question, but I would like to promote the 3d TikZ library which makes it easier to manipulate simple objects with three-dimensional coordinates. Here is a solution in the spirit of Stefan's:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{3d}
\begin{document}

\begin{tikzpicture}[x  = {(0.5cm,0.5cm)},
                    y  = {(0.95cm,-0.25cm)},
                    z  = {(0cm,0.9cm)}]
\begin{scope}[canvas is yz plane at x=-1]
  \shade[left color=blue!50,right color=blue!20] (-1,-1) rectangle (1,1);
\end{scope}
\begin{scope}[canvas is xz plane at y=1]
  \shade[right color=blue!70,left color=blue!20] (-1,-1) rectangle (1,1);
\end{scope}
\begin{scope}[canvas is yx plane at z=1]
  \shade[top color=blue!80,bottom color=blue!20] (-1,-1) rectangle (1,1);
\end{scope}
\end{tikzpicture}
\end{document}

Again, the tricky part is to fine tune the perspective and shading, but in my opinion the canvas option provides an easy way to draw in 3D.

enter image description here

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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