/Reel.jl

computations caught on camera

Primary LanguageJuliaOtherNOASSERTION

Reel

Build Status

Film computations

Quickstart

Installation

Pkg.add("Reel")

This package now relies on FFMPEG.jl. For versions lower than 1.2 you will need ffmpeg and imagemagick installed to use Reel. This package supersedes ComposeVideo.jl

Usage

Reel exports the all-important function roll which you can use to roll the camera on various arguments:

using Reel
using Plots

function render(t, dt)
    # t is the time into the sequence
    # dt is the time to advance for the next frame

    # any expression that results in an object which can be
    # rendered as png or jpg
    plot([x -> sin(x+t*π), x -> cos(x+t*π)], 0, 6)
end

film = roll(render, fps=30, duration=2)

write("output.gif", film) # Write to a gif file

# Or
write("file.webm", film) # Write to a webm video

# Or
write("file.mp4", film)  # An mp4 formatted video

The same thing can be concisely written with Julia's do syntax:

film = roll(fps=30, duration=2) do t, dt
    plot([x -> sin(x+t*π), x -> cos(x+t*π)], 0, 6)
end

write("output.gif", film)

Note that the fps you specify to roll will be enforced no matter how long the computation actually takes: you set the speed at which you want to watch it.

Reel can also render an abstract array of objects:

using Compose
import Cairo, Fontconfig

Compose.set_default_graphic_size(3inch, 3inch) # Square

# draw a regular n-gon
ngon(n) = compose(context(units=UnitBox(-1, -1, 2, 2)), fill("lightblue"),
                polygon([(cos(x), sin(x)) for x in π/2:2π/n:3.5π]))

roll(map(ngon, vcat(3:10, 9:-1:3)), fps=5)

Reel exports Frames, a type for a collection of frames.

Frames constructor takes a MIME type of the frames, and the fps at which the animation should be rendered. e.g.

You can push a new frames to a Frames object using push!.

# A Glider gun from Conway's game of Life

using Reel
frames = Frames(MIME("image/png"), fps=2)

g = glider_gun # initial board state
for i=1:31
    push!(frames, draw(g))
    g = decidefate(g)
end

frames

You can render a Frames object as usual:

write("output.webm", frames)

In IJulia

A call to roll returns a Frames object. A method writemime(::IO, ::MIME{symbol("text/html"),::Frames) orchestrates the rendering of a Frames object in IJulia. Any cell which results in a Frames results in the animation being rendered. By default, a webm video is generated. You can change this behavior:

Reel.set_output_type("gif") # or "mp4"

They see me rollin', they hatin'

# particles in a box.

using Color, Compose

box(x) = let i = floor(x)
    i%2==0 ? x-i : 1+i-x
end

colors = distinguishable_colors(10, lchoices=[82.])

dots(points) = [(context(p[1], p[2], .03, .03), fill(colors[i%10+1]), circle())
    for (i, p) in enumerate(points)]

velocities = [(rand(), rand()) for i in 1:40]

roll(fps=30, duration=10.0) do t, dt

    compose(context(),
            dots([map(v -> box(v*t + 0.5), (vx, vy)) for (vx, vy) in velocities])...)
end

# Solution of Helmholtz equation with Dirichlet BC using ApproxFun

using ApproxFun

B=dirichlet(d)
Δ=lap(d)

plots = [ApproxFun.contour(pdesolve([B,Δ+k*I],ones(4),150))
            for k=vcat([1:1.0:100], [99:-1.0:1])]

roll(plots, fps=24)

# Warning: this gif is 8 mb!


Fin.