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

Saturday 30 January 2010

Using the PeasyCam library in ruby-processing

Here is good example of how nice it is to have libraries, the PeasyCam library makes configuring the camera a cinch (it also works pretty smoothly). The lsystem grammar library means you can forget about how the production string is generated. What was the question?


########################################################
# A 3D Hilbert fractal implemented using a
# Lindenmayer System in ruby-processing by Martin Prout
# Best if you've got opengl
########################################################

require 'hilbert'

class Hilbert_Test < Processing::App
  full_screen # NB: All distances are relative to screen height
  load_libraries 'grammar', 'PeasyCam', 'opengl'
  import 'peasy' 
  import "processing.opengl" if library_loaded? "opengl"  
  attr_reader :hilbert, :cam
  def setup()
    library_loaded?(:opengl) ? configure_opengl : render_mode(P3D)
    configure_peasycam
    @hilbert = Hilbert.new(height)
    hilbert.create_grammar(3)
    no_stroke()
  end
  
  def configure_peasycam
    cam = PeasyCam.new(self, height/10)  
    cam.set_minimum_distance(height/10)
    cam.set_maximum_distance(height/2)
  end
  
  def configure_opengl
    render_mode OPENGL
    hint ENABLE_OPENGL_4X_SMOOTH     # optional
    hint DISABLE_OPENGL_ERROR_REPORT # optional
  end

  def draw()
    background(0)
    lights()
    hilbert.render()
  end
end

############################
# hilbert.rb
###########################
class Hilbert
  include Processing::Proxy

  attr_reader :grammar, :axiom, :production, :premis, :rule,
  :theta, :scale_factor, :distance, :phi, :len
  
  def initialize(len)
    @axiom = "X"
    @grammar = Grammar.new(axiom)
    @production = axiom
    @premis = "X"
    @rule = "^<XF^<XFX-F^>>XFX&F+>>XFX-F>X->"
    @len = len
    @distance = len/12      # distance value relative to screen height
    @theta = Math::PI/180 * 90
    @phi = Math::PI/180 * 90
    grammar.add_rule(premis, rule)
    no_stroke()
  end

  def render()
    translate(-len/42, len/42, -len/42)  # use the "answer?" to center the Hilbert
    fill(0, 75, 152)
    light_specular(204, 204, 204)
    specular(255, 255, 255)
    shininess(1.0)
    production.scan(/./) do |ch
      case(ch)
      when "F"    
        translate(0, distance/-2, 0)
        box(distance/9 , distance, distance/9)
        translate(0, distance/-2, 0)
      when "+"
        rotateX(-theta)
      when "-"
        rotateX(theta)
      when ">"
        rotateY(theta)
      when "<"
        rotateY(-theta)
      when "&"
        rotateZ(-phi)
      when "^"
        rotateZ(phi)
      when "X"
      else
        puts("character '#{ch}' not in grammar")
      end
    end
  end
  ##############################
  # create grammar from axiom and
  # rules (adjust scale)
  ##############################
  
  def create_grammar(gen)
    @distance *= 0.5**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