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

Saturday 28 November 2009

Minkowski island using L-System in ruby processing

Revised as of 28 December 2009 to use a custom grammar library (see Cesàro fractal in a later post)

#################################################
# minkowski_test.rb
#
# A Minkowski island implemented using a
# Lindenmayer System in ruby-processing by Martin Prout
#################################################
require 'minkowski'
require 'grammar'

class Minkowski_Test < Processing::App
  attr_reader :minkowski

  def setup
    size 800, 800
    @minkowski = Minkowski.new
    minkowski.create_grammar 4
    no_loop
  end

  def draw
    background 0
    minkowski.render
  end
end

#############################
# Minkowski Fractal
#
# minkowski.rb
###########################


class Minkowski
  include Processing::Proxy
  require 'grammar'
  DELTA = (Math::PI/180) * 90.0  # L-System angle increment constant, in radians
  attr_accessor :axiom, :grammar, :start_length, :theta, :production, :draw_length, :xpos, :ypos

  def initialize
    @axiom = 'F+F+F+F'              # just one F for a Minkowski sausage
    @grammar = Grammar.new axiom
    grammar.add_rule 'F', 'F-F+F+FF-F-F+F'        # replace F with this string, see iterate function
    @start_length = 400
    @theta = (Math::PI/180) * 30.0  # initialize angle variable
    @xpos = width * 0.6             # starting x position
    @ypos = height/6                # starting y position
    stroke 0, 255, 0
    stroke_weight 2
    @draw_length = start_length
    @production = axiom
  end

  def next_x
    @xpos -= draw_length * Math.cos(theta)
  end

  # a helper function that sets and returns next position x coordinate
  # you could use affine transforms instead but this avoids that overhead
  def next_y
    @ypos += draw_length * Math.sin(theta)  
  end

  def render
    production.each_char do |element|
      case element
      when 'F'              # draw element and move forward                  
        line(xpos, ypos, next_x, next_y)
      when '+'
        @theta += DELTA          
      when '-'
        @theta -= DELTA          
      else puts "Grammar not recognized"
      end
    end
  end

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

  def create_grammar(gen = 1)
    @draw_length *=  0.25**gen
    @production = @grammar.generate gen
  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