12

enter image description here This is an image I draw with tools. But I need to draw it with Tikz. And The 3 squares in the middle, I need to make them looks like 3D stacked with shadow. And the fonts on it, like 'a1', 'a2', ... will also be skewed. I don't know how to draw it, but I daw a sketch by pencil: enter image description here

I hope that I can control the font size, the font is Helvetica. I am not familiar with Tikz, but it is powerful and amazing! I need to draw this graph. Anyone knows how to achieve the 3D image? Looking forward to your replies! Thanks very much!

  • What about using PStricks? – Werner Jul 22 '14 at 13:57
  • Hi @Werner , I never use PStricks. What I use is OmniGraffle. But I want to draw it with LaTeX code and manipulate characters such as shade, square color, font size and so on. – Excalibur Jul 22 '14 at 15:41
  • Hi @Werner , do you know how to use PStricks to implement the effect? I misunderstood the PStricks as a software like PS. Thanks very much! – Excalibur Jul 22 '14 at 21:30
13

EDITED to show more parametric variations of parameters.

Borrowing from Bruno's definition of \slantbox at Shear transform a "box", I was able to construct the following, using simple stacks of \fcolorboxes. The perspective is completely determined by three parameters: \myrotate (the baseline rotation), \myslant (the slant magnitude or fallback parameter), and the short-stacking gap.

First, I demonstrate some variations on the perspective parameters:

