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 reproduce the following two figures in TikZ.

Fig 1 Fig 2

My attempted code for Fig 1 is

\documentclass{minimal}
\usepackage{tikz}
\begin{document}
    \begin{tikzpicture}
    \draw [fill=black, ultra thick, red]  (0.0,0.0) -- (0.5, 0.5) -- (0.5, 1.5) -- (0.0, 1.0) -- cycle;
    \draw [fill=black, ultra thick, blue] (1.0,0.0) -- (1.5, 0.5)-- (1.5, 1.5)--(1.0, 1.0)--cycle;
    \draw  (0.0,0.0)  -- (1.0, 0.0)-- (1.5, 0.5)--(0.5, 0.5)--cycle;
    \draw  (0.0,1.0) -- (1.0, 1.0)-- (1.5, 1.5)--(0.5, 1.5)--cycle;
    \end{tikzpicture}
\end{document}

My Fig 1

and for the second figure the code is

\documentclass{minimal}
\usepackage{tikz}
\begin{document}
    \begin{tikzpicture}
    \draw [fill=black, ultra thick, red]  (1.0,0.0) -- (1.0, 1.0) -- (0.5, 1.5) -- (0.5, 0.5) -- cycle;
    \draw [fill=black, ultra thick, blue] (0.0,0.0) -- (0.0, 1.0)-- (1.5, 1.5)--(1.5, 0.5)--cycle;
    \draw  (0.0,0.0)  -- (1.0, 0.0)-- (1.5, 0.5)--(0.5, 0.5)--cycle;
    \draw  (0.0,1.0) -- (1.0, 1.0)-- (1.5, 1.5)--(0.5, 1.5)--cycle;
    \draw  (1.0, 0.0) -- (1.0, 1.0)  (0.5, 0.5) -- (0.5, 1.5);
    \end{tikzpicture}
\end{document}

My Fig 2

I'm a TikZ newbie and have troubles to produce exactly the same figures with more efficient code. I've a problem with overlays and exact coordinates. I'd highly appreciate if you could help me to fix these problems and get similar figures with more robust code.

share|improve this question
1  
I think that you need to take a look at the outer sep option on page 176 in the tikz manual. -and use \draw [draw=black, ultra thick, fill=blue]. -and read chapter 20 about transparency. –  Hans-Peter E. Kristiansen Feb 21 '12 at 5:16
    
Thanks @Hans-PeterE.Kristiansen for your pointer. I almost rosoved the issue of transparency. Thanks again. –  MYaseen208 Feb 21 '12 at 5:23
    
@Hans-PeterE.Kristiansen: Can you give me more pointer about outer sep? –  MYaseen208 Feb 21 '12 at 5:36
    
I do not know how make it work myself - I just guessed that setting outer sep = 0 would help to make the lines join nicely. -but I do not know enough. –  Hans-Peter E. Kristiansen Feb 21 '12 at 5:41
add comment

2 Answers

up vote 23 down vote accepted

It is often forgotten that tikZ also has an xyz coordinate system. I think it lets you express the coordinates in a more natural way. (I also added the circles.)

\documentclass{minimal}
\usepackage{tikz}      
\usetikzlibrary{calc}  

