Here is another LSystem example using the control panel to set the number of 'generations' of the fractal. This sketch requires my grammar library see the Cesàro fractal.
##############################################
# fern_test.rb inspired by processing fern by Gareth Spor
##############################################
require 'fern'
class FernTest < Processing::App
load_libraries :control_panel, :grammar
attr_accessor :init_color, :fern, :repeat
def setup()
size(800, 800)
setup_panel
@init_color = color(0, 240, 0)
redraw
end
def draw()
background(0)
fern.render(250.0, 650.0, 0.0, 100.0, init_color)
end
def setup_panel
control_panel do |c|
c.title = "Control:"
c.menu(:repeat, ['10', '12', '16', '20'], '12') {|m| load_menu_item(m) }
c.button(:redraw)
end
end
def redraw
@fern = Fern.new()
@production = fern.create_grammar(repeat.to_i)
end
def load_menu_item(item)
repeat = item
end
end
######################
# fern.rb
######################
class Fern
include Processing::Proxy
XPOS = 0 # place holders for pen array
YPOS = 1
THETA = 2
LENGTH = 3
HUE = 4
DELTA = Math::PI/180 * 35.2 # NB: 36 is boring
attr_accessor :pen, :production, :grammar, :axiom
def initialize
@axiom = "FD"
@grammar = Grammar.new(axiom)
grammar.add_rule("D", "C+@FD")
grammar.add_rule("C", "B")
grammar.add_rule("B", "[7+#FD][7-#FD]") # abbreviated lsystem grammar
@production = axiom
@pen = Array.new(5) # use a simple array for pen (for efficiency)
end
def render(x, y, theta, len, col)
pen[XPOS] = x
pen[YPOS] = y
pen[THETA] = -Math::PI/2
pen[LENGTH] = len
pen[HUE] = col
repeats = 1
stack = Array.new # use a locally defined array as the pen stack
@production.each_char do |element|
case(element)
when "F" # move forward
@pen = draw_line(pen)
when "+" #turn right
pen[THETA] += (2 * Math::PI) % (repeats * DELTA)
repeats = 1
when '-' #turn left
pen[THETA] -= (2 * Math::PI) % (repeats * DELTA)
repeats = 1
when "#" #resize line length & darken color
pen[LENGTH] *= 0.33
pen[HUE] = decrement_color(20)
when "@" #resize line length & darken color
pen[LENGTH] *= 0.9
pen[HUE] = decrement_color(10)
when "[" #push state
stack.push(@pen.dup)
when "]" #pop state
@pen = stack.pop()
when "7"
repeats = Integer(element)
when "B" # do nothing except confirm character in grammar
when "C" # do nothing except confirm character in grammar
when "D" # do nothing except confirm character in grammar
else
puts("character '#{element}' not in grammar")
end
end
end
def draw_line(pen)
temp = pen.clone
temp[XPOS] += temp[LENGTH] * Math.cos(temp[THETA])
temp[YPOS] += temp[LENGTH] * Math.sin(temp[THETA])
stroke_weight(2)
stroke(temp[HUE])
line(pen[XPOS], pen[YPOS], temp[XPOS], temp[YPOS])
return temp
end
def decrement_color(hue_step)
gree = green(pen[HUE]) - hue_step
color(0, gree, 0)
end
def create_grammar(gen)
@production = grammar.generate(gen)
end
end
No comments:
Post a Comment