Function Repository Resource:

GenerateTiling

Source Notebook

Generate a tiling pattern from a set of local template constraints

Contributed by: Wolfram Research

ResourceFunction["GenerateTiling"][templates,{},n]

covers an n×n array with values consistent with local constraints listed in templates.

ResourceFunction["GenerateTiling"][templates,{},{m,n}]

covers an m×n array instead.

ResourceFunction["GenerateTiling"][templates,{},size,All]

lists all array coverings consistent with local constraints listed in templates.

ResourceFunction["GenerateTiling"][templates,{},size,count]

lists multiple coverings, up to integer count of them.

ResourceFunction["GenerateTiling"][templates,seed,size,count]

forces the seed array to occur near the center of the pattern.

Details

A tiling pattern is any rectangular array of non-negative integers.
A template is a rectangular array containing non-negative integers or Blank (_) values.
A Blank value in a template can match any integer in a tiling pattern.
For example, the template {{_,0,2},{0,1,_}} has four different integer values and two Blank (_) values.
ResourceFunction["GenerateTiling"] assumes that possible values in a tiling pattern are bounded above by the maximum integer found in the set of templates.
Sets of potentially many templates should have the same bounding size, say {a,b}.
If all {a,b} subarrays of an {m,n} pattern match a template from input templates, the tiling pattern is said to be "consistent with local constraints listed in templates", or for short, "template consistent".
Values on the edge of a pattern should be checked against partial templates by allowing complete templates to partially intersect the tiling pattern and ignoring the overhang to exterior.
ResourceFunction["GenerateTiling"] takes the option "Boundary". When set to "Periodic", ResourceFunction["GenerateTiling"] also requires template consistency of a tiling pattern across North-South and East-West edges (i.e. toroidal boundary conditions).

Examples

Basic Examples (4) 

Generate a uniform tiling pattern of all 0s:

In[1]:=
ResourceFunction["GenerateTiling"][{ {{0}} }, {}, 4]
Out[1]=

Generate uniform tiling patterns for the first few positive integers:

In[2]:=
MatrixForm@ResourceFunction["GenerateTiling"][{ {{#}} }, {}, 4] & /@ Range[5]
Out[2]=

Generate a tiling pattern from a set of three templates:

In[3]:=
MatrixForm@ResourceFunction["GenerateTiling"][{{{0, 1}, {1, 0}},
   {{1, 0}, {1, 1}}, {{1, 1}, {0, 1}}}, {}, 5]
Out[3]=

Plot the tiling pattern using ArrayPlot, and use the resource function TilingPatternPlot to show the templates used:

In[4]:=
tiles = {{{0, 1}, {1, 0}}, {{1, 0}, {1, 1}}, {{1, 1}, {0, 1}}};
tiling = ResourceFunction["GenerateTiling"][tiles, {}, 20];
Labeled[ArrayPlot[
  tiling, {Frame -> False, Mesh -> None, PixelConstrained -> 10}],
 Row[ResourceFunction["TilingPatternPlot"][tiles, ImageSize -> 50], Spacer[20]], Spacings -> {1, 1}]
Out[6]=

Change the dimensions of the tiling pattern and break up the result into generating tiles:

In[7]:=
tiles = {{{0, 1}, {1, 0}}, {{1, 0}, {1, 1}}, {{1, 1}, {0, 1}}};
tiling = ResourceFunction["GenerateTiling"][tiles, {}, {10, 20}];
Labeled[ArrayPlot[tiling,
  {Frame -> False, Mesh -> None, PixelConstrained -> 10}],
 Row[ArrayPlot[#, ImageSize -> 50, Mesh -> True] & /@ Union[Flatten[Partition[tiling, {2, 2}, {1, 1}], 1]],
  Spacer[5]], Spacings -> {1, 1}]
Out[9]=

Plot a four-color periodic tiling pattern:

In[10]:=
With[{tiling = ResourceFunction["GenerateTiling"][
    Partition[RotateRight[Range[0, 3], #], 2] & /@ Range[4], {}, {20, 20}],
  colRules = MapIndexed[(#2[[1]] - 1) -> #1 &,
    {Blend[{Yellow, Orange}], Blend[{Green, Cyan}, .5],
     Lighter[Blue, .5], Lighter[Blend[{Magenta, Red}, .25], 0.4]}]},
 Labeled[ArrayPlot[tiling, ColorRules -> colRules,
   {Frame -> False, Mesh -> True, MeshStyle -> Black}],
  Row[ArrayPlot[#, ColorRules -> colRules,
      ImageSize -> 50, Mesh -> True, MeshStyle -> Black
      ] & /@ Union[Flatten[Partition[tiling, {2, 2}, {1, 1}], 1]],
   Spacer[5]], Spacings -> {1, 1}]]
Out[10]=

Plot all four translates of this tiling pattern:

In[11]:=
With[{tilings = ResourceFunction["GenerateTiling"][
    Partition[RotateRight[Range[0, 3], #], 2] & /@ Range[4], {}, {12, 12}, All],
  colRules = MapIndexed[(#2[[1]] - 1) -> #1 &,
    {Blend[{Yellow, Orange}], Blend[{Green, Cyan}, .5],
     Lighter[Blue, .5], Lighter[Blend[{Magenta, Red}, .25], 0.4]}]},
 ArrayPlot[#, ColorRules -> colRules,
    {Frame -> False, Mesh -> True, MeshStyle -> Black}] & /@ tilings]
Out[11]=

Scope (2) 

Generate a tiling pattern from a complicated set of templates:

In[12]:=
With[{tiles = {{{0, 1, 1}, {1, 1, 1}}, {{1, 0, 1}, {1, 1, 1}}, {{1, 1,
    0}, {1, 1, 1}}, {{1, 1, 1}, {1, 0, 1}}, {{0, 1, 0}, {0, 0, 0}}, {{
   0, 0, 0}, {0, 0, 1}}, {{0, 0, 0}, {0, 1, 0}}, {{0, 0, 0}, {1, 0, 0}}, {{1, 0, 1}, {0, 0, 0}}, {{1, 1, 1}, {0, 1, 0}}, {{0, 0, 1}, {
   0, 1, 1}}, {{0, 1, 0}, {1, 1, 0}}, {{1, 0, 0}, {1, 0, 1}}}},
 Labeled[ArrayPlot[ResourceFunction["GenerateTiling"][tiles, {}, 30],
   {Frame -> False, Mesh -> None, PixelConstrained -> 10}],
  Grid[Partition[Append[
     ArrayPlot[#, ImageSize -> 50, Mesh -> True] & /@ tiles, ""], 7],
   Spacings -> {1, 1}], Spacings -> {1, 1}]]
Out[12]=

Control the offset of a periodic tiling pattern by setting a seed value:

In[13]:=
With[{tiles = Map[{{#[[1]], #[[2]]},
      {#[[2]], #[[3]]}} &,
    RotateRight[Range[3], #] & /@ Range[0, 2]]},
 ArrayPlot[ResourceFunction["GenerateTiling"][tiles, {{#}}, 5],
    Frame -> None, ColorRules -> {
      1 -> Lighter[Blend[{Red, Orange}], .25],
      2 -> Darker[Blend[{Green, Yellow}, .6], .1],
      3 -> Lighter[Blend[{Blue, Green}, .2], .35]}
    ] & /@ Range[3]]
Out[13]=

A tiling pattern around an {{n,n}} initial condition is not possible for this set of tiles:

In[14]:=
With[{tiles = Map[{{#[[1]], #[[2]]},
      {#[[2]], #[[3]]}} &,
    RotateRight[Range[3], #] & /@ Range[0, 2]]},
 ResourceFunction["GenerateTiling"][tiles, {{#, #}}, 5] & /@ Range[3]]
Out[14]=

Options (3) 

Boundary (3) 

Generate a tiling on a size-30 torus (i.e. a tiling with a size 30×30 periodic boundary):

In[15]:=
With[{tiles = {{{0, 1, 1}, {1, 1, 1}}, {{1, 0, 1}, {1, 1, 1}}, {{1, 1,
    0}, {1, 1, 1}}, {{1, 1, 1}, {1, 0, 1}}, {{0, 1, 0}, {0, 0, 0}}, {{
   0, 0, 0}, {0, 0, 1}}, {{0, 0, 0}, {0, 1, 0}}, {{0, 0, 0}, {1, 0, 0}}, {{1, 0, 1}, {0, 0, 0}}, {{1, 1, 1}, {0, 1, 0}}, {{0, 0, 1}, {
   0, 1, 1}}, {{0, 1, 0}, {1, 1, 0}}, {{1, 0, 0}, {1, 0, 1}}}},
 ArrayPlot[
  ResourceFunction["GenerateTiling"][tiles, {}, 30, "Boundary" -> "Periodic"],
  {Frame -> False, Mesh -> None}]]
Out[15]=

The minimum periodic region has size 5×6:

In[16]:=
With[{tiles = {{{0, 1, 1}, {1, 1, 1}}, {{1, 0, 1}, {1, 1, 1}}, {{1, 1,
    0}, {1, 1, 1}}, {{1, 1, 1}, {1, 0, 1}}, {{0, 1, 0}, {0, 0, 0}}, {{
   0, 0, 0}, {0, 0, 1}}, {{0, 0, 0}, {0, 1, 0}}, {{0, 0, 0}, {1, 0, 0}}, {{1, 0, 1}, {0, 0, 0}}, {{1, 1, 1}, {0, 1, 0}}, {{0, 0, 1}, {
   0, 1, 1}}, {{0, 1, 0}, {1, 1, 0}}, {{1, 0, 0}, {1, 0, 1}}}},
 ArrayPlot[ResourceFunction["GenerateTiling"][tiles, {}, {5, 6},
   "Boundary" -> "Periodic"],
  Frame -> False, Mesh -> None, PixelConstrained -> 10]]
Out[16]=

Double-check that value by counting inequivalent translates:

In[17]:=
With[{tiles = {{{0, 1, 1}, {1, 1, 1}}, {{1, 0, 1}, {1, 1, 1}}, {{1, 1,
    0}, {1, 1, 1}}, {{1, 1, 1}, {1, 0, 1}}, {{0, 1, 0}, {0, 0, 0}}, {{
   0, 0, 0}, {0, 0, 1}}, {{0, 0, 0}, {0, 1, 0}}, {{0, 0, 0}, {1, 0, 0}}, {{1, 0, 1}, {0, 0, 0}}, {{1, 1, 1}, {0, 1, 0}}, {{0, 0, 1}, {
   0, 1, 1}}, {{0, 1, 0}, {1, 1, 0}}, {{1, 0, 0}, {1, 0, 1}}}},
 Length@ResourceFunction["GenerateTiling"][tiles, {}, {5, 6}, All,
   "Boundary" -> "Periodic"]]
Out[17]=

Possible Issues (2) 

Templates must have the same bounding dimensions:

In[18]:=
ResourceFunction["GenerateTiling"][{{{1, 1}, {1, 1}}, {{1}}}, {}, 4]
Out[18]=

If not, it is always possible to add more blanks:

In[19]:=
ResourceFunction[
 "GenerateTiling"][{{{1, 1}, {1, 1}}, {{1, _}, {_, _}}}, {}, 4]
Out[19]=

Neat Examples (2) 

Generate a periodic tiling pattern from a complicated set of tiles:

In[20]:=
With[{tiles = {{{0, 0, 
Blank[]}, {0, 
Blank[], 0}, {1, 
Blank[], 
Blank[]}}, {{0, 0, 
Blank[]}, {0, 
Blank[], 1}, {0, 
Blank[], 
Blank[]}}, {{0, 0, 
Blank[]}, {1, 
Blank[], 0}, {0, 
Blank[], 
Blank[]}}, {{0, 0, 
Blank[]}, {1, 
Blank[], 0}, {1, 
Blank[], 
Blank[]}}, {{0, 1, 
Blank[]}, {0, 
Blank[], 0}, {1, 
Blank[], 
Blank[]}}, {{0, 1, 
Blank[]}, {0, 
Blank[], 1}, {0, 
Blank[], 
Blank[]}}, {{0, 1, 
Blank[]}, {1, 
Blank[], 1}, {1, 
Blank[], 
Blank[]}}, {{1, 0, 
Blank[]}, {0, 
Blank[], 0}, {1, 
Blank[], 
Blank[]}}, {{1, 0, 
Blank[]}, {1, 
Blank[], 0}, {0, 
Blank[], 
Blank[]}}, {{1, 0, 
Blank[]}, {1, 
Blank[], 1}, {1, 
Blank[], 
Blank[]}}, {{1, 1, 
Blank[]}, {0, 
Blank[], 0}, {0, 
Blank[], 
Blank[]}}, {{1, 1, 
Blank[]}, {0, 
Blank[], 0}, {1, 
Blank[], 
Blank[]}}, {{1, 1, 
Blank[]}, {1, 
Blank[], 0}, {0, 
Blank[], 
Blank[]}}, {{1, 1, 
Blank[]}, {1, 
Blank[], 1}, {0, 
Blank[], 
Blank[]}}}},
 Labeled[
  ArrayPlot[
   ResourceFunction["GenerateTiling"][tiles, {}, 79, "Boundary" -> "Periodic"],
   {Frame -> False, Mesh -> None, PixelConstrained -> 4}],
  Labeled[Grid[Partition[Append[ArrayPlot[#, ImageSize -> 50,
         Mesh -> True, ColorRules -> {Verbatim[_] -> Gray}
         ] & /@ tiles, ""], 7], Spacings -> {1, 1}],
   Text@Style[
     "(Gray squares in templates stand for Blank wildcards)",
     Gray]], Spacings -> {1, 1}]]
Out[20]=

Generate the nested pattern from NKS, Chapter 5 (p. 219):

In[21]:=
With[{tiles = {{{
Blank[], 1, 
Blank[]}, {1, 0, 0}, {
Blank[], 0, 
Blank[]}}, {{
Blank[], 1, 
Blank[]}, {0, 1, 0}, {
Blank[], 0, 
Blank[]}}, {{
Blank[], 1, 
Blank[]}, {0, 0, 1}, {
Blank[], 1, 
Blank[]}}, {{
Blank[], 1, 
Blank[]}, {0, 0, 1}, {
Blank[], 0, 
Blank[]}}, {{
Blank[], 1, 
Blank[]}, {0, 0, 0}, {
Blank[], 1, 
Blank[]}}, {{
Blank[], 0, 
Blank[]}, {1, 1, 1}, {
Blank[], 0, 
Blank[]}}, {{
Blank[], 0, 
Blank[]}, {1, 0, 1}, {
Blank[], 1, 
Blank[]}}, {{
Blank[], 0, 
Blank[]}, {1, 0, 0}, {
Blank[], 1, 
Blank[]}}, {{
Blank[], 0, 
Blank[]}, {0, 1, 1}, {
Blank[], 1, 
Blank[]}}, {{
Blank[], 0, 
Blank[]}, {0, 1, 0}, {
Blank[], 0, 
Blank[]}}, {{
Blank[], 0, 
Blank[]}, {0, 0, 1}, {
Blank[], 0, 
Blank[]}}, {{
Blank[], 0, 
Blank[]}, {0, 0, 0}, {
Blank[], 0, 
Blank[]}}}},
 Labeled[
  ArrayPlot[ResourceFunction["GenerateTiling"][tiles, {{1}, {1}}, 100],
   {Frame -> False, Mesh -> None, PixelConstrained -> 4}],
  Labeled[Grid[Partition[ArrayPlot[#, ImageSize -> 50,
        Mesh -> True, ColorRules -> {0 -> White, 1 -> Black, _ -> Gray}
        ] & /@ tiles, 6], Spacings -> {1, 1}],
   Text@Style[
     "(Gray squares in templates stand for Blank wildcards)",
     Gray]], Spacings -> {1, 1}]]
Out[21]=

Version History

  • 2.0.0 – 23 June 2022
  • 1.0.0 – 25 March 2022

Related Resources

Author Notes

Significant consistent revision with extended functionality. --Bradley Klee

License Information