Skip to content
Martin Prout edited this page Oct 19, 2015 · 15 revisions

Like ruby-processing, there is a load_library utility, that can be used to load processing libraries or pure ruby libraries (or a mixture thereof when java libraries are called by the ruby library). Libraries need to have unique names and are called in this order:-

  1. local ruby library library/grammar.rb called using load_library :grammar

  2. local java library library/video/{jars} one or more jars including those in lib sub-folder called using load_library :video

  3. processing installed java library {libraries}/library/video/{jars} one or more jars including those in lib sub-folder. This can be configured in `~/.jruby_art/config.yml to point to wherever vanilla processing libraries are stored.

# YAML configuration file for ruby-processing
# K9_HOME: "/home/ruby193 ... /ruby-processing" #windows users may need to set this
---
PROCESSING_ROOT: /home/tux/processing-3.0 
sketchbook_path: /home/tux/sketchbook/

Usage

Using video and video_event libraries, the video_event allows use of java reflection method captureEvent

load_libraries :video, :video_event

include_package 'processing.video'

attr_reader :cam

def setup
  sketch_title 'Test Capture'
  cameras = Capture.list
  fail 'There are no cameras available for capture.' if (cameras.length == 0)
  p 'Matching cameras available:'
  size_pattern = Regexp.new(format('%dx%d', width, height))
  select = cameras.grep size_pattern # filter available cameras
  select.uniq.map { |cam| p cam.strip }
  fail 'There are no matching cameras.' if (select.length == 0)
  start_capture(select[0])
end

def start_capture(cam_string)
  # The camera can be initialized directly using an
  # element from the array returned by list:
  @cam = Capture.new(self, cam_string)
  p format('Using camera %s', cam_string)
  cam.start
end

def draw
  image(cam, 0, 0)
  # The following does the same, and is faster when just drawing the image
  # without any additional resizing, transformations, or tint.
  # set(0, 0, cam)
end

def captureEvent(c)
  c.read
end

def settings
  size 960, 544, P2D
end

A custom ruby library 'library/grammar.rb' example

########################################################
# NB: To be edited refers old arch
########################################################
########################################################
# Chequer implemented using a grammar library
# Lindenmayer System in ruby-processing by Martin Prout
########################################################
load_library :grammar

attr_reader :chequer

def setup
  sketch_title 'Chequer'
  @chequer = Chequer.new width * 0.9, height / 10
  chequer.create_grammar 4
  no_loop
end

def draw
  background 0
  chequer.render
end

def settings
  size 600, 600
end

# Chequer class
class Chequer
  include Processing::Proxy
  attr_accessor :axiom, :grammar, :production, :draw_length, :theta, :xpos, :ypos
  DELTA = Math::PI / 2

  def initialize(xpos, ypos)
    @xpos = xpos
    @ypos = ypos
    @axiom = 'F-F-F-F'        # Axiom
    @grammar = Grammar.new(axiom, 'F' => 'FF-F-F-F-FF')
    @draw_length = 500
    stroke 0, 255, 0
    stroke_weight 2
    @theta = 0
  end

  def render
    production.each do |element|
      case element
      when 'F'
        x_temp = xpos
        y_temp = ypos
        @xpos -= draw_length * cos(theta)
        @ypos -= draw_length * sin(theta)
        line(x_temp, y_temp, xpos, ypos)
      when '+'
        @theta += DELTA
      when '-'
        @theta -= DELTA
      else
        puts format("Character '%s' is not in grammar", element)
      end
    end
  end

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

  def create_grammar(gen)
    @draw_length /= 3**gen
    @production = @grammar.generate gen
  end
end

Here is the library grammar.rb

############################
# Simple lsystem grammar
############################
class Grammar
  attr_reader :axiom, :rules
  def initialize(axiom, rules)
    @axiom = axiom
    @rules = rules
  end

  def expand(production, iterations, &block)
    production.each_char do |token|
      if rules.key?(token) && iterations > 0
        expand(rules[token], iterations - 1, &block)
      else
        yield token
      end
    end
  end

  def each(gen)
    expand(axiom, gen) { |token| yield token }
  end

  def generate(gen)
    [].tap do |output|
      each(gen) { |token| output << token }
    end
  end
end