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

Saturday 16 January 2010

Islands in ruby processing using my grammar library

See Cesàro fractal for grammar.rb library

require 'island'

class Test_Island < Processing::App
  load_libraries "grammar"

  attr_reader :island

  def setup
    size 500, 500
    stroke 255
    smooth
    @island = Island.new
    island.create_grammar 2
    no_loop  
  end

  def draw
    background 0
    island.render  
  end
end

######################################################
# island.rb
######################################################
class Island
  include Processing::Proxy

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

  def initialize
    @axiom = "F-F-F-F"
    @grammar = Grammar.new axiom
    grammar.add_rule("F", "F+f-FF+F+FF+Ff+FF-f+FF-F-FF-Ff-FFF")
    grammar.add_rule("f", "ffffff")
    @start_length = 1200.0
    @theta = 0
    @xpos = width/4
    @ypos = height*0.8
    @production = axiom
    @draw_length = start_length
  end

  ##############################################################################
  # Not strictly in the spirit of either processing in my render
  # function I have ignored the processing translate/rotate functions in favour
  # of the direct calculation of the new x and y positions, thus avoiding such
  # affine transformations.
  ##############################################################################

  def render()
    turtle = [xpos, ypos, theta]                # simple array for turtle
    production.scan(/./).each do |element|
      case element
      when 'F'
        turtle = draw_line(turtle, draw_length)
      when 'f'
        turtle = forward(turtle, draw_length/2)
      when '+'
        turtle[ANGLE] += DELTA
      when '-'
        turtle[ANGLE] -= DELTA
      else puts "Character '#{element}' not in grammar"
      end
    end
  end

  ##############################
  # create grammar from axiom and
  # rules (adjust scale)
  ##############################

  def create_grammar(gen)
    @draw_length *= 0.08**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

  def forward(turtle, length)
    new_xpos = turtle[XPOS] + length * Math.cos(turtle[ANGLE])
    new_ypos = turtle[YPOS] + length * Math.sin(turtle[ANGLE])
    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