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.
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
, end
geom_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.Rmd
set_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 r0
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: r0
, r
geom_arc_bar()
arguments: r0
, r
geom_arc_bar()
arguments: r0
, r
geom_arc_bar()
arguments: r0
, r
geom_arc_bar()
arguments: r0
, r
geom_arc_bar()
arguments: r0
, r
geom_arc_bar()
arguments: r0
, r
geom_arc_bar()
arguments: r0
, r
geom_arc_bar()
arguments: r0
, r
geom_arc_bar()
arguments: r0
, r
geom_arc_bar()
arguments: r0
, r
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]
)
}
)
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 fill
geom_arc_bar()
arguments: color
and fill
truchet_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.Rmd
exercise_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