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

Wednesday 6 January 2010

Adding some controls to Sierpinski sketch


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

class Sierpinski_Test < Processing::App
  load_libraries :grammar, :control_panel

  attr_reader :sierpinski, :fine, :coarse, :generation, :scale_factor, :xpos, :ypos

  def setup
    setup_panel
    size(1000, 1000)    
    redraw_fractal
  end
  
  def setup_panel
    control_panel do |c|
      c.title = "Controller:"
      c.slider :fine, 0.00..3.00, 0.00
      c.slider :coarse, 0.00..3.00, 0.00
      c.slider :generation, 5..8, 6
      c.slider :scale_factor, 1..4, 1
      c.slider :xpos, 0..1000, 100
      c.slider :ypos, 0..1000, 700
      c.button :redraw_fractal
    end
  end

  def redraw_fractal
    @sierpinski = Sierpinski.new(xpos, ypos)
    sierpinski.gamma = fine/150 + coarse/15
    sierpinski.factor = scale_factor  
    sierpinski.create_grammar(generation.to_int)
  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, :gamma, :factor
  attr_reader :xpos, :ypos
  DELTA = (Math::PI/180) * 60.0  
  
  def initialize(xpos, ypos)
    @xpos = xpos
    @ypos = ypos
    @axiom = "A"
    @grammar = Grammar.new axiom
    grammar.add_rule "A", "B+A+B"        
    grammar.add_rule "B", "A-B-A"
    @start_length = 400
    @factor = 1 
    stroke 255
    @production = axiom
    @draw_length = start_length
    @gamma = 0

  end

  def render                       # NB using affine transforms here
    translate(xpos, ypos)
    scale(factor)
    production.each_char do |element|
      case element
      when 'B', 'A'                    
        line(0, 0, draw_length, 0)
        translate(draw_length, 0)
      when '+'
        rotate(DELTA)
      when '-'        
        rotate(-(DELTA+gamma))
      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
end  


Click on image to see full size, I have since added a coarse slider (and renamed delta as fine). The fine range here is fairly conservative, you should try that first. Before trying the coarse or use both controls in combination, to get some pretty funky fractals... 
NB requires my custom grammar library see Cesàro fractal in a previous post for code.




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