Skip to content

Instantly share code, notes, and snippets.

@JoshCheek
Created November 20, 2016 23:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JoshCheek/8f79751225ad92f4939d158bbfb1cecb to your computer and use it in GitHub Desktop.
Save JoshCheek/8f79751225ad92f4939d158bbfb1cecb to your computer and use it in GitHub Desktop.
L-Systems: Round Robin
require 'graphics'
# https://vimeo.com/192379873
class Turtle
attr_accessor :x, :y, :radians, :on_move, :stack, :rotation_multiplier
def initialize(x, y, radians, rotate, &on_move)
self.x = x
self.y = y
self.radians = radians
self.stack = []
self.on_move = on_move
self.rotation_multiplier = rotate
end
def save
stack.push [x, y, radians]
end
def restore
self.x, self.y, self.radians = stack.pop
end
def rotate(radians)
self.radians += radians*rotation_multiplier
end
def forward(n)
new_x = Math.cos(radians)*n + x
new_y = Math.sin(radians)*n + y
on_move.call(x, y, new_x, new_y, radians)
self.x = new_x
self.y = new_y
end
end
class Snowflake < Graphics::Simulation
def initialize
super 1440, 900, 24
color.default_proc = lambda { |h, k| k }
@background = rgb(0x2A, 0x21, 0x1C) # espresso libre brown
@steps = 300
@rules = {"X" => "F−[[X]+X]+F[+FX]−X", "F" => "FF"}
production = 5.times.inject("X") { |a,*| a.gsub /[#{@rules.keys.join}]/, @rules }
trunk_length = production[/F+/].length # how far before the first branch
@production = production[trunk_length/2..-1]
@turtles = [
new_turtle(w/2, h/2, 0, 0.1, rgb(0x66, 0xFF, 0xFF)),
new_turtle(w/2, h/2, 0, 0.2, rgb(0x77, 0xFF, 0xFF)),
new_turtle(w/2, h/2, 0, 0.3, rgb(0x88, 0xFF, 0xFF)),
new_turtle(w/2, h/2, 0, 0.4, rgb(0x99, 0xFF, 0xFF)),
new_turtle(w/2, h/2, 0, 0.5, rgb(0xAA, 0xFF, 0xFF)),
new_turtle(w/2, h/2, 0, 0.6, rgb(0xBB, 0xFF, 0xFF)),
new_turtle(w/2, h/2, 0, 0.7, rgb(0xCC, 0xFF, 0xFF)),
new_turtle(w/2, h/2, 0, 0.8, rgb(0xDD, 0xFF, 0xFF)),
new_turtle(w/2, h/2, 0, 0.9, rgb(0xEE, 0xFF, 0xFF)),
new_turtle(w/2, h/2, 0, 1.0, rgb(0xFF, 0xFF, 0xFF)),
]
end
def rgb(r, g, b)
screen.format.map_rgba(r, g, b, 0xFF)
end
def draw(n)
clear @background
angle = 2*Math::PI * n/@steps.to_f
@turtles.each &:save
@production.each_char do |char|
case char
when 'F' then @turtles.each { |t| t.forward 10 }
when '-' then @turtles.each { |t| t.rotate angle }
when '+' then @turtles.each { |t| t.rotate -angle }
when "[" then @turtles.each &:save
when "]" then @turtles.each &:restore
else
end
end
@turtles.each &:restore
end
def new_turtle(xstart, ystart, østart, rotation_multiplier, colour)
Turtle.new xstart, ystart, østart, rotation_multiplier do |x1,y1, x2,y2, angle|
next if x1 < 0 && x1 < 0 || x1 > w && x2 > w
next if y1 < 0 && y2 < 0 || y1 > h && y2 > h
line x1, y1, x2, y2, colour
end
end
end
Snowflake.new.run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment