CiRcle aRt 0.5

Inspired by Karel Novosad

Generative aRt
Author

Christian Knudsen

Published

October 26, 2025

Inspired by a print by Karel Novosad I saw in a window in Hamburg.

A number of straight lines, combined with circles - three colors on a black background.

We need a couple of libraries:

library(tidyverse)
library(ggforce)

We need a function to place circles

circles <- function(n = 3, seed = NULL) {
  set.seed(seed)
  z <- seq(1, 3, 0.25)
  x0 <- sample(z, n, replace  =TRUE)
  y0 <- sample(z, n, replace = TRUE)
  r <-  sample(c(0.25, 1, 0.25), n, replace = TRUE)
  colors <- sample(1:3, n, replace = TRUE) |> factor()
  df <- tibble(x0 = x0, y0 = y0, r = r)
  
  ggforce::geom_circle(
    data = df,
    mapping = aes(x0 = x0, y0 = y0, r = r, color = colors),
    fill = NA,
    inherit.aes = FALSE
  )
}

We need a function for adding lines:

lines <- function(n = 5, seed = NULL){
   z <- seq(1, 3, 0.25)
  x0 <- sample(z, n, replace = TRUE)
  y0 <- sample(z, n, replace = TRUE)
  l <-  sample(c(0.25, 3, 0.25), n, replace = TRUE)
  xy <- sample(c(0,1), n, replace = TRUE)
  dir <- sample(c(-1,1), n, replace = TRUE)
  colors <- sample(1:3, n, replace = TRUE) |> factor()
  tibble(x0 = x0, y0=y0, l = l, x = xy, dir = dir, color = colors) |> 
  mutate(y = as.numeric((x == 0))) |> 
   mutate(x1 = x0 + x * dir * l,
         y1 = y0 + y * dir * l) |>
    geom_segment(mapping = aes(x = x0, y = y0, xend = x1, yend = y1, color = colors), inherit.aes = FALSE)

}

And then we combine it. 5 circles, 11 lines:

ggplot() +
  circles(n = 5, seed = 666) +
  lines(n = 11, seed = 666) +
  coord_cartesian(xlim = c(0,4), ylim = c(0,4))  +
  theme_void()+
  theme(legend.position = "none",
        plot.background = element_rect(color = "black",
        fill = "black")) +
  annotate("text", x = 3.5, y = -0.1,
            size = 3,
            label = "seed = 666", 
            color = "white")

It should probably be refactored, use something different from default colors etc. Thats for version 1.0.