Last night I ran a free hands on Generative Art session to a full class room at Skills Matter for the F#unctional Londoners meetup group. We host a hands on programming sessions every month, next month we’ll return to the Machine Learning theme with Matt Moloney from the Tsunami IDE team.
Samples: http://trelford.com/GenerativeArt.zip
I recently picked up Matt Pearson’s Generative Art book published by Manning, his examples use the Processing programming language which is loosely based on Java. For the hands on creative part we used F# and the SmallSharp library which has a similar feel but is limited to 2D.
SmallSharp
SmallSharp is a small .Net library for drawing graphics, similar to Small Basic but aimed more at the "Sharp" languages C# and F#
Small Basic the good parts:
- minimal IDE: you get intellisense, buttons for opening and saving files and a big run button (F5)
- simple library: type GraphicsWindow and dot to start drawing shapes, no need worry about Single Threaded Apartments, data binding or XAML
Small Basic’s library is just about usable from C# and F# but relies on strings and implicit conversions to a variant type, where as SmallSharp’s API takes explicit typed arguments.
In F# with SmallSharp we can write:
GraphicsWindow.BrushColor <- red
for i in 0..5..200 do
GraphicsWindow.DrawLine(i,0,200-i,200)
GraphicsWindow.DrawLine(0,i,200,200-i)
Which draws concentric lines:
Bubbles
I found a nice piece on Deviant Art entitled Bubbles:
The task was to generate a similar work, starting with the following code:
Win.Background <- black
let rand = System.Random()
let colors = [red; green; blue; yellow]
for i = 1 to 200 do
Win.Opacity <- rand.NextDouble() ** 3.0
Win.FillColor <- colors.[rand.Next(colors.Length)]
let x = rand.NextDouble() * Win.Width
let y = rand.NextDouble() * Win.Height
let r = 10.0 + rand.NextDouble() * 30.0
Win.DrawEllipse(x-r,y-r,r*2.0,r*2.0)
Here’s a monochrome from David Kowalski:
and an interesting Spiral effect from Rob Lyndon:
FunScript
Following Atwood's Law:
any application that can be written in JavaScript, will eventually be written in JavaScript.
I created the same effect using the HTML5 Canvas, with the F# code being compiled to JavaScript by the FunScript library, which also gives typed access to JavaScript libraries.
[<ReflectedDefinition>]
module Program
open FunScript
open FunScript.TypeScript
type ts = Api<"../Typings/lib.d.ts">
let circle (ctx:ts.CanvasRenderingContext2D) (x,y,d,c) =
let pi = ts.Math.PI
ctx.beginPath()
ctx.arc(x, y, d, 0.0, pi * 2.0)
ctx.fillStyle <- c
ctx.fill()
let inline str x = x.ToString()
let rgba (r,g,b) a = "rgba("+str r+","+str g+","+str b+","+str a+")";
let next n = ts.Math.random() * n
let from n = ts.Math.floor(next (float n)) |> int
let main() =
let canvas = unbox<ts.HTMLCanvasElement>(ts.document.getElementById("canvas"))
canvas.width <- 1000.
canvas.height <- 500.
let ctx = canvas.getContext("2d")
// Set background
ctx.fillStyle <- "rgb(0,0,0)"
ctx.fillRect (0., 0., canvas.width, canvas.height);
/// Circle colors
let colors = [
255,0,0
0,255,0
0,0,255
255,255,0
]
// Draw circles
for i = 1 to 200 do
let x = next canvas.width
let y = next canvas.height
let r = 10. + next 40.
let a = next 1.
let c = rgba (colors.[from colors.Length]) a
circle ctx (x, y, r, c)
Turing Drawings
We finished up on drawing roulette with Turing drawings, made by random Turing machines:
I created an F# version a few weeks back which you can run in the Cloud Tsunami IDE.
Have fun!