circles <- function( image = "goldengate.png", n = 100, N = 100, alpha = .1, show.image = FALSE ){ im <- readPNG( image ) im.raster <- structure( rgb( im[,,1], im[,,2], im[,,3] ), dim = dim(im)[1:2] ) if( show.image ){ grid.raster( im.raster ) } xx <- rep( seq( 0, 1, length.out = ncol(im.raster) ), each = nrow(im.raster) ) yy <- rep( seq( 0, 1, length.out = nrow(im.raster) ), ncol(im.raster) ) for( i in 1:N ) { npoints <- max( 2, round( runif( 1, max = n ) ) ) d <- data.frame( x = runif(npoints), y = runif(npoints) ) dists <- as.matrix(dist(d)) d$r <- apply( dists, 1, function(.) min(.[.>0]) / 2.1 ) d$col <- sapply( 1:nrow(d), function(i){ dists <- sqrt( ( d[i,1] - xx ) ^ 2 + ( 1 - d[i,2] - yy ) ^ 2 ) idx <- which( dists < d[i,3] ) if( length(idx) ){ cols <- apply( col2rgb( im.raster[ idx ] ), 1, mean ) rgb( cols[1], cols[2], cols[3], maxColorValue = 255 ) } else { rgb( 0, 0, 0 ) } } ) grid.circle( d$x, d$y, d$r, gp = gpar( fill = d$col, alpha = alpha) ) } } png( "goldengate-circles.png", width = 800, height = 600 ) grid.newpage() circles( "goldengate.png", 200, 200, .2 ) dev.off()