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

Monday 4 January 2010

An interactive l-system sketch using the Control Panel

Requires my grammar library see Cesàro fractal, cycles through 2, 3 and 4 generation versions using the control panel selector (and redraw button).

#####################
#  pentagonal_test.rb
#  by Martin Prout
#####################
require 'pentagonal'

class Pentagonal_Test < Processing::App
  load_library :control_panel
  load_library :grammar
  
  attr_reader :pentagonal, :repeat
  
  def setup
    size 600, 600
    setup_panel    
    @pentagonal = Pentagonal.new
    pentagonal.create_grammar(2)
  end
  
  def setup_panel
    control_panel do |c|
      c.title = "Control:"
      c.menu(:generation, ['2', '3', '4', '5'], '2') {|m| load_menu_item(m) }
      c.button(:redraw)
    end
  end
  
  def draw
    background(0)
    stroke(255)
    pentagonal.render
  end
  
  def redraw
    @pentagonal = Pentagonal.new
    pentagonal.create_grammar(repeat)
  end
  
  def load_menu_item(item)
    @repeat = item.to_i
  end
end


############################
# pentagonal.rb
# Pentagonal Fractal
###########################

class Pentagonal
  include Processing::Proxy

  SCALE = 0.44  
  DELTA = (Math::PI/180) * 36.0  # convert degrees to radians
  XPOS = 0     # placeholders for turtle array
  YPOS = 1
  ANGLE = 2 
  attr_accessor :axiom, :grammar, :start_length, :theta, :production, :draw_length, :xpos, :ypos

  def initialize
    setup_grammar
    @start_length = 100
    @theta = 0.0
    @xpos = width*0.5
    @ypos = height*0.7    
    @draw_length = start_length
  end
  
  def setup_grammar
    @axiom = "F--F--F--F--F"
    @grammar = Grammar.new axiom
    grammar.add_rule "F", "F+F+F-F-F-F+F+F+"   # replace F with this string see iterate function
    @production = axiom
  end

  def render
    turtle = [xpos, ypos, 0.0]    # simple array act as turtle
    production.scan(/./).each do |element|
      case element
      when 'F'                     # NB NOT using affine transforms
        turtle = draw_line(turtle, draw_length)
      when '+'
        turtle[ANGLE] += DELTA  
      when '-'
        turtle[ANGLE] -= DELTA      
      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 *= SCALE**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