I wanted to try animating Truchet tiles after seeing some really cool examples (see: https://twitter.com/Eko3316/status/1487367084292157448).

I will use this packages:

library(gganimate)
library(sf)
library(tidyverse)
library(truchet)

Create a function to rotate a tile:

rotation = function(a, x, y, type){
  tile <- st_truchet_p(type = type)
  rm <- matrix(c(cos(a), sin(a), -sin(a), cos(a)), nrow = 2, ncol = 2)
  tile %>%
    mutate(geometry = st_geometry(tile) * rm + c(x, y)) %>%
    st_sf()
} 

Prepare the moving tile(s):

a <- c(seq(0, pi/2, pi/90), 
       rep(pi/2, 60),
       seq(pi/2, pi, pi/90),
       rep(pi, 60),
       seq(pi, 3 * pi/2, pi/90),
       rep(3 * pi/2, 60),
       seq(3 * pi/2, 2 * pi, pi/90),
       rep(2 * pi, 60))

tile_1 <- data.frame()
count <- 0
for(i in a){
  count <- count +1
  df <- rbind(tile_1,
              data.frame(rotation(a = i, x = 1, y = 1, type = "dr"), state = count))
}

tile_1 <- tile_1 %>%
  st_sf()

tile_2 <- data.frame()
count <- 0
for(i in a){
  count <- count +1
  df <- rbind(tile_2,
              data.frame(rotation(a = i, x = 2, y = 2, type = "dr"), state = count))
}

tile_2 <- tile_2 %>%
  st_sf()

Rest of mosaic:

xlim <- c(1, 2)
ylim <- c(1, 2)

# Create a data frame with the spots for tiles
container <- expand.grid(x = seq(xlim[1], xlim[2], 1),
                         y = seq(ylim[1], ylim[2], 1)) %>%
  #filter(x != 0 | y != 0) %>%
  mutate(tiles = sample(c("dr", "fne", "fse", "dr"), n(), replace = TRUE),
         scale_p = 1)

Assemble mosaic:

mosaic <- st_truchet_ms(df = container)

Create plot and render:

p <- ggplot() +
  geom_sf(data = mosaic,
          aes(fill = factor(color)),
          color = NA) +
  geom_sf(data = df %>% st_sf(),
          aes(fill = factor(color),
              group = state),
          color = NA) + 
  scale_fill_manual(values = c("1" = "#0057b7", "2" = "#ffd700")) + #values = c("black", "white")) +
  theme_void() +
  theme(legend.position = "none") +
  transition_time(state)

animate(p, rewind = FALSE,
        fps = 60,
        duration = 10,
        res = 300,
        height = 2, 
        width = 2,
        units = "in")

Save plot:

anim_save("animated-mosaic.gif")

Create plot and render:

p <- ggplot() +
  geom_sf(data = mosaic,
          aes(fill = factor(color)),
          color = NA) +
  geom_sf(data = df %>% st_sf(),
          aes(fill = factor(color),
              group = state),
          color = NA) + 
  scale_fill_manual(values = c("white", "black")) +
  theme_void() +
  theme(legend.position = "none") +
  transition_time(state)

animate(p, rewind = TRUE,
        fps = 60,
        duration = 10,
        res = 300,
        height = 2, 
        width = 2,
        units = "in")

Save plot:

anim_save("animated-mosaic-b.gif")

Another version

Moving tile(s):

a <- c(seq(0, pi/2, pi/90), 
       rep(pi/2, 60),
       seq(pi/2, pi, pi/90),
       rep(pi, 60),
       seq(pi, 3 * pi/2, pi/90),
       rep(3 * pi/2, 60),
       seq(3 * pi/2, 2 * pi, pi/90),
       rep(2 * pi, 60))

df <- data.frame()
count <- 0
for(i in a){
  count <- count +1
  df <- rbind(df,
              data.frame(rotation(a = i, x = 3, y = 3, type = "dl"), state = count))
}

df <- df %>%
  st_sf()

Rest of tiles:

xlim <- c(0, 6)
ylim <- c(0, 6)

# Create a data frame with the spots for tiles
container <- expand.grid(x = seq(xlim[1], xlim[2], 1),
                         y = seq(ylim[1], ylim[2], 1)) %>%
  dplyr::filter(x != 3 | y != 3) %>%
  mutate(tiles = sample(c("fnw", "-", "fse", "|"), n(), replace = TRUE),
         scale_p = sample(c(1, 1/2), n(), replace = TRUE))

Assemble mosaic:

mosaic <- st_truchet_ms(df = container)

Plot and render:

p <- ggplot() +
  geom_sf(data = mosaic,
          aes(fill = factor(color)),
          color = NA) +
  geom_sf(data = df %>% st_sf(),
          aes(fill = factor(color),
              group = state),
          color = NA) + 
  scale_fill_manual(values = c("black", "white")) +
  theme_void() +
  theme(legend.position = "none") +
  transition_time(state)

animate(p, rewind = TRUE,
        fps = 60,
        duration = 10,
        res = 300,
        height = 2, 
        width = 2, units = "in")

Save animation:

anim_save("animated-mosaic-2.gif")

Plot and render:

p <- ggplot() +
  geom_sf(data = mosaic,
          aes(fill = factor(color)),
          color = NA) +
  geom_sf(data = df %>% st_sf(),
          aes(fill = factor(color),
              group = state),
          color = NA) + 
  scale_fill_manual(values = c("white", "black")) +
  theme_void() +
  theme(legend.position = "none") +
  transition_time(state)

animate(p, rewind = TRUE,
        fps = 60,
        duration = 10,
        res = 300,
        height = 2, 
        width = 2, units = "in")

Save animation:

anim_save("animated-mosaic-2-b.gif")


paezha/truchet documentation built on April 27, 2022, 9:53 a.m.