frak
frak
is a small R package to generate fractals - currently just Julia Sets.
I needed a fast way to generate test images for testing other software, with images that
- are fast to produce
- are interesting, not just white noise
- 8-bits-per-pixel, so the value can fit in an R
raw
vector or a Cuint8_t
vector. - can be be panned, zoomed and changed with simple changes to the input variables
Installation
You can install from GitHub with:
# install.package('remotes')
remotes::install_github('coolbutuseless/frak')
What’s in the box?
julia(cx, cy, movex, movey, zoom, size, max_iter)
generate a julia set, wherecx
andcy
are the components of imageinary iteration variable c.
Returned array of raw values represents the iteration count at which a particular location veered towards infinity. These values are scaled to span the full range from allowable within a raw vector (i.e. the whole numbers from 0 to 255)
Example: Generate a julia set
library(frak)
fractal <- julia(cx = -0.7, cy = 0.27, zoom = 1, size = 400, max_iter = 255)
mode(fractal) <- 'integer'
plot(as.raster(fractal/255))
Example: colour the image with viridis
library(viridisLite)
# generate a fractal
fractal <- julia(cx = -0.74, cy = 0.17, zoom = 3, size = 400, max_iter = 100)
mode(fractal) <- 'integer'
# Grab a palette from viridis
pal <- rev(viridisLite::viridis(256))
# Recode the values with the palette. Lowest raw value is 0, so offset by 1.
fractal_raster <- fractal
fractal_raster[] <- pal[fractal_raster + 1]
plot(as.raster(fractal_raster))
Example: git file rendered from multiple frames
Click to show/hide code to generate gif
library(foist)
library(displease)
library(frak)
dir.create('/img/frak/anim', showWarnings = FALSE)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Use {displease} to get a pleasing motion as the zoom is performed
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
N <- 100
zoom <- displease::seq_ease(1, 1000, n = N, type = 'exp-in')
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Loop: create an image dump it to file.
# Using {foist} here for fast image output
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for (i in seq(N)) {
frac <- frak::julia(cx = -0.71, zoom = zoom[i], movex = 0.1)
mode(frac) <- 'integer'
frac <- frac/255
filename <- sprintf("/img/frak/anim/%03i.png", i)
foist::write_png(
data = frac,
filename = filename,
pal = foist::vir$magma,
convert_to_row_major = FALSE
)
}
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Create the animation using imagemagick and delete the source frames
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
system("convert /img/frak/anim/*.png /img/frak/anim.gif")
unlink("/img/frak/anim/", recursive = TRUE)
Benchmark
Creating a julia set in C is about 100x faster than using plain R (as in the Julia package on CRAN)
Click to show/hide bench::mark() code
suppressPackageStartupMessages({
library(Julia)
library(frak)
library(ggplot2)
library(dplyr)
library(tidyr)
})
size <- 400
# Julia::JuliaImage does at most 50 iterations
res <- bench::mark(
`Julia::JuliaImage()` = Julia::JuliaImage(imageN = size, centre = 0.0, L = 4, C = 1-1.6180339887),
`frak::julia()` = julia(size = size, max_iter = 50),
check = FALSE
)
Warning: Some expressions had a GC in every iteration; so filtering is disabled.
expression | min | median | itr/sec |
---|---|---|---|
Julia::JuliaImage() | 802.68ms | 802.68ms | 1.24582 |
frak::julia() | 7.57ms | 7.92ms | 115.48860 |
Acknowledgements
- R Core for developing and maintaining such a wonderful language.
- CRAN maintainers, for patiently shepherding packages onto CRAN and maintaining the repository