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

Friday, 29 January 2010

3D Hilbert Using LSystems and ruby-processing

Here is a 3D Hilbert in ruby-processing, you can see the basic shape if you set the number of repeats to 1. For me the best look was 3 iterations (starts to look a bit fuzzy with 4 repeats).
I used this application to test my grammar (and lsystem vanilla processing) library on 32 bit Windows (XP). Which worked OK for me, because linux has a bit of an issue about OPENGL with ruby-processing unless fullscreen (vanilla processing works s fine) I have used P3D here.
I'm sure it could work a bit better using opengl. It would be cool to use my vanilla library with ruby-processing but I can't find an interface for the java char in ruby....


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

require 'hilbert'

class Hilbert_Test < Processing::App
  load_libraries :grammar, :control_panel
  attr_reader :hilbert, :y, :x
  attr_accessor :x_view, :y_view, :zoom, :repeat
  def setup()
    size(500, 500, P3D)
    setup_panel
    @x_view = 400.0;
    @y_view = 0.0;
    @zoom = 9.0;
    @hilbert = Hilbert.new
    hilbert.create_grammar(3)
    no_stroke()
    camera(x_view, y_view, zoom, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)
    translate(width / 2, height / 2)
  end

 def setup_panel
   control_panel do |c|
     c.title = "Control:"
     c.menu(:repeat, ['1', '2', '3', '4'], '3') {|m| load_menu_item(m) }
     c.slider(:zoom, -100..400, zoom)
     c.slider(:x_view, 300..700, x_view)
     c.slider(:y_view, -400..400, y_view)
     c.button :reset!
   end
 end

 def reset!
   x_view = 0.0
   y_view = 0.0
   zoom = 5
   @hilbert = Hilbert.new
   hilbert.create_grammar(repeat.to_i)
 end

 def load_menu_item(item)
   repeat = item
 end


  def draw()
    background(0)
    hilbert.render()
    ambient_light(0, 255, 0)
    directional_light(0, 255, 0, 0.0, -1.0, 0.0)
    camera(x_view, y_view, zoom, # eyeX, eyeY, eyeZ
  0.0, 0.0, 0.0,           # centerX, centerY, centerZ
  0.0, 1.0, 0.0)
  end
end

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

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

  def initialize()
    @axiom = "X"
    @grammar = Grammar.new(axiom)
    @production = axiom
    @premis = "X"
    @rule = "^<XF^<XFX-F^>>XFX&F+>>XFX-F>X->"
    @distance = 160
    @theta = Math::PI/180 * 90
    @phi = Math::PI/180 * 90
    grammar.add_rule(premis, rule)
    no_stroke()
  end

  def render()
    production.scan(/./) do |ch|
      case(ch)
      when "F"  
        fill(0, 200, 0)
        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