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()