Bubble Sketch

To use the RCommand constant UNIFORMLENGTH in JRubyArt (and java constants in general with jruby) you would normally need to address it in the following way:- Java::Generative::RCommand::UNIFORMLENGTH. However in the geomerative gem we have done package_include 'geomerative' for you so you can get away with the short form RCommand::UNIFORMLENGTH, but you do need the RCommand:: prefix. For processing constants the full form for the CENTER constant would be Java::ProcessingCore::PConstants::CENTER but because we hate typing we have made the processing constant CENTER available without the PConstants:: prefix. If you have namespace difficulties you can always fall back on the full forms.

To make processing methods available in the FontAgent class (font_agent.rb) we include the Processing::Proxy module that gives similar access to that of a java inner class as used in vanilla processing.

# --------- GEOMERATIVE EXAMPLES ---------------
#
# This sketch deforms the text using noise as the underlying
# algorithm. mouse_x & mouse_y movement will change the amount
# & intensity of the noise values.
# Key 'f' = Switches animation on/off
# Key '+'  & '-' = Changes the diameter of our ellipse.
#
# Licensed under GNU General Public License (GPL) version 3.
# http://www.gnu.org/licenses/gpl.html
#
# A series of tutorials for using the Geomerative Library
# developed by Ricard Marxer.
# http://www.ricardmarxer.com/geomerative/
#
# More info on these tutorials and workshops at :
# www.freeartbureau.org/blog
# translated to JRubyArt by Martin Prout
#
require 'geomerative'
require_relative 'font_agent'

attr_reader :my_agents, :step, :stop_anime

def settings
  size(800, 350)
  smooth
end

def setup
  sketch_title 'Bubbles'
  background(0)
  @step = 3
  my_text = 'BUBBLES'
  RG.init(self)
  my_font = RFont.new(data_path('FreeSans.ttf'), 113, CENTER)
  @stop_anime = false
  RCommand.set_segment_length(10)
  RCommand.set_segmentator(RCommand::UNIFORMLENGTH)
  @my_agents = my_font.to_group(my_text).get_points.map do |point|
    FontAgent.new(loc: Vec2D.new(point.x, point.y))
  end
end

def draw
  translate(400, 205)
  background(0)
  fill(255)
  my_agents.each do |point|
    point.display(step: step)
    point.motion(x: mouse_x, y: mouse_y)
  end
end

def key_pressed
  case key
  when 'f', 'F'
    @stop_anime = !stop_anime
    stop_anime ? no_loop : loop
  when '+'
    @step += 1
  when '-'
    @step -= 1
  end
end

FontAgent class

# FontAgent class handles motion and display
class FontAgent
  include Processing::Proxy # gives java 'inner class like' access to App
  attr_reader :loc, :mot

  def initialize(loc:)
    @loc = loc
    @mot = 0
  end

  def motion(x:, y:)
    noise_scale = map1d(x, (0..width), (0.001..0.01))
    noise_z = map1d(y, (0..height), (frame_count * 0.0003..frame_count * 0.02))
    @mot = noise(
      loc.x * noise_scale * noise_z,
      loc.y * noise_scale * noise_z
    ) * 53
  end

  def display(step:)
    no_stroke
    fill(255, 53)
    ellipse(loc.x, loc.y, mot + step, mot + step)
  end
end

bubbles.png