Here I experiment with creating contours of Truchet tiles after seeing some really cool examples (see: https://twitter.com/_sayo_y/status/1488504770755440640).
I will use these packages:
library(bezier) library(imager) library(lwgeom) library(MexBrewer) library(sf) library(tidyverse) library(truchet)
Try function:
st_truchet_flex(type = "Al", b = 1/2) %>% plot()
Design data frame with alternating values of b according to a checkerboard pattern. This is identical to the 2-by-2 arrangement of AC-CA called "design C" by Truchet (see p. 122 of Bosch and Colley, 2013):
df <- data.frame(expand.grid(x = 1:10, y = 1:10)) df <- df %>% # The modulus of x + y can be used to create a checkerboard pattern mutate(tiles = case_when((x + y) %% 2 == 0 ~ "Al", (x + y) %% 2 == 1 ~ "Cl"), b = 1/2) # b = ifelse((x + y) %% 2 == 1, 1/3, 2/3))
Create mosaic:
mosaic <- st_truchet_fm(df = df)
Plot:
mosaic %>% ggplot() + geom_sf(aes(fill = color), color = "white") + scale_fill_distiller(direction = 1)
Data frame with random values of b:
df <- data.frame(expand.grid(x = 1:10, y = 1:10)) df <- df %>% # The modulus of x + y can be used to create a checkerboard pattern mutate(tiles = case_when((x + y) %% 2 == 0 ~ "Al", (x + y) %% 2 == 1 ~ "Cl"), b = runif(n(), 1/3, 1/2))
Create mosaic:
mosaic <- st_truchet_fm(df = df)
Plot:
mosaic %>% st_truchet_dissolve() %>% ggplot() + geom_sf(aes(fill = color), color = "white") + scale_fill_distiller(direction = 1)
"Design D" is as follows: $$ \begin{array}\ B & A\ C & D \end{array} $$ Recreate this design:
df <- data.frame(expand.grid(x = 1:10, y = 1:10)) df <- df %>% # The modulus of x + y can be used to create the desired pattern mutate(tiles = case_when(x %% 2 == 1 & y %% 2 == 0 ~ "Bl", x %% 2 == 0 & y %% 2 == 0 ~ "Al", x %% 2 == 1 & y %% 2 == 1 ~ "Cl", x %% 2 == 0 & y %% 2 == 1 ~ "Dl"), b = 1/2)
Create mosaic:
mosaic <- st_truchet_fm(df = df)
Plot:
ggplot() + geom_sf(data = mosaic, aes(fill = color), color = "white", size = 0.5) + scale_fill_distiller(direction = 1)
"Design E" appears in the article as: $$ \begin{array}\ C & B\ D & A \end{array} $$ Recreate this design:
df <- data.frame(expand.grid(x = 1:10, y = 1:10)) df <- df %>% # The modulus of x + y can be used to create the desired pattern mutate(tiles = case_when(x %% 2 == 1 & y %% 2 == 0 ~ "Al", x %% 2 == 0 & y %% 2 == 0 ~ "Dl", x %% 2 == 1 & y %% 2 == 1 ~ "Bl", x %% 2 == 0 & y %% 2 == 1 ~ "Cl"), b = 1/2)
Create mosaic:
mosaic <- st_truchet_fm(df = df)
Plot (notice the difference with figure 2 in Bosch and Colley):
ggplot() + geom_sf(data = mosaic, aes(fill = color), color = "white", size = 0.5) + scale_fill_distiller(direction = 1)
The mosaic above looks different because "Design E" in Figure 2 in Bosch and Colley is actually a 4 by 4 matrix: $$ \begin{array}\ B & C & D & A\ A & D & C & B\ D & A & B & C\ C & B & D & A\ \end{array} $$
Recreate this design:
df <- data.frame(expand.grid(x = 1:12, y = 1:12)) df <- df %>% mutate(tiles = case_when(y %% 4 == 1 & x %% 4 == 1 ~ "Bl", y %% 4 == 1 & x %% 4 == 2 ~ "Cl", y %% 4 == 1 & x %% 4 == 3 ~ "Dl", y %% 4 == 1 & x %% 4 == 0 ~ "Al", # Second Row y %% 4 == 2 & x %% 4 == 1 ~ "Al", y %% 4 == 2 & x %% 4 == 2 ~ "Dl", y %% 4 == 2 & x %% 4 == 3 ~ "Cl", y %% 4 == 2 & x %% 4 == 0 ~ "Bl", # Third Row y %% 4 == 3 & x %% 4 == 1 ~ "Dl", y %% 4 == 3 & x %% 4 == 2 ~ "Al", y %% 4 == 3 & x %% 4 == 3 ~ "Bl", y %% 4 == 3 & x %% 4 == 0 ~ "Cl", # Fourth Row y %% 4 == 0 & x %% 4 == 1 ~ "Cl", y %% 4 == 0 & x %% 4 == 2 ~ "Bl", y %% 4 == 0 & x %% 4 == 3 ~ "Al", y %% 4 == 0 & x %% 4 == 0 ~ "Dl"), b = 1/2)
Create mosaic:
mosaic <- st_truchet_fm(df = df)
Plot:
ggplot() + geom_sf(data = mosaic, aes(fill = color), color = "white", size = 0.5) + scale_fill_distiller(direction = 1)
"Design 1" attributed to Douat by Bosch and Colley is based on a 2 by 4 matrix: $$ \begin{array}\ D & A & C & B\ A & D & B & C\ \end{array} $$
Recreate this design:
df <- data.frame(expand.grid(x = 1:12, y = 1:12)) df <- df %>% mutate(tiles = case_when(y %% 2 == 1 & x %% 4 == 1 ~ "Dl", y %% 2 == 1 & x %% 4 == 2 ~ "Al", y %% 2 == 1 & x %% 4 == 3 ~ "Cl", y %% 2 == 1 & x %% 4 == 0 ~ "Bl", # Second Row y %% 2 == 0 & x %% 4 == 1 ~ "Al", y %% 2 == 0 & x %% 4 == 2 ~ "Dl", y %% 2 == 0 & x %% 4 == 3 ~ "Bl", y %% 2 == 0 & x %% 4 == 0 ~ "Cl"), b = 1/2)
Create mosaic:
mosaic <- st_truchet_fm(df = df)
Plot:
ggplot() + geom_sf(data = mosaic, aes(fill = color), color = "white", size = 0.5) + scale_fill_distiller(direction = 1)
"Design 6" attributed to Douat by Bosch and Colley is based on a 4 by 4 matrix: $$ \begin{array}\ C & B & C & B\ B & D & A & C\ A & C & B & D\ D & A & D & A\ \end{array} $$
Recreate this design:
df <- data.frame(expand.grid(x = 1:12, y = 1:12)) df <- df %>% mutate(tiles = case_when(y %% 4 == 1 & x %% 4 == 1 ~ "Cl", y %% 4 == 1 & x %% 4 == 2 ~ "Bl", y %% 4 == 1 & x %% 4 == 3 ~ "Cl", y %% 4 == 1 & x %% 4 == 0 ~ "Bl", # Second Row y %% 4 == 2 & x %% 4 == 1 ~ "Bl", y %% 4 == 2 & x %% 4 == 2 ~ "Dl", y %% 4 == 2 & x %% 4 == 3 ~ "Al", y %% 4 == 2 & x %% 4 == 0 ~ "Cl", # Third Row y %% 4 == 3 & x %% 4 == 1 ~ "Al", y %% 4 == 3 & x %% 4 == 2 ~ "Cl", y %% 4 == 3 & x %% 4 == 3 ~ "Bl", y %% 4 == 3 & x %% 4 == 0 ~ "Dl", # Fourth Row y %% 4 == 0 & x %% 4 == 1 ~ "Dl", y %% 4 == 0 & x %% 4 == 2 ~ "Al", y %% 4 == 0 & x %% 4 == 3 ~ "Dl", y %% 4 == 0 & x %% 4 == 0 ~ "Al"), b = 1/2)
Create mosaic:
mosaic <- st_truchet_fm(df = df)
Plot:
ggplot() + geom_sf(data = mosaic, aes(fill = color), color = "white", size = 0.5) + scale_fill_distiller(direction = 1)
Try with buffers:
ggplot() + geom_sf(data = mosaic, aes(fill = color), color = NA, size = 0.5) + geom_sf(data = mosaic %>% st_truchet_dissolve() %>% st_buffer(dist = c(-0.1)) %>% filter(color == 2), fill = NA, color = "white", size = 0.5) + geom_sf(data = mosaic %>% st_truchet_dissolve() %>% st_buffer(dist = c(-0.2)) %>% filter(color == 2), fill = NA, color = "white", size = 0.5) + scale_fill_distiller(direction = 1) + theme_void() + theme(legend.position = "none")
Take a 2 by 2 mosaic and assign tiles randomly:
# Set seed seed <- 84467 set.seed(seed) # Coordinates for tiles df <- data.frame(expand.grid(x = 1:4, y = 1:4)) # Randomly select tiles tiles <- sample(c("Al", "Bl", "Cl", "Dl"), size = 4, replace = TRUE) # Design the mosaic df <- df %>% # The modulus of x + y can be used to create the desired pattern mutate(tiles = case_when(x %% 2 == 1 & y %% 2 == 0 ~ tiles[1], x %% 2 == 0 & y %% 2 == 0 ~ tiles[2], x %% 2 == 1 & y %% 2 == 1 ~ tiles[3], x %% 2 == 0 & y %% 2 == 1 ~ tiles[4]), b = 1/2) # Assemble mosaic mosaic <- st_truchet_fm(df = df) # Plot: ggplot() + geom_sf(data = mosaic %>% st_truchet_dissolve(), aes(fill = color), color = NA, size = 0.5) + geom_sf(data = mosaic %>% st_truchet_dissolve() %>% st_buffer(dist = c(-0.15)) %>% filter(color == 2), fill = NA, color = "white", size = 0.5) + scale_fill_distiller(direction = 1) + theme_void() + theme(legend.position = "none") #ggsave(glue::glue("truchet_2x2_{seed}.png"))
Take a 4 by 4 mosaic and assign tiles randomly:
# Set seed seed <- 298265805 set.seed(seed) # Coordinates for tiles df <- data.frame(expand.grid(x = 1:10, y = 1:10)) # Randomly select tiles tiles_1 <- sample(c("Al", "Bl", "Cl", "Dl"), size = 4, replace = TRUE) tiles_2 <- sample(c("Al", "Bl", "Cl", "Dl"), size = 4, replace = TRUE) tiles_3 <- sample(c("Al", "Bl", "Cl", "Dl"), size = 4, replace = TRUE) tiles_4 <- sample(c("Al", "Bl", "Cl", "Dl"), size = 4, replace = TRUE) df <- data.frame(expand.grid(x = 1:12, y = 1:12)) df <- df %>% mutate(tiles = case_when(y %% 4 == 1 & x %% 4 == 1 ~ tiles_1[1], y %% 4 == 1 & x %% 4 == 2 ~ tiles_1[2], y %% 4 == 1 & x %% 4 == 3 ~ tiles_1[3], y %% 4 == 1 & x %% 4 == 0 ~ tiles_1[4], # Second Row y %% 4 == 2 & x %% 4 == 1 ~ tiles_2[1], y %% 4 == 2 & x %% 4 == 2 ~ tiles_2[2], y %% 4 == 2 & x %% 4 == 3 ~ tiles_2[3], y %% 4 == 2 & x %% 4 == 0 ~ tiles_2[4], # Third Row y %% 4 == 3 & x %% 4 == 1 ~ tiles_3[1], y %% 4 == 3 & x %% 4 == 2 ~ tiles_3[2], y %% 4 == 3 & x %% 4 == 3 ~ tiles_3[3], y %% 4 == 3 & x %% 4 == 0 ~ tiles_3[4], # Fourth Row y %% 4 == 0 & x %% 4 == 1 ~ tiles_4[1], y %% 4 == 0 & x %% 4 == 2 ~ tiles_4[2], y %% 4 == 0 & x %% 4 == 3 ~ tiles_4[3], y %% 4 == 0 & x %% 4 == 0 ~ tiles_4[4]), b = 1/2) # Assemble mosaic mosaic <- st_truchet_fm(df = df) # Plot: ggplot() + geom_sf(data = mosaic %>% st_truchet_dissolve(), aes(fill = color), color = NA, size = 0.5) + geom_sf(data = mosaic %>% st_truchet_dissolve() %>% st_buffer(dist = c(-0.15)) %>% filter(color == 2), fill = NA, color = "white", size = 0.5) + scale_fill_distiller(direction = 1) + theme_void() + theme(legend.position = "none") ggsave(glue::glue("truchet_4x4_{seed}.png"))
Load package to work with images:
library(imager)
Read the image using imager::load.image():
elvis <- load.image("elvis.jpg")
Image info:
elvis
plot(elvis)
Resize image:
elvis_rs <- imresize(elvis, scale = 1/10, interpolation = 6)
Convert to grayscale and to data frame:
elvis_df <- elvis_rs %>% grayscale() %>% as.data.frame()
Use this data frame to design truchet mosaic:
df <- elvis_df %>% # Reverse the y axis mutate(y = -(y - max(y)), # The modulus of x + y can be used to create a checkerboard pattern tiles = case_when((x + y) %% 2 == 0 ~ "Al", (x + y) %% 2 == 1 ~ "Cl"), b = case_when((x + y) %% 2 == 0 ~ 1 - value, (x + y) %% 2 == 1 ~ value))
Create mosaic and time process (it takes about 4 minutes to process an image of 200 by 300 pixels or so):
# Start a timer start_time <- Sys.time() # Assemble mosaic mosaic <- st_truchet_fm(df = df %>% mutate(b = b * 0.99 + 0.001)) # End timer end_time <- Sys.time() # Calculate time end_time - start_time
Plot:
mosaic %>% ggplot() + geom_sf(aes(fill = color), color = NA) + scale_fill_distiller(direction = 1) + theme_void() + theme(legend.position = "none") ggsave("elvis-truchet.png")
Read another image:
frida <- load.image("frida.jpg")
Image info:
frida
plot(frida)
frida_sel <- imsub(frida,x %inr% c(109,500))
Resize image:
frida_rs <- imresize(frida_sel, scale = 1/4, interpolation = 6)
Convert to grayscale and to data frame:
frida_df <- frida_rs %>% grayscale() %>% as.data.frame()
Use this data frame to design truchet mosaic according to the pattern "Design A":
df <- frida_df %>% # Reverse the y axis mutate(y = -(y - max(y)), tiles = "Al", b = 1 - value)
Create mosaic:
# Start a timer start_time <- Sys.time() # Assemble mosaic mosaic <- st_truchet_fm(df = df %>% mutate(b = b * 0.80 + 0.001)) # End timer end_time <- Sys.time() # Calculate time end_time - start_time
Plot:
mosaic %>% ggplot() + geom_sf(aes(fill = color), color = NA) + scale_fill_gradientn(colors = mex.brewer("Frida")) + theme_void() + theme(legend.position = "none") ggsave("frida-truchet-design-a.png")
Use this data frame to design truchet mosaic using Design C:
df <- frida_df %>% # Reverse the y axis mutate(y = -(y - max(y)), # The modulus of x + y can be used to create a checkerboard pattern tiles = case_when((x + y) %% 2 == 0 ~ "Al", (x + y) %% 2 == 1 ~ "Cl"), b = case_when((x + y) %% 2 == 0 ~ 1 - value, (x + y) %% 2 == 1 ~ value))
Create mosaic:
# Start a timer start_time <- Sys.time() # Assemble mosaic mosaic <- st_truchet_fm(df = df %>% mutate(b = b * 0.80 + 0.001)) # End timer end_time <- Sys.time() # Calculate time end_time - start_time
Plot:
mosaic %>% ggplot() + geom_sf(aes(fill = color), color = NA) + scale_fill_gradientn(colors = mex.brewer("Frida")) + theme_void() + theme(legend.position = "none") ggsave("frida-truchet-design-c.png")
Frida in Design D:
df <- frida_df %>% # Reverse the y axis mutate(y = -(y - max(y)), # The modulus can be used to create a checkerboard pattern tiles = case_when(x %% 2 == 1 & y %% 2 == 0 ~ "Bl", x %% 2 == 0 & y %% 2 == 0 ~ "Al", x %% 2 == 1 & y %% 2 == 1 ~ "Cl", x %% 2 == 0 & y %% 2 == 1 ~ "Dl"), b = case_when(x %% 2 == 1 & y %% 2 == 0 ~ 1 - value, x %% 2 == 0 & y %% 2 == 0 ~ 1 - value, x %% 2 == 1 & y %% 2 == 1 ~ value, x %% 2 == 0 & y %% 2 == 1 ~ value))
Create mosaic:
# Start a timer start_time <- Sys.time() # Assemble mosaic mosaic <- st_truchet_fm(df = df %>% mutate(b = b * 0.80 + 0.001)) # End timer end_time <- Sys.time() # Calculate time end_time - start_time
Plot:
mosaic %>% ggplot() + geom_sf(aes(fill = color), color = NA) + scale_fill_gradientn(colors = mex.brewer("Frida")) + theme_void() + theme(legend.position = "none") ggsave("frida-truchet-design-d.png")
Frida in the (mistaken) Design E:
df <- frida_df %>% # Reverse the y axis mutate(y = -(y - max(y)), # The modulus of x + y can be used to create a checkerboard pattern tiles = case_when(x %% 2 == 1 & y %% 2 == 0 ~ "Al", x %% 2 == 0 & y %% 2 == 0 ~ "Dl", x %% 2 == 1 & y %% 2 == 1 ~ "Bl", x %% 2 == 0 & y %% 2 == 1 ~ "Cl"), b = case_when(x %% 2 == 1 & y %% 2 == 0 ~ 1 - value, x %% 2 == 0 & y %% 2 == 0 ~ value, x %% 2 == 1 & y %% 2 == 1 ~ 1 - value, x %% 2 == 0 & y %% 2 == 1 ~ value))
Create mosaic:
# Start a timer start_time <- Sys.time() # Assemble mosaic mosaic <- st_truchet_fm(df = df %>% mutate(b = b * 0.99 + 0.001)) # End timer end_time <- Sys.time() # Calculate time end_time - start_time
Plot (notice the difference with figure 2 in Bosch and Colley):
mosaic %>% ggplot() + geom_sf(aes(fill = color), color = NA) + scale_fill_gradientn(colors = mex.brewer("Frida")) + theme_void() + theme(legend.position = "none") ggsave("frida-truchet-design-wrong-e.png")
Read another image:
gara <- load.image("gara-one.jpg")
Image info:
gara
plot(gara)
gara_sel <- imsub(gara, x %inr% c(250, 849), y %inr% c(0, 900))
Resize image:
gara_rs <- imresize(gara_sel, scale = 1/7, interpolation = 6)
Convert to grayscale and to data frame:
gara_df <- gara_rs %>% grayscale() %>% as.data.frame()
Use this data frame to design truchet mosaic according to the pattern "Design A":
df <- gara_df %>% # Reverse the y axis mutate(y = -(y - max(y)), tiles = "Al", b = 1 - value)
Create mosaic:
# Start a timer start_time <- Sys.time() # Assemble mosaic mosaic <- st_truchet_fm(df = df %>% mutate(b = b * 0.80 + 0.001)) # End timer end_time <- Sys.time() # Calculate time end_time - start_time
Plot:
mosaic %>% ggplot() + geom_sf(aes(fill = color), color = NA) + scale_fill_gradientn(colors = mex.brewer("Frida")) + theme_void() + theme(legend.position = "none") ggsave("gara-truchet-design-a.png")
Use this data frame to design truchet mosaic using Design C:
df <- gara_df %>% # Reverse the y axis mutate(y = -(y - max(y)), # The modulus of x + y can be used to create a checkerboard pattern tiles = case_when((x + y) %% 2 == 0 ~ "Al", (x + y) %% 2 == 1 ~ "Cl"), b = case_when((x + y) %% 2 == 0 ~ 1 - value, (x + y) %% 2 == 1 ~ value))
Create mosaic:
# Start a timer start_time <- Sys.time() # Assemble mosaic mosaic <- st_truchet_fm(df = df %>% mutate(b = b * 0.80 + 0.001)) # End timer end_time <- Sys.time() # Calculate time end_time - start_time
Plot:
mosaic %>% ggplot() + geom_sf(aes(fill = color), color = NA) + scale_fill_gradientn(colors = mex.brewer("Frida")) + theme_void() + theme(legend.position = "none") ggsave("gara-truchet-design-c.png")
Gara in Design D:
df <- gara_df %>% # Reverse the y axis mutate(y = -(y - max(y)), # The modulus can be used to create a checkerboard pattern tiles = case_when(x %% 2 == 1 & y %% 2 == 0 ~ "Bl", x %% 2 == 0 & y %% 2 == 0 ~ "Al", x %% 2 == 1 & y %% 2 == 1 ~ "Cl", x %% 2 == 0 & y %% 2 == 1 ~ "Dl"), b = case_when(x %% 2 == 1 & y %% 2 == 0 ~ 1 - value, x %% 2 == 0 & y %% 2 == 0 ~ 1 - value, x %% 2 == 1 & y %% 2 == 1 ~ value, x %% 2 == 0 & y %% 2 == 1 ~ value))
Create mosaic:
# Start a timer start_time <- Sys.time() # Assemble mosaic mosaic <- st_truchet_fm(df = df %>% mutate(b = b * 0.80 + 0.001)) # End timer end_time <- Sys.time() # Calculate time end_time - start_time
Plot:
mosaic %>% ggplot() + geom_sf(aes(fill = color), color = NA) + #scale_fill_gradientn(colors = mex.brewer("Frida")) + scale_fill_distiller(palette = "PuBu", direction = 1) + theme_void() + theme(legend.position = "none") ggsave("gara-truchet-design-d.png")
Gara in the (mistaken) Design E:
df <- gara_df %>% # Reverse the y axis mutate(y = -(y - max(y)), # The modulus of x + y can be used to create a checkerboard pattern tiles = case_when(x %% 2 == 1 & y %% 2 == 0 ~ "Al", x %% 2 == 0 & y %% 2 == 0 ~ "Dl", x %% 2 == 1 & y %% 2 == 1 ~ "Bl", x %% 2 == 0 & y %% 2 == 1 ~ "Cl"), b = case_when(x %% 2 == 1 & y %% 2 == 0 ~ 1 - value, x %% 2 == 0 & y %% 2 == 0 ~ value, x %% 2 == 1 & y %% 2 == 1 ~ 1 - value, x %% 2 == 0 & y %% 2 == 1 ~ value))
Create mosaic:
# Start a timer start_time <- Sys.time() # Assemble mosaic mosaic <- st_truchet_fm(df = df %>% mutate(b = b * 0.99 + 0.001)) # End timer end_time <- Sys.time() # Calculate time end_time - start_time
Plot (notice the difference with figure 2 in Bosch and Colley):
mosaic %>% ggplot() + geom_sf(aes(fill = color), color = NA) + scale_fill_gradientn(colors = mex.brewer("Frida")) + theme_void() + theme(legend.position = "none") ggsave("gara-truchet-design-wrong-e.png")
Read another image:
belen <- load.image("belen.jpg")
Image info:
belen
plot(belen)
belen_sel <- imsub(belen, x %inr% c(100, 500), y %inr% c(22, 622))
Resize image:
belen_rs <- imresize(belen_sel, scale = 1/7, interpolation = 6)
Convert to grayscale and to data frame:
belen_df <- belen_rs %>% grayscale() %>% as.data.frame()
Use this data frame to design truchet mosaic according to the pattern "Design A":
df <- belen_df %>% # Reverse the y axis mutate(y = -(y - max(y)), tiles = "Al", b = 1 - value)
Create mosaic:
# Start a timer start_time <- Sys.time() # Assemble mosaic mosaic <- st_truchet_fm(df = df %>% mutate(b = b * 0.80 + 0.001)) # End timer end_time <- Sys.time() # Calculate time end_time - start_time
Plot:
mosaic %>% ggplot() + geom_sf(aes(fill = color), color = NA) + #scale_fill_gradientn(colors = mex.brewer("Frida")) + scale_fill_distiller(direction = 1) + theme_void() + theme(legend.position = "none") ggsave("belen-truchet-design-a.png")
Use this data frame to design truchet mosaic using Design C:
df <- belen_df %>% # Reverse the y axis mutate(y = -(y - max(y)), # The modulus of x + y can be used to create a checkerboard pattern tiles = case_when((x + y) %% 2 == 0 ~ "Al", (x + y) %% 2 == 1 ~ "Cl"), b = case_when((x + y) %% 2 == 0 ~ 1 - value, (x + y) %% 2 == 1 ~ value))
Create mosaic:
# Start a timer start_time <- Sys.time() # Assemble mosaic mosaic <- st_truchet_fm(df = df %>% mutate(b = b * 0.80 + 0.001)) # End timer end_time <- Sys.time() # Calculate time end_time - start_time
Plot:
mosaic %>% ggplot() + geom_sf(aes(fill = color), color = NA) + #scale_fill_gradientn(colors = mex.brewer("Frida")) + scale_fill_distiller(direction = 1) + theme_void() + theme(legend.position = "none") ggsave("belen-truchet-design-c.png")
Belen in Design D:
df <- belen_df %>% # Reverse the y axis mutate(y = -(y - max(y)), # The modulus can be used to create a checkerboard pattern tiles = case_when(x %% 2 == 1 & y %% 2 == 0 ~ "Bl", x %% 2 == 0 & y %% 2 == 0 ~ "Al", x %% 2 == 1 & y %% 2 == 1 ~ "Cl", x %% 2 == 0 & y %% 2 == 1 ~ "Dl"), b = case_when(x %% 2 == 1 & y %% 2 == 0 ~ 1 - value, x %% 2 == 0 & y %% 2 == 0 ~ 1 - value, x %% 2 == 1 & y %% 2 == 1 ~ value, x %% 2 == 0 & y %% 2 == 1 ~ value))
Create mosaic:
# Start a timer start_time <- Sys.time() # Assemble mosaic mosaic <- st_truchet_fm(df = df %>% mutate(b = b * 0.80 + 0.001)) # End timer end_time <- Sys.time() # Calculate time end_time - start_time
Plot:
mosaic %>% ggplot() + geom_sf(aes(fill = color), color = NA) + #scale_fill_gradientn(colors = mex.brewer("Frida")) + scale_fill_distiller(direction = 1) + theme_void() + theme(legend.position = "none") ggsave("belen-truchet-design-d.png")
Belen in the (mistaken) Design E:
df <- belen_df %>% # Reverse the y axis mutate(y = -(y - max(y)), # The modulus of x + y can be used to create a checkerboard pattern tiles = case_when(x %% 2 == 1 & y %% 2 == 0 ~ "Al", x %% 2 == 0 & y %% 2 == 0 ~ "Dl", x %% 2 == 1 & y %% 2 == 1 ~ "Bl", x %% 2 == 0 & y %% 2 == 1 ~ "Cl"), b = case_when(x %% 2 == 1 & y %% 2 == 0 ~ 1 - value, x %% 2 == 0 & y %% 2 == 0 ~ value, x %% 2 == 1 & y %% 2 == 1 ~ 1 - value, x %% 2 == 0 & y %% 2 == 1 ~ value))
Create mosaic:
# Start a timer start_time <- Sys.time() # Assemble mosaic mosaic <- st_truchet_fm(df = df %>% mutate(b = b * 0.99 + 0.001)) # End timer end_time <- Sys.time() # Calculate time end_time - start_time
Plot (notice the difference with figure 2 in Bosch and Colley):
mosaic %>% ggplot() + geom_sf(aes(fill = color), color = NA) + #scale_fill_gradientn(colors = mex.brewer("Frida")) + scale_fill_distiller(direction = 1) + theme_void() + theme(legend.position = "none") ggsave("belen-truchet-design-wrong-e.png")
Random placement of tiles?
# Set seed seed <- 84467 set.seed(seed) # Coordinates for tiles df <- data.frame(expand.grid(x = 1:2, y = 1:2)) # Randomly select tiles tiles <- sample(c("Al", "Bl", "Cl", "Dl"), size = 4, replace = TRUE) value <- 3/4 # Design the mosaic df <- df %>% # The modulus of x + y can be used to create the desired pattern mutate(tiles = case_when(x %% 2 == 1 & y %% 2 == 0 ~ tiles[1], x %% 2 == 0 & y %% 2 == 0 ~ tiles[2], x %% 2 == 1 & y %% 2 == 1 ~ tiles[3], x %% 2 == 0 & y %% 2 == 1 ~ tiles[4]), # Important! Notice the adjustment to the values to ensure that the area correctly reflects the underlying darkness value b = case_when(tiles == "Al" ~ value, tiles == "Bl" ~ value, tiles == "Cl" ~ 1 - value, tiles == "Dl" ~ 1 - value)) # Assemble mosaic mosaic <- st_truchet_fm(df = df) # Plot: ggplot() + geom_sf(data = mosaic, aes(fill = color), color = NA, size = 0.5) + scale_fill_distiller(direction = 1) + theme_void() + theme(legend.position = "none") #ggsave(glue::glue("truchet_2x2_{seed}.png"))
Belen with a random mosaic:
# Set seed seed <- 1085 set.seed(seed) # Randomly select tiles tiles <- sample(c("Al", "Bl", "Cl", "Dl"), size = 4, replace = TRUE) value <- 3/4 # Design the mosaic df <- belen_df %>% # Reverse the y axis mutate(y = -(y - max(y)), tiles = case_when(x %% 2 == 1 & y %% 2 == 0 ~ tiles[1], x %% 2 == 0 & y %% 2 == 0 ~ tiles[2], x %% 2 == 1 & y %% 2 == 1 ~ tiles[3], x %% 2 == 0 & y %% 2 == 1 ~ tiles[4]), # Important! Notice the adjustment to the values to ensure that the area correctly reflects the underlying darkness value b = case_when(tiles == "Al" ~ 1- value, tiles == "Bl" ~ 1- value, tiles == "Cl" ~ value, tiles == "Dl" ~ value))
Create mosaic:
# Start a timer start_time <- Sys.time() # Assemble mosaic mosaic <- st_truchet_fm(df = df %>% mutate(b = b * 0.99 + 0.001)) # End timer end_time <- Sys.time() # Calculate time end_time - start_time
Plot (notice the difference with figure 2 in Bosch and Colley):
mosaic %>% st_truchet_dissolve() %>% ggplot() + geom_sf(aes(fill = color), color = NA) + #scale_fill_gradientn(colors = mex.brewer("Frida")) + scale_fill_distiller(direction = 1) + theme_void() + theme(legend.position = "none") ggsave(glue::glue("belen-truchet-{seed}.png"))
Random placement of tiles?
# Tiles types tile_types <- data.frame(type = c("Al", "Bl", "Cl", "Dl")) %>% mutate(x = c(1, 2.5, 1, 2.5), y = c(2.5, 2.5, 1, 1), b = 1/2) # Elements for assembling the mosaic x_c <- tile_types$x y_c <- tile_types$y type <- as.character(tile_types$type) b <- tile_types$b pmap_dfr(list(x_c, y_c, type, b), st_truchet_flex) %>% ggplot() + geom_sf(aes(fill = color), color = "black", size = 2) + geom_text(data = tile_types, aes(x = x, y = y, label = c("A", "B", "C", "D")), nudge_y = 0.6) + scale_fill_distiller(direction = 1) + theme_void() + theme(legend.position = "none") #ggsave(glue::glue("truchet_2x2_{seed}.png"))
# Tiles types tile_types <- data.frame(type = c("Al", "Al", "Al", "Al")) %>% mutate(x = c(1, 2, 1, 2), y = c(2, 2, 1, 1), b = 1/2) # Elements for assembling the mosaic x_c <- tile_types$x y_c <- tile_types$y type <- as.character(tile_types$type) b <- tile_types$b pmap_dfr(list(x_c, y_c, type, b), st_truchet_flex) %>% ggplot() + geom_sf(aes(fill = color), color = "black", size = 2) + geom_text(data = tile_types, aes(x = x, y = y, label = c("Design A", "", "", "")), nudge_y = 0.6) + scale_fill_distiller(direction = 1) + theme_void() + theme(legend.position = "none")
# Tiles types tile_types <- data.frame(type = c("Al", "Cl", "Cl", "Al")) %>% mutate(x = c(1, 2, 1, 2), y = c(2, 2, 1, 1), b = 1/2) # Elements for assembling the mosaic x_c <- tile_types$x y_c <- tile_types$y type <- as.character(tile_types$type) b <- tile_types$b pmap_dfr(list(x_c, y_c, type, b), st_truchet_flex) %>% ggplot() + geom_sf(aes(fill = color), color = "black", size = 2) + geom_text(data = tile_types, aes(x = x, y = y, label = c("Design C", "", "", "")), nudge_y = 0.6) + scale_fill_distiller(direction = 1) + theme_void() + theme(legend.position = "none")
# Tiles types tile_types <- data.frame(type = c("Al", "Dl", "Bl", "Cl")) %>% mutate(x = c(1, 2, 1, 2), y = c(2, 2, 1, 1), b = 1/2) # Elements for assembling the mosaic x_c <- tile_types$x y_c <- tile_types$y type <- as.character(tile_types$type) b <- tile_types$b pmap_dfr(list(x_c, y_c, type, b), st_truchet_flex) %>% ggplot() + geom_sf(aes(fill = color), color = "black", size = 2) + geom_text(data = tile_types, aes(x = x, y = y, label = c("Matrix [A, D; B, C]", "", "", "")), nudge_y = 0.6) + scale_fill_distiller(direction = 1) + theme_void() + theme(legend.position = "none")
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.