Here I map characters of the LSystem grammar to human readable symbols. This I do by creating a hash. I then convert axiom strings to an array of symbols. The grammar is then "produced" as an array of symbols. The renderer the interprets the production as an array of symbols (it might use less memory than non-symbolic version but is it any faster???). I don't seem to be able use collect, so I need to create a new array of symbols when generating the grammar.
##
# A Sierpinski Triangle implemented using a
# Lindenmayer System in ruby-processing by Martin Prout
###
require 'symbol'
class Sierpinski_Test < Processing::App
load_library :grammar
attr_reader :sierpinski
def setup
size 610, 600
@sierpinski = Sierpinski.new
sierpinski.create_grammar(8)
no_loop
end
def draw
background 0
sierpinski.render
end
end
############################
# sierpinski.rb
###########################
class Sierpinski
include Processing::Proxy
attr_accessor :axiom, :grammar, :start_length, :production, :draw_length, :xpos, :ypos, :symbol_map
XPOS = 0
YPOS = 1
ANGLE = 2
DELTA = (Math::PI/180) * 120 # convert degrees to radians
def initialize
@start_length = 300
setup_grammar
@xpos = width/60
@ypos = height*0.9
stroke 255
@draw_length = start_length
end
def setup_grammar
@axiom = "FX"
@symbol_map = {"X" => :X, "+" => :PLUS, "-" => :MINUS, "F" => :FORWARD}
@grammar = Grammar.new(axiom, symbol_map)
grammar.add_rule "F", "FF" # replace F rule see grammar library
grammar.add_rule "X", "-FXF+FXF+FXF-" # replace X rule see grammar library
@production = axiom
end
def render # NB not using affine transforms here
turtle = [xpos, ypos, 0.0]
production.each do |element|
case element
when :FORWARD
turtle = draw_line(turtle, draw_length)
when :PLUS
turtle[ANGLE] += DELTA # rotate by + theta if going the affine transform route
when :MINUS
turtle[ANGLE] -= DELTA # rotate by - theta if going the affine transform route
when :X # do nothing except recognize :X as a word in the L-system grammar
else
puts "Character '#{element}' is not in grammar"
end
end
end
##############################
# create grammar from axiom and
# rules (adjust scale)
##############################
def create_grammar(gen)
@draw_length *= 0.5**gen
@production = grammar.generate gen
end
private
######################################################
# draws line using current turtle and length parameters
# returns a turtle corresponding to the new position
######################################################
def draw_line(turtle, length)
new_xpos = turtle[XPOS] + length * Math.cos(turtle[ANGLE])
new_ypos = turtle[YPOS] + length * Math.sin(turtle[ANGLE])
line(turtle[XPOS], turtle[YPOS], new_xpos, new_ypos)
turtle = [new_xpos, new_ypos, turtle[ANGLE]]
end
end
############################
# grammar.rb
# Non-stochastic symbolic grammar
# with unique premise/rules
############################
class Grammar
attr_accessor :axiom, :rules, :symbol_map
def initialize(axiom, symbol_map)
@symbol_map = symbol_map
@axiom = string_to_symbol_array(axiom)
@rules = Hash.new
end
def string_to_symbol_array(a_string)
sym_array = []
a_string.scan(/./).each do |ch|
sym_array.push(symbol_map[ch])
end
return sym_array
end
def add_rule premise, rule
skey = symbol_map[premise]
svalue = string_to_symbol_array(rule)
rules.store(skey, svalue)
end
##########################################
# control the number of iterations
# default 0, returns the axiom
##########################################
def generate repeat = 0
prod = axiom
repeat.times do
prod = new_production(prod)
end
return prod
end
##########################################
# replace each pre symbol with un-splatted symbol array
# from rules lookup
##########################################
def new_production production
prod = []
production.each do |c|
(r = rules[c]) ? prod.push(*r) : prod.push(c)
end
return prod
end
end
Experiments with ruby-processing (processing-2.2.1) and JRubyArt for processing-3.0
Monday, 18 January 2010
Subscribe to:
Post Comments (Atom)
Followers
Blog Archive
-
▼
2010
(73)
-
▼
January
(14)
- Hello Peasy in ruby processing (a simple PeasyCam ...
- Using the PeasyCam library in ruby-processing
- 3D Hilbert Using LSystems and ruby-processing
- Two dimensional Hilbert fractal with LSystems and ...
- Fern Fractal Using LSystems (includes a subtle col...
- Using a symbolic grammar for LSystems ruby-processing
- Islands in ruby processing using my grammar library
- Refactoring my Penrose Snowflake
- A 3D Plant using L-Systems and ruby-processing
- Another control panel example with odd turtle turns
- Adding some controls to Sierpinski sketch
- A Sierpinski Variant using L-Systems and ruby proc...
- An interactive l-system sketch using the Control P...
- Checking the probabilities
-
▼
January
(14)
About Me
- monkstone
- I have developed JRubyArt and propane new versions of ruby-processing for JRuby-9.1.5.0 and processing-3.2.2
No comments:
Post a Comment