Last active
September 23, 2020 19:15
-
-
Save dewittpe/785ee3a77f8b346ddf3a1911101921d5 to your computer and use it in GitHub Desktop.
inscribed circles and regular polygons
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment