Experiments with ruby-processing (processing-2.2.1) and JRubyArt for processing-3.0

Friday, 27 November 2009

Sierpinski Fractal Implemented in ruby-processing using an L-System

Revised as of 17 January 2010 uses a custom grammar library (see Cesàro fractal in a later post)


##
# A Sierpinski Triangle implemented using a
# Lindenmayer System in ruby-processing by Martin Prout
###
require 'sierpinski'

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 
  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"
    @grammar = Grammar.new axiom
    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.scan(/./).each do |element|
      case element
      when 'F'                    
        turtle = draw_line(turtle, draw_length)
      when '+'
        turtle[ANGLE] += DELTA   # rotate by + theta if going the affine transform route
      when '-'
        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  



No comments:

Post a Comment

Followers

Blog Archive

About Me

My photo
I have developed JRubyArt and propane new versions of ruby-processing for JRuby-9.1.5.0 and processing-3.2.2