\begin{document}
    \begin{tikzpicture}[scale=4,fill opacity=0.4,thick,
                        line cap=round,line join=round]
    %% Define coordinate labels.
    % t(op) and b(ottom) layers
    \path \foreach \layer/\direction in {b/{0,0,0},t/{0,1,0}} {
        (\direction)
        \foreach \point/\label in {{0,0,0}/ll,{1,0,0}/lr,{1,0,-1}/ur,{0,0,-1}/ul} {
            +(\point) coordinate (\layer\label)
        }
        ($(\layer ll)!0.5!(\layer ur)$) coordinate (\layer md)
    };

    % Put text next to the labels as requested.
    % Funilly enough we need to set fill opacity to 1.
    \draw \foreach \text/\label/\anchor in {%
        one/bll/east,
        two/bul/east,
        three/tll/east,
        four/tul/east,
        five/blr/west,
        six/bur/west,
        seven/tlr/west,
        eight/tur/west} {
        (\label) node[anchor=\anchor,fill opacity=1] {\text}
    };

    % Draw left cube.
    \fill (0,0,-1) circle (0.5pt);
    \foreach \direction in {(0,0,1),(0,1,0),(1,0,0)} {
        \draw[dashed,black] (bul) -- + \direction;
    }
    \fill[blue!60] (bmd) -- (bur) -- (tur) -- (tmd);
    \fill[red!60]  (blr) -- (tlr) -- (tul) -- (bul);
    \fill[blue!60] (bll) -- (bmd) -- (tmd) -- (tll);
    \draw (bll) -- (blr) -- (tlr) -- (tll) -- cycle;
    \draw (blr) -- (bur) -- (tur) -- (tlr) -- cycle;
    \draw (tll) -- (tlr) -- (tur) -- (tul) -- cycle;
    \foreach \point in {bll,blr,bur,tll,tlr,tul,tur} {
        \fill[fill opacity=1] (\point) circle (0.75pt);
    }

    % Draw right cube.
    \path (blr) + (0.65,0) coordinate (pos);
    \foreach \direction in {(0,0,1),(0,1,0),(1,0,0)} {
        \draw[dashed] (pos) ++ (bul) -- + \direction;
    }
    \fill[blue!60] (pos) +(blr) -- +(bur) -- +(tur) -- +(tlr);
    \fill[red!60]  (pos) +(bll) -- +(bul) -- +(tul) -- +(tll);
    \draw (pos) +(tll) -- +(tlr) -- +(tur) -- +(tul) -- cycle
                +(tll) -- +(bll) -- +(blr) -- +(bur) -- +(tur)
                +(blr) -- +(tlr);
    \end{tikzpicture}
\end{document}

cube with shaded sides

share|improve this answer
1  
Yes and No. Yes it's more easy to see where are the points. No because you have the same calculus to place the points, No because you have a lot of coordinates to write. The better way is to name the coordinates with the 3D library. Each side is a plan, and you can work with only 2 coordinates. After getting the coordinates, you can working without problem. (see my update) –  Alain Matthes Feb 21 '12 at 9:06
    
I understand and in my HD, half of the 3D examples used your method and the other half the 3D library. But I think it's preferable to name the coordinates. The code will be easier to modify and read. –  Alain Matthes Feb 21 '12 at 9:44
    
(+1): Thanks @MarcvanDongen for such a formidable answer. I'd highly appreciate if you let me how to put some text (like A, B, etc...) close to every circle. Thanks again for all your help. Much appreciated. –  MYaseen208 Feb 21 '12 at 16:12
    
Thanks @MarcvanDongen for all your help. Thanks again. –  MYaseen208 Feb 21 '12 at 16:46
1  
@MarcvanDongen: Nice answer. One minor problem is that the lines does not match up nicely - it can only be seen on the right figure, where there is no circles in the corners to hide the problem. (If you do not know what I mean, then try setting the line width to ultra thich.) –  Hans-Peter E. Kristiansen Feb 26 '12 at 5:38
add comment

Your options are not fine. When you write \draw[fill=black, ultra thick, red], as you can see fill=black doesn't work. Your last option red is used for drawing and filling. to fill with red and to draw with black, you need to write \draw[color=black,fill=red, ultra thick]. Surface and line are red and the line width is important so you the result is not fine. Now in a first time, you can use \draw and \fill separately. The order is important because some options have some effects on the first drawings. There are other methods (ways) to create this picture but I give you the codes later. For the circles at each vertex is interesting to use variables instead of "raw" coordinates and you can use \foreach. Comments are in the code.

Figure

enter image description here

My code update

I keep the code initial to show what is wrong and what is right

\documentclass{minimal}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document} 

 \tikzset{vertex/.style={shape=circle, % style for a vertex
                    minimum size=3pt,
                    fill=black,
                    inner sep = 0pt}}
\begin{tikzpicture}[scale=4] 
  % define the points  
 \path  (0,0)     coordinate (A)  (1,0)     coordinate (B) % bottom
        (1.5,0.5) coordinate (C)  (0.5,0.5) coordinate (D)
        (0,1)     coordinate (E)  (1,1)     coordinate (F) % top  add 1 for y
        (1.5,1.5) coordinate (G)  (0.5,1.5) coordinate (H)
        ($(A)!0.5!(C)$) coordinate (O)   % middle of A--C
        ($(E)!0.5!(G)$) coordinate (P);%   

    \draw (A) -- (E) (B) -- (F) (C) -- (G) ; % lateral 
    \draw[gray,dashed]  (D) -- (H) (D) -- (C) (D) -- (A) (D) -- (B) (A) -- (C);   
    \fill [blue!50,fill opacity=.5] (P) -- (O) -- (C) -- (G) -- cycle;
    \fill [red!50, fill opacity=.5] (H) -- (D) -- (B) -- (F) -- cycle;
    \fill [blue!50,fill opacity=.5] (A) -- (O) -- (P) -- (E) -- cycle;
    \draw (A) -- (B) -- (C) (F) -- (H); % bottom 
    \draw (E) -- (F) -- (G) -- (H) -- (E) -- (G); % top
    % vertex 
    \foreach \vertex in {A,...,C} {\node[vertex] at (\vertex) {};}
    \foreach \vertex in {E,...,H} {\node[vertex] at (\vertex) {};}
    \node[vertex,fill=gray] at (D) {};       
  \end{tikzpicture} 
  \end{document}   

version 3D

I think it's the better way. With canvas is xy plane at z=0, you are on a plan (xy). I used some negative values to respect my first solution and to use the same code,. The code looks better with only positive values. To use other side, you just need to write for example canvas is xz plane at y=0 and you get a plan (lateral) axis are x and z. The result is exactly the same and you need no calculus but you need some orientation in space !

I added yellow color to show how to use other plans Be careful, I used canvas is yx plane and not canvas is xy plane.

enter image description here

\documentclass[12pt,a4paper]{article}
\usepackage{tikz}     
\usetikzlibrary{calc,3d}

\begin{document}
\thispagestyle{empty} 

 \tikzset{vertex/.style={shape=circle, % style for a vertex
                        minimum size=3pt,
                        fill=gray,
                        inner sep = 0pt}}  

  \begin{tikzpicture}
    [x={(-0.5cm,-0.5cm)}, y={(1cm,0cm)}, z={(0cm,1cm)}, scale=4]  
    \draw[thick](0,0,0)--(1.2,0,0) node[below right]{x} ;
    \draw[thick](0,0,0)--(0,1.2,0) node[below right]{y} ;
    \draw[thick](0,0,0)--(0,0,1.2) node[below right]{z} ;
  % face  bottom
   \begin{scope}[canvas is xy plane at z=0,very thin]
       \coordinate  (A) at (0,0);   \coordinate (C) at (-1,1);
       \coordinate  (B) at (-1,0);  \coordinate  (D) at (0,1); 
        \coordinate (O) at  ($(A)!0.5!(C)$); % middle of A--C   
   \end{scope}  
     % face  top
    \begin{scope}[canvas is xy plane at z=1,very thin]
        \coordinate  (E) at (0,0);  \coordinate (G) at (-1,1);     
        \coordinate  (F) at (-1,0); \coordinate (H) at (0,1);
        \coordinate (P) at  ($(E)!0.5!(G)$); % middle of A--C     
    \end{scope} 

    \begin{scope}[canvas is yx plane at z=0]
      \path[fill = yellow] (0,0) rectangle (1,-1);
    \end{scope} 

     \foreach \vertex in {A,...,H} {\node[vertex] at (\vertex) {};}
        \draw (A) -- (B) -- (C) -- (D) -- cycle; % bottom
        \draw (E) -- (F) -- (G) -- (H) -- cycle; % top 
        \draw (A) -- (E) (B) -- (F) (C) -- (G) (D)--(H); % lateral  
        \fill [blue!50,fill opacity=.5] (P) -- (O) -- (C) -- (G) -- cycle;
        \fill [red!50, fill opacity=.5] (H) -- (D) -- (B) -- (F) -- cycle;
        \fill [blue!50,fill opacity=.5] (A) -- (O) -- (P) -- (E) -- cycle;     
