Miskatonic University Press

Animated intersecting circles

r mathematics

I was looking again at some of the intersecting circles I wrote about last month, looking at 2, 3, 4, 5, 6 intersecting circles one after the other, and it looked pretty smart, so I tried making an animated GIF out of it. The R package animation makes it pretty easy.

Here’s the setup, which gives the drawcircles function.

circle <- function(x, y, rad = 1.1, vertices = 500, ...) {
  rads <- seq(0, 2*pi, length.out = vertices)
  xcoords <- cos(rads) * rad + x
  ycoords <- sin(rads) * rad + y
  polygon(xcoords, ycoords, ...)
}

roots <- function(n) {
  lapply(
    seq(0, n - 1, 1),
    function(x)
      c(round(cos(2*x*pi/n), 4), round(sin(2*x*pi/n), 4))
  )
}

drawcircles <- function(n) {
  centres <- roots(n)
  plot(-2:2, type="n", xlim = c(-2,2), ylim = c(-2,2), asp = 1, xlab = "", ylab = "", axes = FALSE)
  lapply(centres, function (c) circle(c[[1]], c[[2]]))
}

We want to go from 1 circle to 60, then back down to 1, and then loop all of that so it repeats. The looping is taken care of by the GIF, but to generate a sequence of numbers (1, 2, 3, …, 59, 60, 59, …, 2) (the 1 will happen when the loop starts again ) we can use a simple R command. Here’s how to do it up to 10 and back:

> 1:10
 [1]  1  2  3  4  5  6  7  8  9 10
> 9:2
[1] 9 8 7 6 5 4 3 2
> c(1:10, 9:2)
 [1]  1  2  3  4  5  6  7  8  9 10  9  8  7  6  5  4  3  2

Putting it all together:

> library(animation)
> saveGIF({for (i in c(1:60, 59:2)) drawcircles(i)}, interval = 0.2, movie.name = "intersecting-circles.gif")
1 to 60 and back to 1 intersecting circles
(1, 2, 3, ..., 59, 60, 59, ..., 2) intersecting circles, looping

The GIF is 2.1 MB, which is pretty large. Perhaps there’s some way to make a smaller file. In any case, it’d be nice to see that projected on a huge wall. Nice vids.