Воспроизведение «Компьютерной композиции со строками» в R

#r #ggplot2 #random

#r #ggplot2 #Случайный

Вопрос:

Ребята,

Я пытаюсь воспроизвести известную компьютерную художественную работу «Компьютерная композиция с линиями» А. Майкла Нолла на языке R, используя ggplot.

Вот оригинал: https://collections.vam.ac.uk/item/O1193787/computer-composition-with-lines-photograph-noll-a-michael/

Я дошел до того, что могу создать круг из случайных черных или белых пикселей, но мне трудно создавать шаблоны, подобные тем, которые использует Noll.

Я могу легко создать матрицу из единиц и нулей, а затем вырезать части, которые выходят за пределы круга. Но шаблон (я пробовал равномерный, бета, обычный …) определенно слишком похож на белый шум, в то время как в случайности оригинальной работы есть структура.

 library(tidyverse)

# this generates the matrix
genData <- function(N) {

  # a N*N matrix of ones and zero according to a rounded beta draw
  df <- tibble(x = rep(seq(1,N), N),
         y = rep(seq(1,N), each = N),
         z = round(rbeta(N*N, 2, 1)))

  # centering on zero and cutting away all points outside of a circle
  df %>% 
    mutate(x = x-(N/2   1), y = y-(N/2   1)) %>% 
    filter(x^2   y^2 < (N/2)^2)
}

#this plots the data
plotData <- function(df, color = "black"){
  df %>% 
    ggplot(aes(x,y, fill = as.factor(z))) 
    geom_tile() 
    scale_fill_manual(values = c(color, "white")) 
    coord_equal() 
    theme_void() 
    theme(legend.position = "none")
}

#executing
genData(100) %>% 
  plotData()
  

Что приводит к:

введите описание изображения здесь

Я полагаю, вопрос сводится к тому, какой случайный процесс я могу использовать здесь? Я не нашел ни одной зацепки в Интернете.

Ответ №1:

Я думаю, это немного приблизит вас. Я также сократил код, используя geom_segment , который позволяет извлекать длины из распределения Пуассона.

Она включает в себя некоторую логику, чтобы сделать строки в верхней части короче.

Если вы попробуете это с разными случайными начальными значениями, вы, вероятно, найдете то, что вам понравится:

 draw_picture <- function(seed = 1, density = 1, length = 2, 
                         col = "black", bg = "gray90")
{
  set.seed(seed)
  
  x <- sample(100, 600 * density, TRUE) - 50
  y <- sample(100, 600 * density, TRUE) - 50
  ss <- which(sqrt(x^2   y^2) < 50)
  x <- x[ss]
  y <- y[ss]
  orient <- sample(2, length(x), TRUE)
  
  lambda <- abs(ifelse(y > 0, length - 2/3 * length * abs(atan(y/x)), length))
  lens <- rpois(length(x), lambda)   1
  end_x <- (orient %% 2) * lens   x
  end_y <- (orient - 1) * lens   y
  df <- data.frame(x, y, end_x, end_y)
  
  ggplot(df, aes(x, y))  
    geom_segment(aes(xend = end_x, yend = end_y), color = col, size = 2)  
    coord_equal()  
    theme_void()  
    theme(panel.background = element_rect(fill = bg, color = NA))
}
  

Итак, вы можете сделать:

 draw_picture(8)
  

введите описание изображения здесь

Или настройте ее с помощью параметров:

 draw_picture(2020, density = 0.9, length = 5, col = "#567AFF", bg = "#2345A0")
  

введите описание изображения здесь

Комментарии:

1. Блестяще. Спасибо, это определенно становится ближе. Я не думал об использовании geom_segment, я думал о какой-то игре с правилами жизни для точек, чтобы сегменты «появлялись». Я полагаю, что оставшееся (трудное, насколько я вижу) — это иметь точечные артефакты вверху, а более сегментные — внизу. Случайный процесс должен каким-то образом зависеть от позиции, но я не понял, как. Спасибо!

2. @PaoloCrosetto это тоже возможно, хотя я не был уверен, было ли это просто случайным. Я посмотрю еще раз, когда вернусь к своему компьютеру.

3. не могли бы вы просто создать length функцию x и y ? например, расстояние от 75,75

4. @PaoloCrosetto смотрите мое обновление. Это еще немного ближе.