Skip to content

Instantly share code, notes, and snippets.

@yutannihilation
Created July 21, 2022 13:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yutannihilation/3f687903197f55824e62c2a14be7c3d0 to your computer and use it in GitHub Desktop.
Save yutannihilation/3f687903197f55824e62c2a14be7c3d0 to your computer and use it in GitHub Desktop.
library(ggplot2)
library(patchwork)
library(dplyr, warn.conflicts = FALSE)
d <- string2path::string2path("R", "Arial")
max_dist <- 0.003
d2 <- d |>
group_by(glyph_id, path_id) |>
summarise(
slider::slide2_dfr(x, y, \(x, y) {
if (length(x) == 1L) {
return(vctrs::data_frame(x = x, y = y))
}
dist <- sqrt((x[2] - x[1])^2 + (y[2] - y[1])^2)
if (dist < max_dist) {
# 1つ目は前の区間に含まれているので取り除く
return(vctrs::data_frame(x = x[2], y = y[2]))
}
# max_distを超えない最大の長さになるように分割する
n <- ceiling(dist / max_dist)
if (identical(x[1], x[2])) {
# approxはX軸に垂直だと使えない
vctrs::data_frame(x = x[1], y = seq(y[1], y[2], length.out = n))
} else {
out <- approx(x, y, n = n)
# 1つ目は前の区間に含まれているので取り除く
vctrs::data_frame(x = out$x[-1], y = out$y[-1])
}
}, .before = 1L),
.groups = "drop"
)
steps <- 150
pt <- c(0.5, 0.5)
gifski::save_gif(
for (i in seq_len(steps)) {
x <- 0.3 + 0.23 * i / steps * cos(28 * i / steps)
y <- 0.3 + 0.23 * i / steps * sin(23 * i / steps)
pt <- c(x, y)
m <- cbind(d2$x, d2$y)
m2 <- t(apply(m, 1, function(row) {
dist <- sqrt(sum((row - pt)^2))
row + (row - pt) / dist * (i / steps)^1.4
}))
d_tmp <- d2 |>
mutate(x = m2[, 1], y = m2[, 2])
p <- ggplot(d_tmp, aes(x, y)) +
geom_path(aes(group = path_id, colour = factor(path_id))) +
geom_point(aes(colour = factor(path_id)), size = 2) +
geom_point(data = data.frame(x, y), size = 10, colour = "black") +
coord_fixed() +
theme_void() +
guides(colour = "none")
print(p)
},
delay = 1 / 60
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment