
Infinite Truchet
Roni Kaufman
posit::conf(2023)


Infinitely Variable Tiling Patterns: From Truchet to Sol LeWitt Revisited


Initially, the underlying idea of truchet tiles is that adjacent tiles of right triangles make larger connecting patterns.
Infinitely Variable Tiling Patterns: From Truchet to Sol LeWitt Revisited
Cyril Smith, 1987, analyzed truchet tiles and abstracted them into 1) diagonal lines, then 2) two arcs starting and ending at midpoints of the tiles edges.
Robert J. Krawczyk, 2020
Infinitely Variable Tiling Patterns: From Truchet to Sol LeWitt Revisited


exercises/05-infinite-truchet/truchet_tiles_examples directory. These are different examples of truchet tiles. Choose one example.10:00
geom_arc_bar()We will use the following aesthetics
x0, y0: x, y coordinate, center of arcstart: radian value of where arc startsend: radian value of where arc endsr0: radius of inner arcr: radius of outer arccolor, fill: color of arcr vs r0
In this example, we have r0 as the inner radius and r as the outer radius. {ggforce} allows you to also have it be vice versa.
Most important thing is to remain consistent in your definitions across your code.
geom_arc_bar()We will use the following aesthetics
x0, y0: x, y coordinate, center of arcstart: radian value of where arc startsend: radian value of where arc endsr0: radius of inner arcr: radius of outer arccolor, fill: color of arcgeom_arc_bar() arguments: x0, y0, start, endgeom_arc_bar() arguments: x0, y0, start, end
x0, y0
start, end


x0, y0
start, end


x0, y0
start, end


x0, y0
start, end

exercise/05-infinite-truchet/exercise-2.Rmdset_incorrect_params() function and then the code chunk that plots the output of the function.start and end arguments for geom_arc_bar(). Create a new function called set_correct_params() that fixes this mistake.07:00


set_params()🔔 start bottom left, travel counter clockwise!

set_params()set_params <-
function(x, y, sq_width, tile_type) {
tile <- tribble(
~x0, ~y0, ~start, ~end,
x, y, 0, pi/2,
x + sq_width, y, 3*pi/2, 2*pi,
x + sq_width, y + sq_width, pi, 3*pi/2,
x, y + sq_width, pi/2, pi
)
if (tile_type == 1) {
tile %>%
mutate(num_arcs = c(3, 4, 3, 4))
} else if (tile_type == 2) {
tile %>%
mutate(num_arcs = c(5, 2, 5, 2))
}
}🔔 start bottom left, travel counter clockwise!

