Ever since Bill Keehn and I started writing our paper, “Counting Tilings of the ๐ ร ๐ Grid, Cylinder, and Torus,” I’ve been noticing and taking photos of tiles that I see that exhibit interesting symmetries.
















































My wife will sometimes kid on the square: “Whenever you take your phone out to take a picture of a tile, you also have to take a picture of me.”
CPP Job Talk
When I gave my job talk at CPP, I included some of these tiles in my most labor-intensive slide transition:
Random Tiling Bot
I used some of these photos to programmatically generate tilings, inspired by Dave Richeson’s (@divbyzero.bsky.social) Bluesky bot Random Tiling Bot.












Torus tilings on a torus
Mathematica code
Here’s the code for drawing the patterns on a torus:
faceImage = ImageCrop[Import["tiling_018.png"],1620/3];
torus[u_, v_, R_ : 2, r_ : 1] := {
(R + r Cos[v]) Cos[u],
(R + r Cos[v]) Sin[u],
r Sin[v]
};
frames = Table[
ParametricPlot3D[torus[u, v], {u, 0, 2 Pi}, {v, 0, 2 Pi},
TextureCoordinateFunction -> ({#4, #5 + a} &),
PlotStyle -> Texture[faceImage],
Mesh -> None, Lighting -> "Neutral",
Boxed -> False, Axes -> False, Method -> {"ShrinkWrap" -> True},
Background -> Black, ImageSize -> Large
],
{a, 0, 1 - 1/120, 1/120}
]
Python Code
Here’s code that randomly picks one of the above tiles, and draws rotations and reflections of it in a nรm grid. (I saved the tile images under the path /tiles/tile_000.png
.)
from PIL import Image
import random
import os
current_dir = os.path.dirname(os.path.abspath(__file__))
tiling_path = current_dir + "/generated/"
generation = len(os.listdir(tiling_path))
gen_string = str(generation).zfill(3)
random.seed(generation)
path = current_dir + "/tiles/"
tile_name = random.choice([f for f in os.listdir(path) if f[-3:]=="png"])[0:-4]
big_tile_design = Image.open(path + tile_name + ".png")
tile_design = big_tile_design.resize((180, 180), Image.LANCZOS)
(n,m) = (3,3) # n ร m torus
canvas = Image.new("RGB", (180*n*3, 180*m*3))
tile_symmetries = [
tile_design,
tile_design.rotate(90),
tile_design.rotate(180),
tile_design.rotate(270),
tile_design.transpose(Image.FLIP_LEFT_RIGHT),
tile_design.transpose(Image.FLIP_LEFT_RIGHT).rotate(90),
tile_design.transpose(Image.FLIP_LEFT_RIGHT).rotate(180),
tile_design.transpose(Image.FLIP_LEFT_RIGHT).rotate(270)
]
tiles = random.choices(tile_symmetries, k=n*m)
for j in range(m*3):
for i in range(n*3):
tile_choice = tiles[n*(j%m) + (i%n)]
canvas.paste(tile_choice, (i * 180, j * 180))
canvas.save(tiling_path + "tiling_" + gen_string + ".png")
Maybe I’ll make a bot? ๐
Leave a Reply