#!/usr/bin/ruby
# Code from a lesson by Keith Peters.
# See: https://www.youtube.com/watch?v=geqq63WFLr0
require('Imager')
var (width, height) = (800, 800)
var img = %O<Imager>.new(xsize => width, ysize => height)
struct Rule {
a, b, c, d, tx, ty, w
}
var rules = [
Rule(
a: 0.05,
b: 0,
c: 0,
d: 0.6,
tx: 0,
ty: 0,
w: 0.17,
),
Rule(
a: 0.05,
b: 0,
c: 0,
d: -0.5,
tx: 0,
ty: 1,
w: 0.17,
),
Rule(
a: 0.46,
b: -0.321,
c: 0.386,
d: 0.383,
tx: 0,
ty: 0.6,
w: 0.17,
),
Rule(
a: 0.47,
b: -0.154,
c: 0.171,
d: 0.423,
tx: 0,
ty: 1.1,
w: 0.17,
),
Rule(
a: 0.433,
b: 0.275,
c: -0.25,
d: 0.476,
tx: 0,
ty: 1,
w: 0.16,
),
Rule(
a: 0.421,
b: 0.257,
c: -0.353,
d: 0.306,
tx: 0,
ty: 0.7,
w: 0.16,
),
]
func plot(x, y) {
static green = %O<Imager::Color>.new('#00ff00')
img.setpixel(
x => width/2 + Math.map(10*x, 0, 10, 0, width/2),
y => height - Math.map(10*y, 0, 10, 0, height/2),
color => green
)
}
func getRule {
var r = 1.rand
for rule in (rules) {
if (r < rule.w) {
return rule
}
r -= rule.w
}
}
var (x, y) = 2.of { 1.rand }...
var iterate = {
var rule = getRule()
var x1 = (x*rule.a + y*rule.b + rule.tx)
var y1 = (x*rule.c + y*rule.d + rule.ty)
x = x1
y = y1
plot(x, y)
}
iterate * 5000
img.write(file => 'tree.png')