set_params() output# A tibble: 4 × 5
x0 y0 start end num_arcs
<dbl> <dbl> <dbl> <dbl> <dbl>
1 0 0 0 1.57 3
2 15 0 4.71 6.28 4
3 15 15 3.14 4.71 3
4 0 15 1.57 3.14 4
This allows us to create one tile of width 15 that has the bottom left corner at x = 0, y = 0
# A tibble: 16 × 2
y x
<dbl> <dbl>
1 0 0
2 0 15
3 0 30
4 0 45
5 15 0
6 15 15
7 15 30
8 15 45
9 30 0
10 30 15
11 30 30
12 30 45
13 45 0
14 45 15
15 45 30
16 45 45
# A tibble: 16 × 3
y x tile_type
<dbl> <dbl> <dbl>
1 0 0 1
2 0 15 1
3 0 30 2
4 0 45 2
5 15 0 1
6 15 15 1
7 15 30 1
8 15 45 1
9 30 0 1
10 30 15 2
11 30 30 1
12 30 45 1
13 45 0 1
14 45 15 1
15 45 30 1
16 45 45 1
# A tibble: 16 × 3
y x tile_type
<dbl> <dbl> <dbl>
1 0 0 2
2 0 15 1
3 0 30 2
4 0 45 2
5 15 0 2
6 15 15 2
7 15 30 2
8 15 45 2
9 30 0 2
10 30 15 1
11 30 30 2
12 30 45 2
13 45 0 1
14 45 15 2
15 45 30 1
16 45 45 2
library(purrr)
truchet_tiles <-
function(seed) {
ncol <- 4
nrow <- 4
sq_width <- 15
set.seed(seed)
grid <-
expand_grid(
y = seq(from = 0, by = sq_width, length.out = ncol),
x = seq(from = 0, by = sq_width, length.out = nrow)
) %>%
mutate(tile_type = sample(c(1, 2), size = n(), replace = TRUE))
params_grid <-
map_dfr(
1:nrow(grid),
function(i) {
set_params(
x = grid$x[i],
y = grid$y[i],
sq_width = sq_width,
tile_type = grid$tile_type[i]
)
}
)
return(params_grid)
}# A tibble: 64 × 5
x0 y0 start end num_arcs
<dbl> <dbl> <dbl> <dbl> <dbl>
1 0 0 0 1.57 3
2 15 0 4.71 6.28 4
3 15 15 3.14 4.71 3
4 0 15 1.57 3.14 4
5 15 0 0 1.57 5
6 30 0 4.71 6.28 2
7 30 15 3.14 4.71 5
8 15 15 1.57 3.14 2
9 30 0 0 1.57 3
10 45 0 4.71 6.28 4
# ℹ 54 more rows
num_arcs != r or r0geom_arc_bar()We will use the following aesthetics
x0, y0: x, y coordinate, center of arcstart: radian value of where arc startsend: radian value of where arc endsr0: radius of inner arcr: radius of outer arccolor, fill: color of arcgeom_arc_bar() arguments: r0, rgeom_arc_bar() arguments: r0, rgeom_arc_bar() arguments: r0, rgeom_arc_bar() arguments: r0, rgeom_arc_bar() arguments: r0, rgeom_arc_bar() arguments: r0, rgeom_arc_bar() arguments: r0, rgeom_arc_bar() arguments: r0, rgeom_arc_bar() arguments: r0, rgeom_arc_bar() arguments: r0, rgeom_arc_bar() arguments: r0, rtruchet_tiles <-
function(seed) {
ncol <- 4
nrow <- 4
sq_width <- 15
set.seed(seed)
grid <-
expand_grid(
y = seq(from = 0, by = sq_width, length.out = ncol),
x = seq(from = 0, by = sq_width, length.out = nrow)
) %>%
mutate(tile_type = sample(c(1, 2), size = n(), replace = TRUE))
params_grid <-
map_dfr(
1:nrow(grid),
function(i) {
set_params(
x = grid$x[i],
y = grid$y[i],
sq_width = sq_width,
tile_type = grid$tile_type[i]
)
}
)
output <-
map_dfr(
1:nrow(params_grid),
function(i) {
bind_cols(
slice(params_grid, i),
r0 = seq(from = 1, by = 2, length.out = params_grid$num_arcs[i]),
r = seq(from = 2, by = 2, length.out = params_grid$num_arcs[i])
)
}
)
return(output)
}Infinite Truchet available at Open Processing
geom_arc_bar() arguments: color and fillgeom_arc_bar() arguments: color and filltruchet_tiles <-
function(color1,
color2,
seed) {
ncol <- 4
nrow <- 4
sq_width <- 15
max_num_arcs <- 5
set.seed(seed)
grid <-
expand_grid(
y = seq(from = 0, by = sq_width, length.out = ncol),
x = seq(from = 0, by = sq_width, length.out = nrow)
) %>%
mutate(tile_type = sample(c(1, 2), size = n(), replace = TRUE))
params_grid <-
map_dfr(
1:nrow(grid),
function(i) {
set_params(
x = grid$x[i],
y = grid$y[i],
sq_width = sq_width,
tile_type = grid$tile_type[i]
)
}
)
color <- c(color1, color2)
color_seq <- rep(color, length.out = max_num_arcs)
output <-
map_dfr(
1:nrow(params_grid),
function(i) {
bind_cols(
slice(params_grid, i),
r0 = seq(from = 1, by = 2, length.out = params_grid$num_arcs[i]),
r = seq(from = 2, by = 2, length.out = params_grid$num_arcs[i]),
color = color_seq[1:params_grid$num_arcs[i]]
)
}
)
return(output)
}# A tibble: 224 × 8
x0 y0 start end num_arcs r0 r color
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <chr>
1 0 0 0 1.57 3 1 2 #fffbe6
2 0 0 0 1.57 3 3 4 #fc8405
3 0 0 0 1.57 3 5 6 #fffbe6
4 15 0 4.71 6.28 4 1 2 #fffbe6
5 15 0 4.71 6.28 4 3 4 #fc8405
6 15 0 4.71 6.28 4 5 6 #fffbe6
7 15 0 4.71 6.28 4 7 8 #fc8405
8 15 15 3.14 4.71 3 1 2 #fffbe6
9 15 15 3.14 4.71 3 3 4 #fc8405
10 15 15 3.14 4.71 3 5 6 #fffbe6
# ℹ 214 more rows
if you set color= to NA you can see the gaps between the arcs
if you set color= to NA you can see the gaps between the arcs
expand= set to FALSE, removes margins




exercises/05-infinite-truchet/exercise-3.Rmdexercise_truchet_tiles().exercises/05-infinite-truchet/ there is an image luft_13_roni.png. Use https://mattdesl.github.io/colorgrab/ to select two colors to use in your system.color1 and color2. Modify the seed to experiment with different outputs.ggsave() code provided and share on the GitHub discussion05:00
geom_arc_bar() to create arcs and its arguments - using trigonometry without ever having to sin() a thing!fill= and color= for the shapes in truchet tile