\end{tikzpicture}
\end{document}

For fun

I would like to avoid maximum of coordinates

\documentclass[12pt,a4paper]{article}
\usepackage{tikz}     
\usetikzlibrary{calc,3d}

\begin{document}
\thispagestyle{empty} 

 \tikzset{vertex/.style={shape=circle, % style for a vertex
                        minimum size=8pt,
                        ball color=gray,
                        inner sep = 0pt}}  

\begin{tikzpicture}
    [x={(-0.5cm,-0.5cm)}, y={(1cm,0cm)}, z={(0cm,1cm)}, scale=4]
\foreach \z in {0,1}  \foreach \y in {0,1}  \foreach  \x in {0,1}   
    {\coordinate (\x\y\z) at  (\x,\y,\z) ;} 

         \coordinate (O) at  ($(000)!0.5!(110)$);
         \coordinate (P) at  ($(001)!0.5!(111)$);

\fill[fill opacity=.5,blue!30] (O) 
    \foreach \pt in {P,011,010}{--(\pt.center)}--cycle;% 

\fill[fill opacity=.5,red!30] (000) 
    \foreach \pt in {110,111,001}{--(\pt.center)}--cycle;% 

\fill[fill opacity=.5,blue!30] (O) 
    \foreach \pt in {P,101,100}{--(\pt.center)}--cycle;% 

\draw[thick,double] (000.center)
    \foreach \pt in {010,011,001}{--(\pt.center)}--cycle;%

\foreach \y in {0,1}  \foreach  \z in {0,1}    
    {\node[vertex] (0\y\z) at  (0\y\z) {};}

\draw[thick,double] (100.center)
    \foreach \pt in {110,111,101}{--(\pt.center)}--cycle;%  

 \foreach \y in {0,1}  \foreach  \z in {0,1}    
    {\draw[thick,double] (0\y\z) -- (1\y\z);
     \node[vertex] (1\y\z) at  (1\y\z) {};}
\end{tikzpicture} 
\end{document}

enter image description here

share|improve this answer
    
Thanks @Altermundus for your help. This is awesome. Would you mind to make little circle on every vertex? Thanks –  MYaseen208 Feb 21 '12 at 6:49
    
No problem but I need before explain some of the problems –  Alain Matthes Feb 21 '12 at 7:18
    
Okay. If you see the original figures, you can find small circles at very vertices, e.g. circles at (0, 0), (0, 1), etc. Thanks again for all your help. –  MYaseen208 Feb 21 '12 at 7:21
    
@Altermundus Just one minor comment about the first code exmple (there are so many:-). Redefing the labels using copy-and-paste sort of defeats the purpose of using the labels. It would be nicer if you could reuse the label commands. This can be done using incremental coordinates (or shifts). The second cube in my example reuses the coordinate labels. –  Marc van Dongen Feb 21 '12 at 14:04
    
I have another one because I have the beginning of a package that I made for my students. I don't understand exactly what you mean by "Redefing the labels using copy-and-paste". Is it the fact to use node after coordinate at the same position? What do you understand by "label commands". Sorry but my english is not very good! –  Alain Matthes Feb 21 '12 at 15:03
show 6 more comments

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.