Torus tilings

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? ๐Ÿ˜


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *