7

I want to create a checkerboard pattern with two colors. Is there a possibility to do this inside a pattern definition?

I found a node-based solution (first print the background, then add the foreground or better: use a combination with preaction and fill)

But I'm looking for a twocolored pattern.

My favorite solution would be a pattern with selectable colors, but pattern don't accept parameters (correct my, if I understood it wrong).

Example:

\documentclass[tikz]{standalone}
\usetikzlibrary{patterns}
\usepackage{luatex85}

% Flexible Checkerboards - based on the definition for checkerboard, but with different size.
% Define size of own check in pattern
\newlength{\flexcheckerboardsize}

%Define a small checkerboard
\setlength{\flexcheckerboardsize}{.5mm}
\pgfdeclarepatternformonly{smallcheckerboard}{\pgfpointorigin}{\pgfqpoint{2\flexcheckerboardsize}{2\flexcheckerboardsize}}{\pgfqpoint{2\flexcheckerboardsize}{2\flexcheckerboardsize}}%
  {
    \pgfpathrectangle{\pgfpointorigin}{\pgfqpoint{\flexcheckerboardsize}{\flexcheckerboardsize}}
    \pgfpathrectangle{\pgfqpoint{\flexcheckerboardsize}{\flexcheckerboardsize}}{\pgfqpoint{\flexcheckerboardsize}{\flexcheckerboardsize}}
    \pgfusepath{fill}
  }

%Define a new checkerboard with predefined size and colors.
%Parameters: Name, size, color1, color2
\newcommand{\defineflexcheckerboard}[4]{
  \setlength{\flexcheckerboardsize}{#2}
  \pgfdeclarepatternformonly{#1}{\pgfpointorigin}{\pgfqpoint{2\flexcheckerboardsize}{2\flexcheckerboardsize}}{\pgfqpoint{2\flexcheckerboardsize}{2\flexcheckerboardsize}}%
  {
    \pgfsetfillcolor{#4}%no effect
    \pgfsetcolor{#3}%ok, but option pattern color is ignored
    \pgfpathrectangle{\pgfpointorigin}{\pgfqpoint{\flexcheckerboardsize}{\flexcheckerboardsize}}
    \pgfpathrectangle{\pgfqpoint{\flexcheckerboardsize}{\flexcheckerboardsize}}{\pgfqpoint{\flexcheckerboardsize}{\flexcheckerboardsize}}
    \pgfusepath{fill}
  }
}

\defineflexcheckerboard{flexcheckerboard_bw}{.5mm}{black}{white}
\defineflexcheckerboard{flexcheckerboard_redblue}{.5mm}{red}{blue}

\begin{document}
  \begin{tikzpicture}[node distance=5mm]
  %background is not used
  \node (c0bw) [circle, radius = 1cm, pattern=flexcheckerboard_bw] {};
  \node (c0rb) [circle, radius = 1cm, pattern=flexcheckerboard_redblue,right of=c0bw] {}; %Wrong no blue

  %This are two work arounds: Paint background, then pattern
  \node (c1) [circle, radius = 1cm, blue, fill, below of=c0bw] {};
  \node (c1) [circle, radius = 1cm, pattern=flexcheckerboard_redblue, below of=c0bw] {};
  %Same with a preaction
  \node (c1b) [preaction={fill, blue},circle, radius = 1cm, right of=c1, pattern=flexcheckerboard_redblue] {};

  %Without any color definition in the pattern, I can influence both.
  \node [circle, radius = 1cm, below of=c1,pattern=smallcheckerboard,pattern color=green,preaction={fill, blue}] {};
  \end{tikzpicture}
\end{document}
  • First row: This pattern should be two-colored
  • 2nd row: Work arounds (I don't want this work around)
  • 3rd row: No color definition in the pattern, colors are controlled from outside. enter image description here

Background why I don't want the work around: I'm preparing a new tikzduck-decoration and I want to use it with a pattern. Without the multi-color-pattern I must define additional parameters in tikzduck to handle the different colors.

knut
  • 8,838
  • How do you want to declare the colors for the multicolor pattern? – Ignasi Apr 18 '18 at 14:36
  • The macro \defineflexcheckerboard has two parameters #3+#4 with the colors. With \pgfsetcolor I can use one of the colors, but I found no way to use the 2nd color. I expected, that I can use \pgfsetfillcolor, but it has no effect. – knut Apr 18 '18 at 14:39
  • 1
    In the example of the manual on page 1060 on the bottom it is explained how to add parameters. And I think you are missing a number of \pgfpathclose commands after the squares. –  Apr 18 '18 at 14:44
  • I am really curious which new gadget the duck will get! – samcarter_is_at_topanswers.xyz Apr 18 '18 at 19:33
  • @samcarter it's a bathing cap - ducks love bathing :) Actually I try to add ear muffs, so they can play water polo. The pattern is needed to add team colors – knut Apr 18 '18 at 22:11
  • @knut That project sounds familiar :) Nice to meet you here in virtual life! – samcarter_is_at_topanswers.xyz Apr 18 '18 at 22:28

2 Answers2

7

You can start from already defined checkerboard light grey which uses two colors. It draws a large square and two smaller squares with a second color on it. Based is this definition and adapting it to your code is easy to do

\documentclass[tikz]{standalone}
\usetikzlibrary{patterns}
\usepackage{luatex85}

% Flexible Checkerboards - based on the definition for checkerboard, but with different size.
% Define size of own check in pattern
\newlength{\flexcheckerboardsize}

%Define a new checkerboard with predefined size and colors.
%Parameters: Name, size, color1, color2
\newcommand{\defineflexcheckerboard}[4]{
    \setlength{\flexcheckerboardsize}{#2}
    \pgfdeclarepatterninherentlycolored{#1}
        {\pgfpointorigin}{\pgfqpoint{2\flexcheckerboardsize}    
        {2\flexcheckerboardsize}}
        {\pgfqpoint{2\flexcheckerboardsize}
        {2\flexcheckerboardsize}}%
        {
            \pgfsetfillcolor{#4}
            \pgfpathrectangle{\pgfpointorigin}{
            \pgfqpoint{2.1\flexcheckerboardsize}    
                {2.1\flexcheckerboardsize}}% make
                                % slightly larger to ensure that tiles
                                % are really solid
          \pgfusepath{fill}
          \pgfsetfillcolor{#3}
          \pgfpathrectangle{\pgfpointorigin}
            {\pgfqpoint{\flexcheckerboardsize}
            {\flexcheckerboardsize}}
          \pgfpathrectangle{\pgfqpoint{\flexcheckerboardsize}
            {\flexcheckerboardsize}}
            {\pgfqpoint{\flexcheckerboardsize}
            {\flexcheckerboardsize}}
            \pgfusepath{fill}
        }
}

\defineflexcheckerboard{flexcheckerboard_bw}{.5mm}{black}{white}
\defineflexcheckerboard{flexcheckerboard_redblue}{.5mm}{red}{blue}
\defineflexcheckerboard{flexcheckerboard_greenorange}{1mm}{green}{orange}
\defineflexcheckerboard{flexcheckerboard_bluecyan}{.2mm}{cyan}{blue}

\begin{document}
  \begin{tikzpicture}[node distance=5mm]
  %background is not used
  \node (c0bw) [circle, radius = 1cm, pattern=flexcheckerboard_bw] {};
  \node (c0rb) [circle, radius = 1cm, pattern=flexcheckerboard_redblue,right of=c0bw] {}; %Wrong no blue
  \node (c0go) [circle, radius = 1cm, pattern=flexcheckerboard_greenorange,below of=c0bw] {}; %Wrong no blue
  \node (c0og) [circle, radius = 1cm, pattern=flexcheckerboard_bluecyan,below of=c0rb] {};   \end{tikzpicture}
\end{document}

enter image description here

In Tikz : rotate a fill pattern some other bicolor patterns are defined. They can also be adapted to your syntax.

Ignasi
  • 136,588
6

Just spelling out my comment a bit (and using this answer). TikZ has already a pattern color, which gets stored in \tikz@pattern@color. (To use it, I put the pattern in a \makeatletter environment.) And I do not see anything wrong with using a background, you can add the pattern in a postaction and get beautiful two-colored patterns. However, after I learned that this might potentially be used in the famous tikzducks package, I rewrote my code to come with two functionalities: either draw a two-color checkerboard or just one color on a background (checker board background=none, which is the predefined setting). You can adjust all the things with pgfkeys, just like in ordinary patterns.

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{patterns}

\makeatletter
\tikzset{/tikz/.cd,
    checker board size/.store in=\flexcheckerboardsize,
    checker board size=6pt,
    checker board background/.store in=\flexcheckerboardbgd,
    checker board background=none
}

\pgfdeclarepatterninherentlycolored[\flexcheckerboardsize,\flexcheckerboardbgd]{flex checker board}
{\pgfqpoint{-1pt}{-1pt}}
{\pgfqpoint{\flexcheckerboardsize}{\flexcheckerboardsize}}
{\pgfqpoint{\flexcheckerboardsize}{\flexcheckerboardsize}}
{\pgfmathsetmacro{\tmp}{0.5*\flexcheckerboardsize}
    \pgfsetcolor{\tikz@pattern@color}
    \pgfpathrectangle{\pgfpointorigin}{\pgfqpoint{\tmp pt}{\tmp pt}}
    \pgfpathrectangle{\pgfqpoint{\tmp pt}{\tmp pt}}{\pgfqpoint{\tmp pt}{\tmp pt}}
    \pgfusepath{fill}
    \def\none{none}
    \ifx\flexcheckerboardbgd\none%
    \else
    \pgfsetcolor{\flexcheckerboardbgd}
    \pgfpathrectangle{\pgfqpoint{0pt}{\tmp pt}}{\pgfqpoint{\tmp pt}{\tmp pt}}
    \pgfpathrectangle{\pgfqpoint{\tmp pt}{0pt}}{\pgfqpoint{\tmp pt}{\tmp pt}}
    \pgfusepath{fill}
    \fi
}
\makeatother

\begin{document}
\begin{tikzpicture}

    \draw [checker board size=9pt, pattern=flex checker board, pattern color =
    red] (0,0) circle[radius = 1cm];
    \draw [checker board background=blue,checker board size=12pt, pattern=flex checker board, pattern color =
    red] (2,0) circle[radius = 1cm];
    \draw [fill=orange,postaction={checker board background=none,checker board size=12pt, pattern=flex checker board, pattern color =
    red}] (4,0) circle[radius = 1cm];

\end{tikzpicture}
\end{document}

enter image description here

  • \flexcheckerboardsize is defined as a length, not as a macro. So this is not a problem. The usage of a background is ok, but I want to use my pattern within tikzducks and I want to reduce the number of parameters. – knut Apr 18 '18 at 21:48
  • @knut I made an update which (I hope) accomodates your wish and still allows to put a single-color checkerboard on top of a background, which was what I had in mind when I wrote the first version. –  Apr 18 '18 at 22:09