Easy way to generate Rubik's cube diagrams

That's a neat question, and here is a proposal for an answer. The colors are stored in an array called \myarray, which determines the colors of the cells. The relation between entry (the index starts at 0) and cell is illustrated by this example

\documentclass{article}
\usepackage{tikz}
\usepackage{tikz-3dplot}
\usetikzlibrary{3d}
\newif\ifshowcellnumber
\showcellnumbertrue
\begin{document}
\definecolor{R}{RGB}{202,65,55}
\definecolor{G}{RGB}{151,216,56}
\definecolor{B}{RGB}{51,72,237}
\definecolor{W}{RGB}{255,255,255}
\definecolor{X}{RGB}{65,65,65}

\newcommand{\TikZRubikFaceLeft}[9]{\def\myarrayL{#1,#2,#3,#4,#5,#6,#7,#8,#9}}
\newcommand{\TikZRubikFaceRight}[9]{\def\myarrayR{#1,#2,#3,#4,#5,#6,#7,#8,#9}}
\newcommand{\TikZRubikFaceTop}[9]{\def\myarrayT{#1,#2,#3,#4,#5,#6,#7,#8,#9}}
\newcommand{\BuildArray}{\foreach \X [count=\Y] in \myarrayL%
{\ifnum\Y=1%
\xdef\myarray{"\X"}%
\else%
\xdef\myarray{\myarray,"\X"}%
\fi}%
\foreach \X in \myarrayR%
{\xdef\myarray{\myarray,"\X"}}%
\foreach \X in \myarrayT%
{\xdef\myarray{\myarray,"\X"}}%
\xdef\myarray{{\myarray}}%
}
\TikZRubikFaceLeft
        {X}{X}{X}
        {X}{X}{X}
        {X}{X}{G}
\TikZRubikFaceRight
        {W}{X}{X}
        {R}{G}{G}
        {X}{G}{G}
\TikZRubikFaceTop
        {X}{X}{R}
        {R}{R}{G}
        {R}{R}{X}
\BuildArray
%\def\myarray{{"X","X","B","X","G","X","R","R","X","X","X","X","G","X","B","B","X","X","G","B","R","X","R","B","X","X","X"}}
\pgfmathsetmacro\radius{0.1}
\tdplotsetmaincoords{55}{135}
\begin{tikzpicture}
 \clip (-3,-2.5) rectangle (3,2.5);
 \begin{scope}[tdplot_main_coords]
  \filldraw [canvas is yz plane at x=1.5] (-1.5,-1.5) rectangle (1.5,1.5);
  \filldraw [canvas is xz plane at y=1.5] (-1.5,-1.5) rectangle (1.5,1.5);
  \filldraw [canvas is yx plane at z=1.5] (-1.5,-1.5) rectangle (1.5,1.5);
  \foreach \X [count=\XX starting from 0] in {-1.5,-0.5,0.5}{
   \foreach \Y [count=\YY starting from 0] in {-1.5,-0.5,0.5}{
   \pgfmathtruncatemacro{\Z}{\XX+3*(2-\YY)}
   \pgfmathsetmacro{\mycolor}{\myarray[\Z]}
    \draw [thick,canvas is yz plane at x=1.5,shift={(\X,\Y)},fill=\mycolor] (0.5,0) -- ({1-\radius},0) arc (-90:0:\radius) -- (1,{1-\radius}) arc (0:90:\radius) -- (\radius,1) arc (90:180:\radius) -- (0,\radius) arc (180:270:\radius) -- cycle;
    \ifshowcellnumber
     \node[canvas is yz plane at x=1.5,shift={(\X+0.5,\Y+0.5)}] {\Z};
    \fi 
    \pgfmathtruncatemacro{\Z}{2-\XX+3*(2-\YY)+9}
    \pgfmathsetmacro{\mycolor}{\myarray[\Z]}
    \draw [thick,canvas is xz plane at y=1.5,shift={(\X,\Y)},fill=\mycolor] (0.5,0) -- ({1-\radius},0) arc (-90:0:\radius) -- (1,{1-\radius}) arc (0:90:\radius) -- (\radius,1) arc (90:180:\radius) -- (0,\radius) arc (180:270:\radius) -- cycle;
    \ifshowcellnumber
     \node[canvas is xz plane at y=1.5,shift={(\X+0.5,\Y+0.5)},xscale=-1] {\Z};
    \fi 
    \pgfmathtruncatemacro{\Z}{2-\YY+3*\XX+18}
    \pgfmathsetmacro{\mycolor}{\myarray[\Z]}
    \draw [thick,canvas is yx plane at z=1.5,shift={(\X,\Y)},fill=\mycolor] (0.5,0) -- ({1-\radius},0) arc (-90:0:\radius) -- (1,{1-\radius}) arc (0:90:\radius) -- (\radius,1) arc (90:180:\radius) -- (0,\radius) arc (180:270:\radius) -- cycle;
    \ifshowcellnumber
     \node[canvas is yx plane at z=1.5,shift={(\X+0.5,\Y+0.5)},xscale=-1,rotate=-90] {\Z};
    \fi 
    }
   }
 \end{scope}
\end{tikzpicture}

\TikZRubikFaceLeft
    {X}{X}{X}
    {X}{X}{X}
    {X}{G}{X}
\TikZRubikFaceRight
    {X}{X}{X}
    {X}{B}{X}
    {W}{B}{X}
\TikZRubikFaceTop
    {X}{R}{X}
    {X}{W}{X}
    {X}{W}{G}
\BuildArray
\showcellnumberfalse
\begin{tikzpicture}
 \clip (-3,-2.5) rectangle (3,2.5);
 \begin{scope}[tdplot_main_coords]
  \filldraw [canvas is yz plane at x=1.5] (-1.5,-1.5) rectangle (1.5,1.5);
  \filldraw [canvas is xz plane at y=1.5] (-1.5,-1.5) rectangle (1.5,1.5);
  \filldraw [canvas is yx plane at z=1.5] (-1.5,-1.5) rectangle (1.5,1.5);
  \foreach \X [count=\XX starting from 0] in {-1.5,-0.5,0.5}{
   \foreach \Y [count=\YY starting from 0] in {-1.5,-0.5,0.5}{
   \pgfmathtruncatemacro{\Z}{\XX+3*(2-\YY)}
   \pgfmathsetmacro{\mycolor}{\myarray[\Z]}
    \draw [thick,canvas is yz plane at x=1.5,shift={(\X,\Y)},fill=\mycolor] (0.5,0) -- ({1-\radius},0) arc (-90:0:\radius) -- (1,{1-\radius}) arc (0:90:\radius) -- (\radius,1) arc (90:180:\radius) -- (0,\radius) arc (180:270:\radius) -- cycle;
    \ifshowcellnumber
     \node[canvas is yz plane at x=1.5,shift={(\X+0.5,\Y+0.5)}] {\Z};
    \fi 
    \pgfmathtruncatemacro{\Z}{2-\XX+3*(2-\YY)+9}
    \pgfmathsetmacro{\mycolor}{\myarray[\Z]}
    \draw [thick,canvas is xz plane at y=1.5,shift={(\X,\Y)},fill=\mycolor] (0.5,0) -- ({1-\radius},0) arc (-90:0:\radius) -- (1,{1-\radius}) arc (0:90:\radius) -- (\radius,1) arc (90:180:\radius) -- (0,\radius) arc (180:270:\radius) -- cycle;
    \ifshowcellnumber
     \node[canvas is xz plane at y=1.5,shift={(\X+0.5,\Y+0.5)},xscale=-1] {\Z};
    \fi 
    \pgfmathtruncatemacro{\Z}{2-\YY+3*\XX+18}
    \pgfmathsetmacro{\mycolor}{\myarray[\Z]}
    \draw [thick,canvas is yx plane at z=1.5,shift={(\X,\Y)},fill=\mycolor] (0.5,0) -- ({1-\radius},0) arc (-90:0:\radius) -- (1,{1-\radius}) arc (0:90:\radius) -- (\radius,1) arc (90:180:\radius) -- (0,\radius) arc (180:270:\radius) -- cycle;
    \ifshowcellnumber
     \node[canvas is yx plane at z=1.5,shift={(\X+0.5,\Y+0.5)},xscale=-1,rotate=-90] {\Z};
    \fi 
    }
   }
 \end{scope}
\end{tikzpicture}   
\end{document} 

enter image description here

As you can see, if you replace \showcellnumbertrue by \showcellnumberfalse, the numbers are suppressed.

EDITs: Illustrated the relation between array index and cell (which is almost redundant now) and adjusted the color (big thanks to @manooooh!). I also used now the conventions of the rubik package, which I did not really know before seeing Peter Grill's nice answer. The conventions are still slightly different since I refer to the faces as left, right and top. This is because this thingy can be rotated in some range, but left will always be left in that range. I also added some %, which were added in first in this answer.

ADDENDUM: Encouraged by @LoopSpace's comment:

\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{tikz-3dplot}
\usetikzlibrary{3d}
\newif\ifshowcellnumber
\showcellnumberfalse
\begin{document}
\definecolor{R}{RGB}{202,65,55}
\definecolor{G}{RGB}{151,216,56}
\definecolor{B}{RGB}{51,72,237}
%\definecolor{W}{RGB}{255,255,255}
\definecolor{W}{RGB}{65,65,65}

\def\myarray{{"W","W","B","W","G","W","R","R","W","W","W","W","G","W","B","B","W","W","G","B","R","W","R","B","W","W","W"}}
\pgfmathsetmacro\radius{0.1}
\newcommand{\frontcolor}{red}
\newcommand{\sidecolor}{blue}
\foreach \X in {95,100,...,175}
{            \tdplotsetmaincoords{55}{\X}
            \begin{tikzpicture}
                \clip (-3,-2.5) rectangle (3,2.5);
                \begin{scope}[tdplot_main_coords]
                    \filldraw [canvas is yz plane at x=1.5] (-1.5,-1.5) rectangle (1.5,1.5);
                    \filldraw [canvas is xz plane at y=1.5] (-1.5,-1.5) rectangle (1.5,1.5);
                    \filldraw [canvas is yx plane at z=1.5] (-1.5,-1.5) rectangle (1.5,1.5);
                    \foreach \X [count=\XX starting from 0] in {-1.5,-0.5,0.5}{
                        \foreach \Y [count=\YY starting from 0] in {-1.5,-0.5,0.5}{
                        \pgfmathtruncatemacro{\Z}{\XX+3*(2-\YY)}
                        \pgfmathsetmacro{\mycolor}{\myarray[\Z]}
                            \draw [thick,canvas is yz plane at
x=1.5,shift={(\X,\Y)},fill=\mycolor] (0.5,0) -- ({1-\radius},0) arc
(-90:0:\radius) -- (1,{1-\radius}) arc (0:90:\radius) -- (\radius,1) arc
(90:180:\radius) -- (0,\radius) arc (180:270:\radius) -- cycle;
        \ifshowcellnumber
            \node[canvas is yz plane at x=1.5,shift={(\X+0.5,\Y+0.5)}] {\Z};
        \fi 
                        \pgfmathtruncatemacro{\Z}{2-\XX+3*(2-\YY)+9}
                        \pgfmathsetmacro{\mycolor}{\myarray[\Z]}
                            \draw [thick,canvas is xz plane at
y=1.5,shift={(\X,\Y)},fill=\mycolor] (0.5,0) -- ({1-\radius},0) arc
(-90:0:\radius) -- (1,{1-\radius}) arc (0:90:\radius) -- (\radius,1) arc
(90:180:\radius) -- (0,\radius) arc (180:270:\radius) -- cycle;
        \ifshowcellnumber
            \node[canvas is xz plane at y=1.5,shift={(\X+0.5,\Y+0.5)},xscale=-1] {\Z};
        \fi 
                        \pgfmathtruncatemacro{\Z}{2-\YY+3*\XX+18}
                        \pgfmathsetmacro{\mycolor}{\myarray[\Z]}
                            \draw [thick,canvas is yx plane at
z=1.5,shift={(\X,\Y)},fill=\mycolor] (0.5,0) -- ({1-\radius},0) arc
(-90:0:\radius) -- (1,{1-\radius}) arc (0:90:\radius) -- (\radius,1) arc
(90:180:\radius) -- (0,\radius) arc (180:270:\radius) -- cycle;
        \ifshowcellnumber
            \node[canvas is yx plane at z=1.5,shift={(\X+0.5,\Y+0.5)},xscale=-1,rotate=-90] {\Z};
        \fi 
                        }
                    }
                \end{scope}
\end{tikzpicture}}
\end{document} 

enter image description here


There is also a rubik package designed specifically for this. The MWE below generates the four cube positions shown in the question.

enter image description here

Code:

\documentclass{article}
\usepackage{tikz}%% load tikz BEFORE rubikcube
\usepackage{rubikcube}
%\usepackage{rubikrotation,rubikpatterns,rubiktwocube}% Related packages

\begin{document}
\noindent
\begin{minipage}{0.4\linewidth}
    \RubikFaceUp
        {X}{X}{X}
        {X}{X}{X}
        {X}{X}{G}
    \RubikFaceRight
        {W}{X}{X}
        {R}{G}{G}
        {X}{G}{G}
    \RubikFaceFront
        {X}{X}{R}
        {R}{R}{G}
        {R}{R}{X}
   \ShowCube{7cm}{0.7}{\DrawRubikCube}
\end{minipage}
\begin{minipage}{0.4\linewidth}
    \RubikFaceUp
        {X}{X}{X}
        {X}{X}{X}
        {X}{G}{X}
    \RubikFaceRight
        {X}{X}{X}
        {X}{B}{X}
        {W}{B}{X}
    \RubikFaceFront
        {X}{R}{X}
        {X}{O}{X}
        {X}{O}{G}
   \ShowCube{7cm}{0.7}{\DrawRubikCube}
\end{minipage}

\par\medskip
\noindent
\begin{minipage}{0.4\linewidth}
    \RubikFaceRight
        {X}{X}{X}
        {G}{B}{X}
        {G}{B}{X}
    \RubikFaceFront
        {X}{X}{X}
        {X}{O}{R}
        {X}{O}{R}
   \ShowCube{7cm}{0.7}{\DrawRubikCube}
\end{minipage}
\begin{minipage}{0.4\linewidth}
    \RubikFaceUp
        {X}{X}{X}
        {G}{X}{X}
        {X}{X}{G}
    \RubikFaceRight
        {W}{X}{X}
        {X}{G}{G}
        {X}{G}{G}
    \RubikFaceFront
        {X}{X}{X}
        {R}{R}{X}
        {R}{R}{X}
   \ShowCube{7cm}{0.7}{\DrawRubikCubeRU}
\end{minipage}   
\end{document}

Tags:

Tikz Pgf