Text Along a Geomerative Path

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 RIGHT constant would be Java::ProcessingCore::PConstants::RIGHT but because we hate typing we have made the processing constant RIGHT available without the PConstants:: prefix. If you have namespace difficulties you can always fall back on the full forms.

# Louis Christodoulou (louis -at- louisc.co.uk)
#
# Very quickly thrown together code whilst learning how the
# geomerative library ticks.
#
# Here we take out previous scripts drawing and placing points along an arc and
# complete our initial idea of placing text along the arc.
#
# Full Writeup on the Blog here: http://louisc.co.uk/?p=2686
require 'geomerative'

MESSAGE = 'hello bendy world  >>>'.freeze
SCALE = 3
attr_reader :font

def settings
  size(800, 450)
end

def setup
  # Geomerative
  sketch_title 'Geomerative Text On A Path'
  RG.init(self)
  background(255)
  # We want a dymo labeller style look, replace this font with your choice
  # see data folder for licence
  @font = RFont.new(data_path('Impact Label Reversed.ttf'), 72, RIGHT)
end

def draw
  background(0)
  wave = RShape.new
  wave.add_move_to(0 * SCALE, 100 * SCALE)
  wave.add_bezier_to(
    0 * SCALE,
    100 * SCALE,
    50 * SCALE,
    25 * SCALE,
    100 * SCALE,
    100 * SCALE
  )
  wave.add_bezier_to(
    100 * SCALE,
    100 * SCALE,
    150 * SCALE,
    175 * SCALE,
    200 * SCALE,
    100 * SCALE
  )
  translate(100, -80)
  # draw our wave
  no_fill
  stroke(255, 0, 0)
  stroke_weight(60)
  stroke_cap(PROJECT)
  wave.draw
  stroke_cap(ROUND)
  # Collect some points along the curve
  RG.set_polygonizer(RCommand::UNIFORMLENGTH)
  RG.set_polygonizer_length(35)
  points = wave.get_points
  index = 0 # Letter index within the string message
  # loop through and place a letter at each point
  MESSAGE.each_char do |letter|
    stroke_weight(5)
    stroke_weight(10)
    center = RCommand.new(points[index], points[index + 1]).get_center
    fill(255)
    no_stroke
    push_matrix
    translate(center.x, center.y)
    rotate(get_angle(points[index], points[index + 1]))
    translate(5, 20)
    font.draw(letter)
    pop_matrix
    index += 1
  end
end

# Simple function to calculate the angle between two points
def get_angle(p1, p2)
  atan2(p2.y - p1.y, p2.x - p1.x)
end

dymo.png