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

Wednesday, 13 January 2010

A 3D Plant using L-Systems and ruby-processing

For the grammar library see my previously posted Cesàro fractal (plant grammar after Hung-Wen Chen). If you are using either Windows or Mac OS then try using opengl instead of P3D. There is an issue with linux such that you need to use fullscreen in combination with opengl, and that for me at least mucks up using the control panel.



########################################################
# A 3D plant implemented using a
# Lindenmayer System in ruby-processing by Martin Prout
########################################################

require 'plant'

class Plant_Test < Processing::App
  load_libraries :grammar, :control_panel
  attr_reader :plant, :rot_z, :rot_y, :rot_x

  def setup()
    size(800, 800, P3D)
    setup_panel
    @plant = Plant.new
    plant.create_grammar(5)
    no_stroke()
    @rot = 0
  end


  def setup_panel
    control_panel do |c|
      c.title = "Control:"
      c.slider :rot_x, 43..63, 53.81
      c.slider :rot_y, 18..38, 28.41
      c.slider :rot_z, -20..20, -0.45
      c.button :reset
    end
  end

  def reset
     @rot_x = 53.81
     @rot_y = 28.41
     @rot_z = -0.45    
  end

  def draw()
    background(0)
    ambient_light(0, 255, 0)
    directional_light(0, 255, 0, 0.0, -1.0, 0.0)
    camera(rot_x, rot_y, rot_z, # eye_x, eye_y, eye_z
      0.0, -50.0, 0.0,            # centerX, centerY, centerZ
      0.0, 1.0, 0.0)
    plant.render()
  end
end

############################
# plant.rb
###########################
class Plant
  include Processing::Proxy

  attr_reader :grammar, :axiom, :production, :premis, :rule,
  :theta, :scale_factor, :distance, :phi

  def initialize()
    @axiom = "F"
    @grammar = Grammar.new(axiom)
    @production = axiom
    @premis = "F"
    @rule = "F[&+F]F[->F][->F][&F]"
    @scale_factor = 0.8
    @distance = 3
    @theta = Math::PI/180 * 28
    @phi = Math::PI/180 * 28
    grammar.add_rule(premis, rule)
    no_stroke()
  end

  def render()
    production.each_char do |ch|
      case(ch)
      when "F"    
        fill(0, 200, 0)
        translate(0, distance/-2, 0)
        box(distance/4 , distance, distance/4)
        translate(0, distance/-2, 0)
      when "-"
        rotateX(-theta)
      when "+"
        rotateX(theta)
      when "&"
        rotateY(-phi%(Math::PI*2))
      when ">"
        rotateZ(phi%(Math::PI*2))
      when "<"
        rotateZ(-phi)
      when "["
        push_matrix
        @distance = distance * scale_factor
      when "]"
        pop_matrix
        @distance = distance / scale_factor
      else
        puts("character '#{ch}' not in grammar")
      end
    end
  end
  ##############################
  # create grammar from axiom and
  # rules (adjust scale)
  ##############################

  def create_grammar(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