Created
November 20, 2016 23:13
-
-
Save JoshCheek/8f79751225ad92f4939d158bbfb1cecb to your computer and use it in GitHub Desktop.
L-Systems: Round Robin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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