# What is the easiest way to draw 3D cube with TikZ?

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:

-
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

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}

-
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
@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
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

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{\pgfqpoint{\pgf@xa}{\pgf@yb}}
\pgfpathmoveto{\pgfqpoint{\pgf@xb}{\pgf@yb}}
}
}
\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}

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

-
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
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
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

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.

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:

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.

4. How to draw parallelepiped and cube with LaTeX?

One answer provides a pic for drawing annotated cuboids like these:

-
+1 for a new package :-) – ℝaphink Oct 3 '11 at 8:37
I hope adding an own answer is not unacceptable. If it is, please roll back. – cfr Jan 18 at 0:45
Also, Tom's answer has made significant progress since the version posted here and now includes some shaded cubes which really look as if they belong among the rings and mists of Middle Earth... ;). – cfr Jan 18 at 0:50

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;
\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}

-
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

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

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

I used on on my blog.

-
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
(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

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.

-

A bit late to join the party, but I found that a bit of corner rounding is sufficient to make the corners look decent:

\documentclass{article}
\usepackage[active,tightpage]{preview}
\usepackage{tikz,color}
\usetikzlibrary{calc}
\PreviewEnvironment{tikzpicture}

\begin{document}
\begin{tikzpicture}
% Settings
\definecolor{CUBE}{rgb}{0.3,0.3,0.9};
\coordinate (CenterPoint) at (0,0);
\def\width{1.5cm};
\def\height{1.0cm};
\def\textborder{0.1cm};
\def\xslant{0.2cm};
\def\yslant{0.15cm};
\def\rounding{0.2pt};
% Drawing
\node[thick, draw,
minimum height  = \height,
minimum width   = \width,
text width      = {\width-2*\textborder},
align           = center,
fill            = CUBE!50,
rounded corners = \rounding]
at (CenterPoint) {Cube''}; % TEXT HERE?
% "3D" top
\draw [rounded corners = \rounding, thick, fill=CUBE!70] %
($(CenterPoint) + (-\width/2. - 2*\rounding, \height/2.)$) -- %
($(CenterPoint) + (-\width/2. + \xslant - 2*\rounding, \height/2. + \yslant)$) -- %
($(CenterPoint) + (\width/2. + \xslant + 2*\rounding, \height/2. + \yslant)$) -- %
($(CenterPoint) + (\width/2. + 2*\rounding, \height/2.)$) -- %
cycle;
% "3D" side
\draw [rounded corners = \rounding, thick, fill=CUBE!90] %
($(CenterPoint) + (\width/2. + \xslant + 2*\rounding, \height/2. + \yslant)$) -- %
($(CenterPoint) + (\width/2. + 2*\rounding, \height/2.)$) -- %
($(CenterPoint) + (\width/2. + 2*\rounding, -\height/2.)$) -- %
($(CenterPoint) + (\width/2. + \xslant + 2*\rounding, -\height/2. + \yslant)$) -- %
cycle;
\end{tikzpicture}
\end{document}

I am sure if this is useful someone with more experience and knowledge can compensate, if required, the extra width (+ 2*\rounding) added to make the corners fit together, add anchors around the drawing, encapsulate it in some routine you can call and even allow for the "3D" part to appear on other sides (change perspective).

But since this article helped me, I thought I would give back what I learned even if little or rudimentary.

Also, details on the corners (please remove them if they are occupying too much space and are not useful):

-
Welcome to TeX.SX! You can have a look at our starter guide to familiarize yourself further with our format. This is really quite late, but a nice answer! :) – yo' Dec 9 '14 at 12:27
Instead of rounded corners, you may try line cap=round,line join=round (and 0pt as value for \rounding in your MWE). – Paul Gaborit Dec 10 '14 at 21:55
line cap=round and line join=round leave the corners between the three distinct faces pointy, with bits sticking out. 0pt also leaves the same artifacts. I didn't try different values but I guess there should be a best value for each line thickness. – berna1111 Jan 15 '15 at 14:27

A PSTricks solution:

\documentclass{article}

\usepackage{pstricks}

\begin{document}

\begin{center}
\psset{
dimen = m,
linejoin = 1,
fillstyle = solid,
fillcolor = yellow!30
}
\begin{pspicture}(4,2.5)
\psframe(0,0)(3.5,2)
\pspolygon(3.5,0)(3.5,2)(4,2.5)(4,0.5)
\pspolygon(0,2)(0.5,2.5)(4,2.5)(3.5,2)
\rput(1.75,1){Node}
\end{pspicture}
\end{center}

\end{document}

-