6

I find myself needing to draw a bunch of simple patterns with a few colors, as in the example below.

\begin{tikzpicture}[scale=1.5]
\draw[style=help lines,step=1cm] (-2.3,-2.3) grid (2.3,2.3);
\draw[fill=green] (-2,1) rectangle (-1,2);
\draw[fill=red] (-1,1) rectangle (0,2);
\draw[fill=blue] (0,1) rectangle (1,2);
\draw[fill=yellow] (1,1) rectangle (2,2);

\draw[fill=red] (-2,0) rectangle (-1,1);
\draw[fill=green] (-1,0) rectangle (0,1);
\draw[fill=yellow] (0,0) rectangle (1,1);
\draw[fill=blue] (1,0) rectangle (2,1);    

\draw[fill=yellow] (-2,-1) rectangle (-1,0);
\draw[fill=blue] (-1,-1) rectangle (0,0);
\draw[fill=red] (0,-1) rectangle (1,0);
\draw[fill=green] (1,-1) rectangle (2,0);    

\draw[fill=blue] (-2,-2) rectangle (-1,-1);
\draw[fill=red] (-1,-2) rectangle (0,-1);
\draw[fill=green] (0,-2) rectangle (1,-1);
\draw[fill=yellow] (1,-2) rectangle (2,-1);
\end{tikzpicture}

Output

This is clearly an inefficient way of creating the picture though, and would ideally like to have a function rowpatternmaker coords string so that rowpatternmaker (-2,0) rgyb would create a row of coloured squares starting from (-2,0) which, from left to right, are red, green, yellow, blue. In this way, I could then create the pattern above with

rowpatternmaker (-2,1) grby
rowpatternmaker (-2,0) rgyb
rowpatternmaker (-2,-1) ybrg
rowpatternmaker (-2,-2) brgy

Of course, what I'd really like is to make a function square pattern maker where

squarepatternmaker (-2,1) grby rgyb ybrg brgy

would create the pattern above.

While I've created a few figures with TikZ, I'm unsure of how to create a function like this, let along one that can read a string "grby" and interpret this as a list of colours.

Assuming it's possible, how would I go about creating rowpatternmaker (or squarepatternmaker)?

5

Having bare words as commands is unnecessarily hard in LaTeX. That is why I introduce

\rowpatternmaker (-2,1) grby;
\rowpatternmaker (-2,0) rgyb;
\rowpatternmaker (-2,-1) ybrg;
\rowpatternmaker (-2,-2) brgy;

I hope that's okay. The first argument is the starting coordinate and the second is the color sequence. If you leave the color sequence empty it will default to rgby. The line length is determined by the length of the color sequence, i.e. rgbrgb will be six long.

The square pattern maker is also possible

\squarepatternmaker (-2,1) grby rgyb ybrg brgy;

It is implement in terms of the row pattern maker.

\documentclass{article}
\pagestyle{empty}
\usepackage{tikz,xparse}

\ExplSyntaxOn

\seq_new:N \l_cookie_rows_seq
\int_new:N \l_cookie_rowcount_int
\seq_new:N \l_cookie_colors_seq
\int_new:N \l_cookie_count_int

\cs_new_protected:Npn \cookie_map_colors:Nn #1#2
 {
  \seq_clear:N #1
  \seq_set_split:Nnn \l_tmpa_seq { } { #2 }
  \seq_map_inline:Nn \l_tmpa_seq
   {
    \str_case:nn { ##1 }
     {
      { r } { \seq_put_right:Nn #1 { red } }
      { g } { \seq_put_right:Nn #1 { green } }
      { b } { \seq_put_right:Nn #1 { blue } }
      { y } { \seq_put_right:Nn #1 { yellow } }
     }
   }
 }

\cs_new_protected:Npn \cookie_row_pattern_maker:nnn #1#2#3
 {
  \cookie_map_colors:Nn \l_cookie_colors_seq { #3 }
  \int_zero:N \l_cookie_count_int
  \seq_map_inline:Nn \l_cookie_colors_seq
   {
    \draw[fill=##1] (#1+\int_use:N \l_cookie_count_int,#2) rectangle +(1,1);
    \int_incr:N \l_cookie_count_int
   }
 }

\cs_new_protected:Npn \rowpatternmaker (#1,#2) #3;
 {
  \tl_if_empty:nTF { #3 }
   { \cookie_row_pattern_maker:nnn { #1 } { #2 } { rgby } }
   { \cookie_row_pattern_maker:nnn { #1 } { #2 } { #3 } }
 }

\cs_generate_variant:Nn \seq_set_split:Nnn { Nnx }

\cs_new_protected:Npn \cookie_square_pattern_maker:nnn #1#2#3
 {
  \seq_set_split:Nnx \l_cookie_rows_seq { ~ } { \tl_trim_spaces:n { #3 } }
  \int_zero:N \l_cookie_rowcount_int
  \seq_map_inline:Nn \l_cookie_rows_seq
   {
    \cookie_row_pattern_maker:nnn { #1 } { #2 - \int_use:N \l_cookie_rowcount_int } { ##1 }
    \int_incr:N \l_cookie_rowcount_int
   }
 }

\cs_new_protected:Npn \squarepatternmaker (#1,#2) #3;
 {
  \cookie_square_pattern_maker:nnn { #1 } { #2 } { #3 }
 }

\ExplSyntaxOff

\begin{document}
\begin{tikzpicture}
  \draw[style=help lines,step=1cm] (-2.3,-2.3) grid (2.3,2.3);
  \rowpatternmaker (-2,1) grby;
  \rowpatternmaker (-2,0) rgyb;
  \rowpatternmaker (-2,-1) ybrg;
  \rowpatternmaker (-2,-2) brgy;
\end{tikzpicture}

\begin{tikzpicture}
  \draw[style=help lines,step=1cm] (-2.3,-2.3) grid (2.3,2.3);
  \squarepatternmaker (-2,1) grby rgyb ybrg brgy;
\end{tikzpicture}
\end{document}

enter image description here

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.