Experiments with ruby-processing (processing-2.2.1) and JRubyArt for processing-3.0
Thursday, 10 December 2009
Stochastic Plant rules Lindenmayer Systems in ruby processing
#######################################################
# stochastic_test.rb
#
# Lindenmayer System in ruby-processing by Martin Prout
# Exploring terminals with minimum logic
########################################################
require 'stochastic_plant'
class Stochastic_Test < Processing::App
attr_reader :stochastic, :stochastic1, :stochastic2
def setup
size 1000, 800
@stochastic = StochasticPlant.new 200, 700
@stochastic1 = StochasticPlant.new 500, 700
@stochastic2 = StochasticPlant.new 700, 700
stochastic.create_grammar 5
stochastic1.create_grammar 4 # simpler plant
stochastic2.create_grammar 5
no_loop
end
def draw
background 0
stroke(0, 255, 0)
stroke_width(3)
stochastic.render
stochastic1.render
stochastic2.render
end
end
############################
# stochastic_plant.rb
# includes option for no pen
# move forward, unused here
###########################
require 'stochastic_grammar'
class StochasticPlant
include Processing::Proxy
attr_reader :grammar, :axiom, :draw_length, :theta, :xpos, :ypos, :production, :pen_down
XPOS = 0 # placeholders for turtle array
YPOS = 1
ANGLE = 2
DELTA = PI/8
def initialize xpos_, ypos_
@draw_length = 350
@xpos = xpos_
@ypos = ypos_
@theta = PI/2 # this way is up?
setup_grammar
end
def setup_grammar
@axiom = "F"
@grammar = StochasticGrammar.new(axiom)
grammar.add_rule("F", "F[+F]F[-F]F", 0.1)
grammar.add_rule("F", "F[+F]F", 0.45)
grammar.add_rule("F", "F[-F]F", 0.45)
@production = axiom
@pen_down = false
end
def render
stack = Array.new # ruby array as the turtle stack
turtle = [xpos, ypos, theta] # ruby array as a turtle
production.scan(/./).each do |element|
case element
when 'F' # NB NOT using affine transforms
@pen_down = true
turtle = draw_line(turtle, draw_length)
when '+'
turtle[ANGLE] += DELTA
when '-'
turtle[ANGLE] -= DELTA
when '['
stack.push(turtle.dup) # push a copy of the current turtle to stack
when ']'
turtle = stack.pop # assign current turtle to an instance popped from the stack
else
puts "Character '#{element}' is not in grammar"
end
end
end
def create_grammar gen
@draw_length *= 0.5**gen
@production = grammar.generate gen
end
private
######################################################
# draws a line using current turtle and length parameters
# unless pen_down = false (then only move forward)
# 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) if pen_down
@pen_down = false
turtle = [new_xpos, new_ypos, turtle[ANGLE]]
end
end
########################
# stochastic_grammar.rb
# unweighted rules accepted
# with default weight = 1
# complex stochastic rule
########################
class StochasticGrammar
PROB = 1
attr_accessor :axiom, :srules
def initialize axiom
@axiom = axiom
@srules = Hash.new # rules dictionary (a hash of hashes)
end
######################################################
# randomly selects a rule (with a weighted probability)
#####################################################
def stochastic_rule(rules)
total = rules.inject(0) do |total, rule_and_weight|
total += rule_and_weight[PROB]
end
srand
chance = rand * total
rules.each do |rule, weight|
return item unless chance > weight
chance -= weight
end
return rule
end
def has_rule?(pre)
@srules.has_key?(pre)
end
def add_rule(pre, rule, weight = 1) # default weighting 1 (can handle non-stochastic rules)
if (has_rule?(pre)) then # add to existing hash
srules[pre].store rule, weight
else
temp = Hash.new # create a new hash for rule/weights
temp.store rule, weight # add to new hash
srules.store pre, temp # store new hash with pre key
end
end
def new_production(prod)
prod.gsub!(/./) do |ch|
(has_rule?(ch)) ? stochastic_rule(srules[ch]) : ch
end
end
def generate(repeat = 0)
prod = axiom
repeat.times do
prod = new_production(prod)
end
return prod
end
end
Labels:
ruby-processing,
stochastic l-system rules
Subscribe to:
Post Comments (Atom)
Followers
Blog Archive
-
▼
2009
(50)
-
▼
December
(8)
- Peano curve fractal using Lindenmayer Systems
- 3D Lindenmayer Systems using the anar+ library wit...
- Another Example of Using Anar+ lib in ruby-processing
- Using the Anar+ library in ruby-processing
- Stochastic Plant rules Lindenmayer Systems in ruby...
- A square edge fractal with L-System and ruby-proce...
- Seasonal sketch, adding terminals to L-System plant
- A Cesàro (or torn square) fractal in ruby processi...
-
▼
December
(8)
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
how to running this module in open processing? i have insert ruby processing plugin and i use windows 7
ReplyDeleteHave you installed ruby-processing from? https://github.com/jashkenas/ruby-processing/wiki
ReplyDeleteon mac/linux it is simples as:-
sudo gem install ruby-processing
Then on command line type:-
rp5 run stochastic_test.rb
I've written a commando file so you can do this from jEdit (so you don't need a console)
http://community.jedit.org/?q=filestore/browse/20