Skip to content

Instantly share code, notes, and snippets.

@dewittpe
Last active September 23, 2020 19:15
Show Gist options
  • Save dewittpe/785ee3a77f8b346ddf3a1911101921d5 to your computer and use it in GitHub Desktop.
Save dewittpe/785ee3a77f8b346ddf3a1911101921d5 to your computer and use it in GitHub Desktop.
inscribed circles and regular polygons
# objective - plot circles and polygons such that
# 0. A circle
# 1. An equilateral triangle such that the edges are tangent to the circle
# 2. A circle such that the vertices of the triangle are on the circumference
# 3. A square with edges tangent to the circle drown in step 2.
# 4. A circle with the vertices of the square on the circumference
# 5. A regular pentagon....
#
# A vertex of the regular polygons will all be co-linear. That is, with the
# initial circle centered at the Cartesian point (0, 0), then on vertex for each
# of the regular polygons will have an x-coordinate of 0.
library(ggplot2)
library(ggforce) # needed for geom_circle
# Radius given length of side:
# r = s / (2 * sin(pi / n))
# where s is the length of the side of regular polygon
# n is the number of sides
# Apothem (inradius)
# r = a / cos(pi / n)
# a is the apothem
# n is the number of sides
# Get the vertices of a regular polygon centered at the origin given the apothem
# and at least one vertex with x = 0 (one vertex if n is odd, two if n is even)
vertices <- function(apothem = NULL, radius = NULL, n = 3, rotate = 0) {
if (!xor(is.null(apothem), is.null(radius)) ) {
stop("apothem xor radius needs to be defined")
}
if (!is.null(apothem)) {
radius <- apothem / cos(pi / n)
} else {
apothem <- radius * cos(pi / n)
}
pts <- matrix(c(0, radius), ncol = 1)
theta <- seq(0, 2 * pi, length = n + 1)[-(n + 1)] + rotate
rtn <- do.call(rbind, lapply(theta, function(th) {data.frame(x = - radius * sin (th), y = radius * cos(th))}))
rtn$n <- n
rtn$apothem <- apothem
rtn$radius <- radius
rtn
}
vertices(radius = 2)
circles <- data.frame(x0 = 0, y0 = 0, r = 1)
polygons <- data.frame <- vertices(apothem = 1)
for(i in 2:30) {
circles <- rbind(circles, data.frame(x0 = 0, y0 = 0, r = tail(polygons$radius, 1)))
polygons <- rbind(polygons,
vertices(apothem = circles[i, "r"], n = tail(polygons$n, 1) + 1)
)
}
# build up layers
p1 <-
lapply(
1:nrow(circles),
function(i) {
eval(
substitute(
list(
geom_polygon(data = subset(polygons, n == nn), mapping = aes(x = x, y = y, group = n), fill = "black"),
geom_circle(data = subset(circles, r == rr), mapping = aes(x0 = x0, y0 = y0, r = r), fill = "white", color = NA)
)
,
list(nn = rev(unique(polygons$n))[i],
rr = rev(unique(circles$r))[i]))
)
})
g1 <-
ggplot() +
p1 +
coord_fixed() +
theme_no_axes() +
theme(legend.position = "none",
panel.background = element_rect(fill = "black"))
# Another way
circles <- data.frame(x0 = 0, y0 = 0, r = 1)
polygons <- vertices(radius = 1, n = 3, rotate = pi)
for(i in 2:10) {
circles <- rbind(circles, data.frame(x0 = 0, y0 = 0, r = tail(polygons$apothem, 1)))
polygons <- rbind(polygons, vertices(radius = circles[i, "r"], n = tail(polygons$n, 1) + 1, rotate = pi)
)
}
p2 <-
lapply(
1:nrow(circles),
function(i) {
eval(
substitute(
list(
geom_circle(data = subset(circles, r == rr), mapping = aes(x0 = x0, y0 = y0, r = r), fill = "white", color = NA),
geom_polygon(data = subset(polygons, n == nn), mapping = aes(x = x, y = y, group = n), fill = "black")
)
,
list(nn = unique(polygons$n)[i],
rr = unique(circles$r)[i]))
)
})
g2 <-
ggplot() +
p2 +
coord_fixed() +
theme_no_axes() +
theme(legend.position = "none",
panel.background = element_rect(fill = "black"))
g3 <-
ggplot() +
p1 + p2 +
coord_fixed() +
theme_no_axes() +
theme(legend.position = "none",
panel.background = element_rect(fill = "black"))
gridExtra::grid.arrange(g1, g2, g3, nrow = 1)
ggsave(filename = "g1.pdf", g1, width = 8, height = 8)
# end of file
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment