Ruby Processing

Here is my blog in which I will describe my experiments with ruby-processing, find out more about ruby-processing at:- compatible with processing-2.2.1 and for my version of the cfdg DSL (context-free-art)

Saturday, 19 July 2014

Ruby-processing at version 2.5.0 on github

Can't wait to try it out? The latest version of ruby-processing is now available at github. It is a bit trickier to build than previous versions and requires an installed jruby, ruby-compiler (gem) see instructions here. Actually the build is really easy just do "rake" and you are done (but you need to set your procssing root and you might not have ruby-compiler installed?). The compiled jruby extensions offer an interesting way in which to extend ruby-processing to use java libraries (not necessarily restricted to processing libraries), but especially with libraries that rely on reflection in their interface. The best exemplar of this the ArcBall utility, that uses reflection under the hood (to register pre()) so we can implement ArcBall functionality in a ruby processing sketch in one line (updates are sent to sketch via pre()). Obvious candidates for such an approach is java JBox2D, so would not have to rely on Dan Schiffmans PBox2D (now Box2DProcessing) or Ricard Marxers fisica, which could build on ruby-processings Vec2D.

ArcBall sketch code:-
# 1. drag mouse to rotate arcball
# 2. hold down x, y, or z to constrain arcball rotation to that axis

load_library :vecmath

# initialize arcball in setup and you are done...........

  # either provide arc ball center (sketch is translated to center)

  ArcBall.init(self, width/2.0, height/2.0)

  # or alternative form, where camera is set to point at center


DegLut sketch code:-

# DegLut.sin() and DegLut.cos() values

load_library :fastmath
# draw minute markers for analogue clock
  (0..360).step(6) do |a|
    x = 100 + DegLut.cos(a) * 72
    y = 100 + DegLut.sin(a) * 72
    point x, y

A complete example showing how to initialize AppRender, and use it to allow Vec2D to be written (by sketch authors) directly as PApplet vertices
# Morph. 
# Changing one shape into another by interpolating
# vertices from one to another
load_library :vecmath

attr_reader :circle, :square, :morph, :state, :v1, :v2, :renderer

ALPHA = Math::PI / 4.0
THETA = Math::PI / 20.0

def setup
  size(640, 360)
  @circle = []
  @square = []
  @morph = []
  @state = false
  @renderer =
  # Create a circle using vectors pointing from center
  (ALPHA .. OMEGA).step(THETA) do |angle|
    # Note we are not starting from 0 in order to match the
    # path of a circle.  
    circle << Vec2D.from_angle(angle) * 100
    # Let's fill out morph Array with blank Vec2Ds while we are at it
    morph <<

  # A square is a bunch of vertices along straight lines
  # Top of square
  (-50 .. 50).step(10) do |x|
    square <<, -50)
  # Right side
  (-50 .. 50).step(10) do |y|
    square <<, y)
  # Bottom, NB: can't negative step ruby so use your loaf
  5.downto(-5) do |x|
    square << * 10, 50)
  # Left side
  5.downto(-5) do |y|
    square <<, y * 10)

def draw

  # We will keep how far the vertices are from their target
  @total_distance = 0

  # Look at each vertex
  circle.length.times do |i|
    # Are we lerping to the circle or square?
    v1 = (state)?  circle[i] : square[i]
    # Get the vertex we will draw
    v2 = morph[i]

    # Lerp to the target
    v2.lerp!(v1, 0.1)
    # Check how far we are from target
    @total_distance += v1.dist(v2)

  # If all the vertices are close, switch shape
  if (@total_distance < 0.08)
    @state = !state

  # Draw relative to center
  translate(width/2, height/2)
  # Draw a polygon that makes up all the vertices
  morph.each do |v|

Wednesday, 9 July 2014

Exploring PApplet with jruby

There is a lot of clever stuff that goes on in jruby, that allows you to treat java objects as if they were ruby. Recently I had been interested in refactoring the ruby-processings library loader, but that may be premature since changes seem to be afoot with the jruby class loader?

Anyway what is the current situation?
You can simply 'require a jar' to add the jar contents to your CLASSPATH, you can then start using the java classes as if they were ruby objects see PApplet example below:-
require 'java'
require '/home/tux/processing-2.2.1/core/library/core.jar'
app =
puts "inspect: #{app.inspect}"
app.set_size(200, 200)
puts "\nto_s: #{app.to_s}"
# print the default renderer
puts "\nrenderer: #{app.sketch_renderer}"
# prints a list of methods including '_size'
puts "\nmethods:\n #{ app.methods.reject{ |method| /_size/ !~ method.to_s} }"


inspect: #<Java::ProcessingCore::PApplet:0x4656c38e>

to_s: processing.core.PApplet[panel0,0,0,200x200,invalid,layout=java.awt.FlowLayout]

renderer: processing.core.PGraphicsJava2D

 [:text_size, :unregister_size, :register_size, :preferred_size_set?, :preferred_size=, :maximum_size=, :set_size, :is_minimum_size_set, :preferred_size, :set_preferred_size, :is_minimum_size_set?, :is_maximum_size_set?, :preferred_size_set, :set_maximum_size, :get_size, :minimum_size_set, :maximum_size_set?, :minimum_size=, :get_maximum_size, :get_minimum_size, :is_preferred_size_set?, :maximum_size, :minimum_size_set?, :maximum_size_set, :set_minimum_size, :is_preferred_size_set, :minimum_size, :get_preferred_size, :is_maximum_size_set]

Alternatively you can make use of the global CLASSPATH directly:-
require 'java'
$CLASSPATH << '/home/tux/processing-2.2.1/core/library/core.jar'
app =
puts "inspect: #{app.inspect}"
app.set_size(200, 200)
puts "\nto_s: #{app.to_s}"
# print the default renderer
puts "\nrenderer: #{app.sketch_renderer}"
# prints a list of methods including '_size'
puts "\nmethods:\n #{ app.methods.reject{ |method| /_size/ !~ method.to_s} }"

There is yet another way to do it using classloader directly:-

require 'java'
F =
class_loader = JRuby.runtime.jruby_class_loader
app =
puts "inspect: #{app.inspect}"
app.set_size(200, 200)
puts "\nto_s: #{app.to_s}"
# print the default renderer
puts "\nrenderer: #{app.sketch_renderer}"
# prints a list of methods including '_size'
puts "\nmethods:\n #{ app.methods.reject{ |method| /_size/ !~ method.to_s} }"

In ruby-processing exported sketches, the jars are currently added to the java CLASSPATH (ie on the java side) this may not be necessary anymore (no Applets), the current export process can mess with nested libraries (on the plus side you only need specify a directory to include the contained jars).
java -cp ".:../lib/ruby/*:../lib/*:../lib/library/*" org.jruby.Main ../lib/ruby-processing/runners/run.rb drawolver.rb

Tuesday, 8 July 2014

Pondering whether to hide implementation detail of Renderers

In a previous post I posted code using my new renderer interface, that exposed the user to the fact that the renderer object were java objects (partly because I thought it would be more transparent, but that would be lost on many users?). But I could easily hide it, by changing vecmath.rb as follows:-
require 'rvecmath', false), false), false)

AppRender = Java::ProcessingVecmath::AppRender
ShapeRender = Java::ProcessingVecmath::ShapeRender

The wise could use renderer.inspect to get the following, but it might not be obvious that they should do.

Actually it just occurred to me that inspect is a synonym for toString, that I should explicitly provide....
Well I learnt something new there it is not synonym after all, but chose to create a toString anyway.

Monday, 7 July 2014

Development plans for ruby-processing

The next release of ruby-processing will likely be version 2.5.0 (current release 2.4.4 using jruby-1.7.12).  The reason why this will not be a minor release is that I intend to incorporate my pre-compiled vecmath and fastmath libraries as developed on JRubyArt. Both these libraries have been created as jruby extensions (they are written in java, but can be loaded into the jruby runtime as ruby). Apart from the possible efficiency gains of using pre-compiled code, the compiled version of vecmath greatly simplifies the use of my ArcBall utility (only one line of code is required to include ArcBall functionality in a sketch).  What I propose to do is to roll back ruby processing commits to the 2.4.4 release, and set that as the stable branch (for the foreseeable future). I see no compelling reasons to issue anymore 2.4 point releases (eg to bump to jruby-1.7.13, and there seems no likelihood of any further processing 2.0 releases, now development has switched up to version 3.0).

JRubyArt has been using the much heralded jruby-9000, but that will only be at a preview release this summer, see tweet:-

Drawolver featuring new libraries, degree precision look up tables, and to_vertex utility for Vec3D:-
# Drawolver: draw 2D & revolve 3D

# Example shows how to use the vecmath library, including AppRender utility.
# On the ruby side features the use each_cons, a possibly a rare use for this 
# ruby Enumerable method?
# 2010-03-22 - fjenett (somewhat revised by Martin Prout 2014-07-06)

load_library :vecmath, :fastmath

attr_reader :drawing_mode, :points, :rot_x, :rot_y, :vertices, :renderer

def setup
  size 1024, 768, P3D
  @renderer =
  frame_rate 30

def draw
  background 0
  if (!drawing_mode)
    translate(width/2, height/2)
    rotate_x rot_x
    rotate_y rot_y
    @rot_x += 0.01
    @rot_y += 0.02
    translate(-width/2, -height/2)
  stroke 255
  points.each_cons(2) { |ps, pe| line ps.x, ps.y, pe.x, pe.y}

  if (!drawing_mode)
    stroke 125
    fill 120
    ambient_light 120, 120, 120
    vertices.each_cons(2) do |r1, r2|
      begin_shape(TRIANGLE_STRIP) { |v1, v2| v1.to_vertex(renderer); v2.to_vertex(renderer)}

def reset_scene
  @drawing_mode = true
  @points = []
  @rot_x = 0.0
  @rot_y = 0.0

def mouse_pressed
  points <<, mouse_y)

def mouse_dragged
  points <<, mouse_y)

def mouse_released
  points <<, mouse_y)

def recalculate_shape
  @vertices = []
  points.each_cons(2) do |ps, pe|
    b = (points.last - points.first).normalize!
    a = ps - points.first
    dot_product = b
    b *= dot_product
    normal = points.first + b
    c = ps - normal
    vertices << []
    (0..360).step(12) do |ang|
      e = normal + c * DegLut.cos(ang)
      e.z = c.mag * DegLut.sin(ang)
      vertices.last << e
  @drawing_mode = false

Sketch demonstrating use of ShapeRender (ShapeRender and AppRender both implement the Render interface which is used by Vec3D (and Vec2D) to_vertex, to_vertex_uv and to_normal methods, see here for earlier version without using ShapeRender, NB: the FastMath of that version has not survived:
# Trefoil, by Andres Colubri
# A parametric surface is textured procedurally
# by drawing on an offscreen PGraphics surface.
# Features (Vec3D).to_normal(renderer) and (Vec3D).to_vertex_uv(renderer, u, v)
# see line 62 for inititialization of renderer where obj is an instance of PShape
# renderer =

load_library :vecmath

attr_reader :pg, :trefoil

def setup
  size(1024, 768, P3D)


  # Creating offscreen surface for 3D rendering.
  @pg = create_graphics(32, 512, P3D)
  pg.background(0, 0)
  pg.fill(255, 0, 0, 200)

  # Saving trefoil surface into a PShape3D object
  @trefoil = create_trefoil(350, 60, 15, pg)

def draw

  pg.ellipse(rand(0.0 .. pg.width), rand(0.0 .. pg.height), 4, 4)

  ambient(250, 250, 250)
  pointLight(255, 255, 255, 0, 0, 200)

  translate(width/2, height/2, -200)
  rotate_x(frame_count * PI / 500)
  rotate_y(frame_count * PI / 500)

# Code to draw a trefoil knot surface, with normals and texture 
# coordinates. Makes of the Vec3D Render interface (uses ShapeRender here).
# Adapted from the parametric equations example by Philip Rideout:

# This function draws a trefoil knot surface as a triangle mesh derived
# from its parametric equation.
def create_trefoil(s, ny, nx, tex)

  obj = create_shape()

  renderer =
  (0 ... nx).each do |j|
    u0 = j.to_f / nx
    u1 = (j + 1).to_f / nx
    (0 ... ny).each do |i|
      v0 = i.to_f / ny
      v1 = (i + 1).to_f / ny

      p0 = eval_point(u0, v0)
      n0 = eval_normal(u0, v0)

      p1 = eval_point(u0, v1)
      n1 = eval_normal(u0, v1)

      p2 = eval_point(u1, v1)
      n2 = eval_normal(u1, v1)

      # Triangle p0-p1-p2      
      (p0 * s).to_vertex_uv(renderer, u0, v0)
      (p1 * s).to_vertex_uv(renderer, u0, v1)
      (p2 * s).to_vertex_uv(renderer, u1, v1)

      p1 = eval_point(u1, v0)
      n1 = eval_normal(u1, v0)

      # Triangle p0-p2-p1      
      (p0 * s).to_vertex_uv(renderer, u0, v0)
      (p2 * s).to_vertex_uv(renderer, u1, v1)
      (p1 * s).to_vertex_uv(renderer, u1, v0)
  return obj

# Evaluates the surface normal corresponding to normalized 
# parameters (u, v)
def eval_normal(u, v)
  # Compute the tangents and their cross product.
  p = eval_point(u, v)
  tangU = eval_point(u + 0.01, v)
  tangV = eval_point(u, v + 0.01)
  tangU -= p
  tangV -= p
  tangV.cross(tangU).normalize! # it is easy to chain Vec3D operations

# Evaluates the surface point corresponding to normalized 
# parameters (u, v)
def eval_point(u, v)
  a = 0.5
  b = 0.3
  c = 0.5
  d = 0.1
  s = TAU * u
  t = (TAU * (1 - v)) * 2

  sint = sin(t)
  cost = cos(t)
  sint15 = sin(1.5 * t)
  cost15 = cos(1.5 * t)

  r = a + b * cost15
  x = r * cost
  y = r * sint
  z = c * sint15

  dv =
  -1.5 * b * sint15 * cost - y,
  -1.5 * b * sint15 * sint + x,
  1.5 * c * cost15)

  q = dv.normalize     # regular normalize creates a new Vec3D for us
  qvn =, -q.x, 0).normalize!  # chained Vec3D operations

  ww = q.cross(qvn)

  coss = cos(s)
  sins = sin(s)
  x + d * (qvn.x * coss + ww.x * sins),
  y + d * (qvn.y * coss + ww.y * sins),
  z + d * ww.z * sins)