\documentclass{article}
\usepackage{stackengine,xcolor,graphicx}
\newsavebox{\foobox}
\newcommand{\slantbox}[2][.5]{\mbox{%
        \sbox{\foobox}{#2}%
        \hskip\wd\foobox
        \pdfsave
        \pdfsetmatrix{1 0 #1 1}%
        \llap{\usebox{\foobox}}%
        \pdfrestore
}}
\def\mybox#1{\strut\makebox[\baselineskip]{$#1$}}
\def\mycell#1#2{\fcolorbox{black}{#1}{\mybox{#2}}}
\def\makeply#1#2#3{\expandafter\def\csname layer#1\endcsname{%
  \stackunder[-\fboxrule]{%
    \mycell{#3}{#2_1}\kern-\fboxrule\mycell{#3}{#2_3}}{%
    \mycell{#3}{#2_2}\kern-\fboxrule\mycell{#3}{#2_4}}%
  }%
}
\makeply{A}{a}{white}
\makeply{B}{b}{gray!30}
\makeply{C}{c}{gray!60}
\def\tristack{\Shortstack{\rotatebox{\myrotate}{\slantbox[\myslant]{\layerA}}
                          \rotatebox{\myrotate}{\slantbox[\myslant]{\layerB}}
                          \rotatebox{\myrotate}{\slantbox[\myslant]{\layerC}}}
}
\begin{document}
\def\myrotate{0}  \def\myslant{0}    \setstackgap{S}{1ex}  \tristack~~~
\def\myrotate{15} \def\myslant{-.9}  \setstackgap{S}{-5ex} \tristack~~~~~~
\def\myrotate{20} \def\myslant{-1.1} \setstackgap{S}{-7ex} \tristack
\end{document}

enter image description here

In fact, here is a general parametric variation of parameters (note that "Ply C atop stack" means that the stack was drawn as a \Shortunderstack, rather than as a \Shortstack):

enter image description here

And then, here, I try to recreate something like what the author is seeking:

\documentclass{article}
\usepackage{stackengine,xcolor,graphicx}
\newsavebox{\foobox}
\newcommand{\slantbox}[2][.5]{\mbox{%
        \sbox{\foobox}{#2}%
        \hskip\wd\foobox
        \pdfsave
        \pdfsetmatrix{1 0 #1 1}%
        \llap{\usebox{\foobox}}%
        \pdfrestore
}}
\def\mybox#1{\strut\makebox[\baselineskip]{$#1$}}
\def\mycell#1#2{\fcolorbox{black}{#1}{\mybox{#2}}}
\def\makeply#1#2#3{\expandafter\def\csname layer#1\endcsname{%
  \stackunder[-\fboxrule]{%
    \mycell{#3}{#2_1}\kern-\fboxrule\mycell{#3}{#2_3}}{%
    \mycell{#3}{#2_2}\kern-\fboxrule\mycell{#3}{#2_4}}%
  }%
}
\def\tristack{\Shortstack{\rotatebox{\myrotate}{\slantbox[\myslant]{\layerA}}
                          \rotatebox{\myrotate}{\slantbox[\myslant]{\layerB}}
                          \rotatebox{\myrotate}{\slantbox[\myslant]{\layerC}}}
}
\def\makestrip#1#2#3{\expandafter\def\csname strip#1\endcsname{%
    \setstackgap{S}{-\fboxrule}\Shortstack{%
      \mycell{#3}{#2_1} \mycell{#3}{#2_2} \mycell{#3}{#2_3} \mycell{#3}{#2_4}%
    }\kern-\fboxrule}%
}
\def\tristrip{\stripA\stripB\stripC}
\def\makecomponents#1#2#3{\makeply{#1}{#2}{#3}\makestrip{#1}{#2}{#3}}
\makecomponents{A}{a}{white}
\makecomponents{B}{b}{gray!30}
\makecomponents{C}{c}{gray!60}
\begin{document}
\def\myrotate{0}  \def\myslant{0}    \setstackgap{S}{-.2\fboxsep}  
\stackon[10pt]{$M_1$}{\tristack}\hspace{.1cm}
\raisebox{62pt}{\scalebox{2.5}{$\leftarrow$}}\hspace{.1cm}
\def\myrotate{15} \def\myslant{-.9}  \setstackgap{S}{-5ex} 
\stackon[12pt]{$M$}{\tristack}\hspace{.7cm}
\raisebox{62pt}{\scalebox{2.5}{$\rightarrow$}}\hspace{.2cm}
\stackon[25pt]{$M_2$}{\tristrip}
\end{document}

enter image description here

  • Wow! That is excellent! Thanks very much @Steven B. Segletes ! – Excalibur Jul 30 '14 at 5:07
8

I got a bit bored in the end but here is a TikZ implementation of the same mechanism Steven gives in his answer. With TikZ you can access the trafo matrix entries via <x,y>scale and <x,y>slant keys. Due to Helvetica, this needs Lua/XeLatex.

\documentclass{article}
\usepackage{tikz,amsmath,fontspec}
\setsansfont{Helvetica}
\usetikzlibrary{matrix}
% make a generic matrix style
\tikzset{mycell/.style={
  execute at empty cell={\node[draw,font=\sffamily,minimum size=5mm,outer sep=0]{
      #1$_{\text{\pgfmathparse{int(2*(\pgfmatrixcurrentrow-1)+\pgfmatrixcurrentcolumn)}\pgfmathresult}}$
    };},row sep=-\pgflinewidth,column sep=-\pgflinewidth},ampersand replacement=\&,inner sep=0
}
\begin{document}
\begin{tikzpicture}
\foreach \x[count=\xi from 0,evaluate=\xs using 100-50*\xi] in{a,b,c}{
  \matrix[mycell=\x,fill=gray!\xs] at (0,\xi) {\&\\\&\\};}

\begin{scope}[shift={(3cm,5mm)},transform canvas={xslant=-1},transform shape]
  \foreach \x[count=\xi from 0,evaluate=\xs using 100-50*\xi] in{a,b,c}{
      \matrix[mycell=\x,fill=gray!\xs] at (0.75*\xi,0.75*\xi) {\&\\\&\\};}
\end{scope}
\end{tikzpicture}
\end{document}

enter image description here

  • Thanks very much @percusse ! Combine your solution with the previous one, both the font and image are perfect! – Excalibur Jul 30 '14 at 5:08
4

A pstricks version using the rich pst-3dplot package:

enter image description here

\documentclass{article}
\usepackage{pst-3dplot,xcolor,multido,graphicx}

\newcommand{\clap}[1]{\makebox[0pt]{#1}}
\newcounter{framenumber}
\newcommand{\preframelabel}{}
\begin{document}

\begin{pspicture}(\textwidth,12)
  \psset{linewidth = .4pt, fillstyle = solid, unit = 0.5, Alpha = 30, Beta = 25, plane = xy}
  \multido{\iBa=1+1,\iBb=12+-4}{3}{%
    \setcounter{framenumber}{0}%
    \expandafter\ifcase\iBa
      \or   \renewcommand{\preframelabel}{a}\psset{fillcolor=white} % 1
      \or   \renewcommand{\preframelabel}{b}\psset{fillcolor=black!10} % 2
      \else \renewcommand{\preframelabel}{c}\psset{fillcolor=black!20}% 3
    \fi%
    \multido{\iC=1+2}{2}{%
      \multido{\iR=\iBb+-2}{2}{%
        \stepcounter{framenumber}%
        \psframe(\iC,\iR)(\numexpr\iC-2\relax,\numexpr\iR+2\relax)%
        \rput(\numexpr\iC-1\relax,\numexpr\iR+1\relax){\preframelabel\theframenumber}
      }%
    }%
  }

  \rput(5,8){\scalebox{3}{$\Leftarrow$}}

  \rput(12,2){\psset{unit=0.7}
    \multido{\iBa=3+-1,\iBb=9+4}{3}{%
      \setcounter{framenumber}{0}%
      \expandafter\ifcase\iBa
        \or   \renewcommand{\preframelabel}{a}\psset{fillcolor=white} % 1
        \or   \renewcommand{\preframelabel}{b}\psset{fillcolor=black!10} % 2
        \else \renewcommand{\preframelabel}{c}\psset{fillcolor=black!20}% 3
      \fi%
      \multido{\iC=5+-4}{2}{%
        \multido{\iR=1+4}{2}{%
          \stepcounter{framenumber}%
          \pstThreeDSquare(\iC,\iR,\iBb)(4,0,0)(0,4,0)%
          \pstPlanePut(\number\numexpr\iC+2\relax,\number\numexpr\iR+2\relax,\iBb){%
            \rotatebox{180}{%
              \clap{%
                \raisebox{-.5\height}{%
                  \scalebox{1.2}{\preframelabel\theframenumber}}}}}
        }%
      }%
    }}

  \rput(16,8){\scalebox{3}{$\Rightarrow$}}

  \multido{\iB=1+1,\iR=20+2}{3}{%
    \setcounter{framenumber}{0}%
    \expandafter\ifcase\iB
      \or   \renewcommand{\preframelabel}{a}\psset{fillcolor=white} % 1
      \or   \renewcommand{\preframelabel}{b}\psset{fillcolor=black!10} % 2
      \else \renewcommand{\preframelabel}{c}\psset{fillcolor=black!20}% 3
    \fi%
    \multido{\iC=10+-2}{4}{%
      \stepcounter{framenumber}%
      \psframe(\iR,\iC)(\numexpr\iR-2\relax,\numexpr\iC+2\relax)%
      \rput(\numexpr\iR-1\relax,\numexpr\iC+1\relax){\preframelabel\theframenumber}
    }%
  }

\end{pspicture}
\end{document}

A similar example is presented in Isometric Tables in LaTeX.

  • Thanks very much @Werner , the pstricks package seems really good! – Excalibur Aug 1 '14 at 19:23

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.