Sketch demonstrating new ArcBall utility, all that's needed to allow mousewheel zoom, and mouse drag to rotate the cube (this form uses camera 'under the hood' to centralize the cube in sketch viewpane, alternative form translates the sketch to provided coordinates):-
load_library :vecmath

attr_reader :my_cube

def setup
  size(600, 600, P3D)
  @my_cube = create_shape(BOX, 300, 300, 300)
  my_cube.set_fill(color(100, 10, 100))


def draw
  background(50, 50, 100)

def define_lights
  ambient(20, 20, 20)
  ambient_light(50, 50, 50)
  point_light(30, 30, 30, 200, -150, 0)
  directional_light(0, 30, 50, 1, 0, 0)
  spot_light(30, 30, 30, 0, 40, 200, 0, -0.5, -0.5, PI / 2, 2)

Tuesday, 24 June 2014

Decoupling Sub Classes Using Hook Messages (in ruby-processing)

About time I posted a bit more code:-
# An example demonstrating the use of a hook to decouple subclasses in 
# ruby-processing. The base class here is Spin, and we have included 
# post_initialize as the hook (it does nothing in the base class). SpinArm
# and SpinSpots both subclass Spin, but only SpinSpots requires the hook to
# change the initialization. Note the use the hook means the subclass does 
# not need to call super

def setup
  size 640, 360
  @arm ={ x: width/2, y: height/2, s: 0.01 })
  @spots ={ x: width/2, y: height/2, s: -0.02, d: 90.0 })

def draw
  background 204

class Spin

  attr_accessor :x, :y, :speed
  attr_accessor :angle

  def initialize(args = {})
    @x, @y = args[:x], args[:y]
    @speed = args[:s]
    @angle = args[:angle] || 0.0
    post_initialize(args)  # this is the hook

  def update
    @angle += speed

  def post_initialize args


class SpinArm < Spin # inherit from (or "extend") class Spin
  # NB: initialize inherited from Spin class

  def display
    stroke_weight 1
    stroke 0
    translate x, y
    rotate angle
    line 0, 0, 165, 0

class SpinSpots < Spin
  attr_accessor :dim

  def post_initialize args
    @dim = args[:d]

  def display
    translate x, y
    rotate angle
    ellipse(-dim/2, 0, dim, dim)
    ellipse(dim/2, 0, dim, dim)

Ruby 2D games using ruby-processing

Morohoshi-san is developing a ruby games application based on dxruby_sdl here is the tweet from ruby-gems:-

This is a sketch from dxruby_sdl on github run on my linux box (better if I had game controllers I am sure).

Here is the project on github.

Wednesday, 18 June 2014

JRubyArt is now using java extensions to generate ruby (Vecmath, ArcBall, DegLut)

Still waiting for @headius to confirm I am the right track with my java extensions to jruby. But I am not waiting forever so now my updated JRubyArt now includes these extensions:-
  1. A vecmath library, featuring Vec2D and Vec3D classes (written in java, but loaded as ruby)
  2. Also featured in the vecmath library is an ArcBall class  (also written in java, but loaded as ruby)
  3. A deglut library which is  now all, java uses a sin90 look up table to create sin cos functionality(is actually slightly faster than regular math sin/cos)
The extension stuff is written up here 

Thing to do:-
  1. Fix overloaded methods for color? eg background, fill, stroke
  2. Experiment with jafama (again, why is Jonathan Feinberg including google guava libs)
  3. improve build now at least a two stage process
  4. Clone and BFG clobber processing-2.2.1 snapshot?
  5. Create a renderer class that is initialized with PApplet, and has medods to send vertex(arg), normal(arg), curvedVertex(arg) etc. where arg is an instance of Vec3D?


About Me

My Photo
Consolidating my online identity as monkstone. I am a 64 bit linux user and advocate of open source software, you can sometimes find me on the processing forum.