Experiments with ruby-processing (processing-2.2.1) and JRubyArt for processing-3.0
Thursday, 19 November 2009
Lindenmayer system in ruby-processing
##
# Lindenmayer System in ruby-processing by Martin Prout
# Loosely based on processing Pentigree L-System by Geraldine Sarmiento
###
require 'pentigree'
class Pentigree_Test < Processing::App
load_library :grammar
attr_reader :pentigree
def setup
size 800, 800
@pentigree = Pentigree.new
pentigree.create_grammar(5)
no_loop
end
def draw
background 0
pentigree.render
end
end
######################
# pentigree.rb
######################
class Pentigree
include Processing::Proxy
attr_reader :axiom, :grammar, :start_length, :theta, :production, :generations, :draw_length
def initialize
@axiom = "F-F-F-F-F"
@grammar = Grammar.new(axiom)
grammar.add_rule("F", "F-F++F+F-F-F")
@start_length = 40.0
@theta = (Math::PI/180) * 72.0 # convert degrees to radians
@production = axiom
@draw_length = start_length
end
def render
translate(width * 0.8, height * 0.75)
@production.each_char do |prod|
case prod
when 'F'
no_fill
stroke 255
line(0, 0, 0, draw_length)
translate(0, draw_length)
when '+'
rotate(theta)
when '-'
rotate(-theta)
when '['
push_matrix()
when ']'
pop_matrix()
else
puts "Character '#{element}' is not in grammar"
end
end
end
def create_grammar(gen)
@draw_length *= 0.6**gen
@production = grammar.generate gen
end
end
Labels:
l-system,
Lindenmayer system,
ruby-processing
Tuesday, 17 November 2009
Tessellated "curvy" triangles in ruby-processing
# alhambra.rb by Martin Prout
class CurvyTriangle < Processing::App
def setup()
size(700, 650)
@x_values = [100, 300, 500, 700]
@y_values = [50 * Math.sqrt(3), 150 * Math.sqrt(3), 250 * Math.sqrt(3), 350 * Math.sqrt(3)]
background 21, 15, 72
smooth
render
save_frame "alahambra.png"
end
def draw_hexagon(xpos, ypos, sz, theta)
begin_shape
6.times do |i|
vertex(xpos + sz*Math.cos((Math::PI/3 * i) + theta), ypos + sz*Math.sin((Math::PI/3 * i) +theta));
end
end_shape CLOSE
end
def draw_triangle(x0, y0, sz, color, disp)
# Calculate triangle points
pts = Array.new(12)
pts[0] = PVector.new(x0, y0 - sz/Math.sqrt(3)) # A
pts[1] = PVector.new(x0 - 0.5 * sz, y0 + (Math.sqrt(3)*sz)/6)# B
pts[2] = PVector.new(x0 + 0.5 * sz, y0 + (Math.sqrt(3)*sz)/6)# C
pts[3] = get_mid_point(pts[0], pts[1]) # Ab
pts[4] = get_mid_point(pts[1], pts[2]) # Bc
pts[5] = get_mid_point(pts[0], pts[2]) # Ca
pts[6] = get_mid_point(pts[0], pts[3]) # Aba
adjust_bezier(pts[6], Math::PI/3, disp*sz) # Aba
pts[7] = get_mid_point(pts[3], pts[1]) # Abb
adjust_bezier(pts[7], Math::PI/3, -disp*sz) # Abb
pts[8] = get_mid_point(pts[1], pts[4])
adjust_bezier(pts[8], Math::PI/2, -disp*sz)
pts[9] = get_mid_point(pts[4], pts[2])
adjust_bezier(pts[9], Math::PI/2, disp*sz)
pts[10] = get_mid_point(pts[2], pts[5])
adjust_bezier(pts[10], -Math::PI/3, -disp*sz)
pts[11] = get_mid_point(pts[5], pts[0])
adjust_bezier(pts[11], -Math::PI/3, disp*sz)
# render triangle
fill color
begin_shape()
vertex(pts[0].x, pts[0].y)
bezier_vertex(pts[0].x, pts[0].y, pts[6].x, pts[6].y, pts[3].x, pts[3].y)
bezier_vertex(pts[3].x, pts[3].y, pts[7].x, pts[7].y, pts[1].x, pts[1].y)
bezier_vertex(pts[1].x, pts[1].y, pts[8].x, pts[8].y, pts[4].x, pts[4].y)
bezier_vertex(pts[4].x, pts[4].y, pts[9].x, pts[9].y, pts[2].x, pts[2].y)
bezier_vertex(pts[2].x, pts[2].y, pts[10].x, pts[10].y, pts[5].x, pts[5].y)
bezier_vertex(pts[5].x, pts[5].y, pts[11].x, pts[11].y, pts[0].x, pts[0].y)
end_shape(CLOSE)
# set color and render small hexagon
fill(255);
draw_hexagon(x0 + 4, y0, sz * 0.214, 0);
end
def adjust_bezier(base, theta, disp)
base.add(PVector.new(Math.cos(theta)*disp, Math.sin(theta)*disp))
end
def get_mid_point(a, b)
mid = PVector.add(a, b)
mid.div(2)
return mid
end
def render
@x_values.length.times do |column|
@y_values.length.times do |row|
if (row % 2 == 0) then
if (column % 3 ==0) then
draw_triangle(@x_values[column], @y_values[row], 200, color(255, 0, 0), 0.32)
else
draw_triangle(@x_values[column], @y_values[row], 200, color(255, 0, 255), 0.32)
end
# end
# offset tiles so that they tesselate
elsif ((column - 2) % 3 ==0) then
draw_triangle(@x_values[column] - 100, @y_values[row], 200, color(255, 0, 0), 0.32)
else
draw_triangle(@x_values[column] - 100, @y_values[row], 200, color(255, 0, 255), 0.32)
end
end
end
end
end
Labels:
ruby processing,
tessellation
Wednesday, 11 November 2009
Dynamic rand with ruby-processing context-free DSL
Regular context free can't do dynamic random, here I experiment with the possibilities of ruby-processing DSL. This example is essentially a modified city.rb that is included as a sample with the application. Note I have added a convenience method rand_range for use in the DSL, partly as an experiment in ways of extending the program.
load_library 'context_free'
def setup_the_spots
@spots = ContextFree.define do
class << self
define_method (:rand_range) do |max, min| # nice to have a range
rand * (max - min) + min
end
end
rule :region do
split do
block :x => -0.25, :y => -0.25, :brightness => 1.0, :saturation => 1.0
rewind
block :x => 0.25, :y => -0.25, :brightness => 1.0, :saturation => 1.0
rewind
block :x => 0.25, :y => 0.25, :brightness => 1.0, :saturation => 1.0
rewind
block :x => -0.25, :y => 0.25, :brightness => 1.0, :saturation => 1.0
end
end
rule :block do
spots :size => 0.85, :hue => rand, :saturation => rand_range(1.0, 0.8), :brightness => rand_range(1.0, 0.8)
end
rule :block, 5 do
region :size => 0.5, :rotation => rand_range(8, 4), :hue => rand_range(0.8, 0.5), :saturation => rand_range(1.0, 0.5), :brightness => rand_range(1.0, 0.5)
end
rule :block, 0.1 do
# Do nothing
end
rule :spots do
circle :hue => rand_range(0.8, 0.5), :saturation => 1.0, :brightness => 1.0, :alpha => 0.4
end
end
end
def setup
size 600, 600
background 255, 255, 0
smooth
color_mode HSB, 1.0
setup_the_spots
draw_it
end
def draw
# Do nothing
end
def draw_it
@spots.render :region, :color => [0.2, 1.0, 1.0, 1.0],
:start_x => width/2, :start_y => height/2,
:size => height/2.5
end
def mouse_clicked
draw_it
end

load_library 'context_free'
def setup_the_spots
@spots = ContextFree.define do
class << self
define_method (:rand_range) do |max, min| # nice to have a range
rand * (max - min) + min
end
end
rule :region do
split do
block :x => -0.25, :y => -0.25, :brightness => 1.0, :saturation => 1.0
rewind
block :x => 0.25, :y => -0.25, :brightness => 1.0, :saturation => 1.0
rewind
block :x => 0.25, :y => 0.25, :brightness => 1.0, :saturation => 1.0
rewind
block :x => -0.25, :y => 0.25, :brightness => 1.0, :saturation => 1.0
end
end
rule :block do
spots :size => 0.85, :hue => rand, :saturation => rand_range(1.0, 0.8), :brightness => rand_range(1.0, 0.8)
end
rule :block, 5 do
region :size => 0.5, :rotation => rand_range(8, 4), :hue => rand_range(0.8, 0.5), :saturation => rand_range(1.0, 0.5), :brightness => rand_range(1.0, 0.5)
end
rule :block, 0.1 do
# Do nothing
end
rule :spots do
circle :hue => rand_range(0.8, 0.5), :saturation => 1.0, :brightness => 1.0, :alpha => 0.4
end
end
end
def setup
size 600, 600
background 255, 255, 0
smooth
color_mode HSB, 1.0
setup_the_spots
draw_it
end
def draw
# Do nothing
end
def draw_it
@spots.render :region, :color => [0.2, 1.0, 1.0, 1.0],
:start_x => width/2, :start_y => height/2,
:size => height/2.5
end
def mouse_clicked
draw_it
end

Labels:
context free,
DSL,
random,
ruby processing
Tuesday, 10 November 2009
Flower in ruby-processing DSL
# flower.rb ruby-processing
load_library 'context_free'
ROT = 180*(Math.sqrt(5) - 1)
def setup_the_flower
@flower = ContextFree.define do
@rot = 0
@pet = 0
rule :start do
flower :brightness => 1.0
end
rule :flower do
@rot += ROT
@rot = @rot % 360
split do
petal :brightness => 1.0, :saturation => 0.5
rewind
flower :rotation => @rot, :size => 0.99, :hue => 0.15
rewind
end
end
rule :petal do
@pet += 15
split do
triangle :x => 4.1, :rotation => @pet
rewind
petal :size => 0.995, :alpha => 0.4, :brightness => 0.5
#rewind
end
end
end
end
def setup
size 800, 800
setup_the_flower
smooth
draw_it
save_frame("flower.png")
end
def draw
# Do nothing.
end
def draw_it
background 60, 0, 0
@flower.render :start, :size => width*0.8, :stop_size => 2,
:start_x => width/2, :start_y => height/2
end
load_library 'context_free'
ROT = 180*(Math.sqrt(5) - 1)
def setup_the_flower
@flower = ContextFree.define do
@rot = 0
@pet = 0
rule :start do
flower :brightness => 1.0
end
rule :flower do
@rot += ROT
@rot = @rot % 360
split do
petal :brightness => 1.0, :saturation => 0.5
rewind
flower :rotation => @rot, :size => 0.99, :hue => 0.15
rewind
end
end
rule :petal do
@pet += 15
split do
triangle :x => 4.1, :rotation => @pet
rewind
petal :size => 0.995, :alpha => 0.4, :brightness => 0.5
#rewind
end
end
end
end
def setup
size 800, 800
setup_the_flower
smooth
draw_it
save_frame("flower.png")
end
def draw
# Do nothing.
end
def draw_it
background 60, 0, 0
@flower.render :start, :size => width*0.8, :stop_size => 2,
:start_x => width/2, :start_y => height/2
end
Labels:
DSL,
flower,
ruby-processing
Sunday, 8 November 2009
Heighway Dragon in ruby-processing context free DSL
This implementation of the Heighway dragon starts with square, that is hidden by being transparent, the rotations scaling and translations used make this solution similar to the paper folding solution.
# dragon.rb ruby-processing NB: :alpha is now implemented in ruby-processing (since 8 Nov 2009) the brightness, of dragon in the start rule has no effect, but the DSL doesn't like to call rules with no arguments.
load_library 'context_free'
def setup_the_dragon
@dragon = ContextFree.define do
rule :start do
dragon :brightness => 1.0
end
rule :dragon do
split do
fractal :hue => 0, :brightness => 1.0, :saturation => 1.0
rewind
fractal :hue => 0.2, :brightness => 1.0, :saturation => 1.0, :rotation => 90, :x => -0.4
rewind
fractal :hue => 0.7, :brightness => 1.0, :saturation => 1.0, :rotation => 270, :x => -0.4, :y => -0.33
rewind
end
end
rule :fractal do
square :alpha => 0.01
split do
fractal :size => 1/Math.sqrt(2), :rotation => -45, :x => 0.25, :y => 0.25
rewind
fractal :size => 1/Math.sqrt(2), :rotation => 135, :x => 0.25, :y => 0.25
rewind
end
end
end
end
def setup
size 800, 800
setup_the_dragon
smooth
draw_it
save_frame("dragon.png")
end
def draw
# Do nothing.
end
def draw_it
background 0
@dragon.render :start, :size => width*0.6, :stop_size => 2,
:start_x => width*0.6, :start_y => height*0.6
end
# dragon.rb ruby-processing NB: :alpha is now implemented in ruby-processing (since 8 Nov 2009) the brightness, of dragon in the start rule has no effect, but the DSL doesn't like to call rules with no arguments.
load_library 'context_free'
def setup_the_dragon
@dragon = ContextFree.define do
rule :start do
dragon :brightness => 1.0
end
rule :dragon do
split do
fractal :hue => 0, :brightness => 1.0, :saturation => 1.0
rewind
fractal :hue => 0.2, :brightness => 1.0, :saturation => 1.0, :rotation => 90, :x => -0.4
rewind
fractal :hue => 0.7, :brightness => 1.0, :saturation => 1.0, :rotation => 270, :x => -0.4, :y => -0.33
rewind
end
end
rule :fractal do
square :alpha => 0.01
split do
fractal :size => 1/Math.sqrt(2), :rotation => -45, :x => 0.25, :y => 0.25
rewind
fractal :size => 1/Math.sqrt(2), :rotation => 135, :x => 0.25, :y => 0.25
rewind
end
end
end
end
def setup
size 800, 800
setup_the_dragon
smooth
draw_it
save_frame("dragon.png")
end
def draw
# Do nothing.
end
def draw_it
background 0
@dragon.render :start, :size => width*0.6, :stop_size => 2,
:start_x => width*0.6, :start_y => height*0.6
end
Labels:
context free,
DSL,
heighway dragon,
ruby processing
Thursday, 5 November 2009
Lévy curve implemented in ruby-processing context free DSL
NB I modified the context_free.rb to accept :alpha to get this script to work properly, these mods are now included in ruby-processing (since 8th Nov 2009).
# levy.rb ruby-processing NB: :alpha is now implemented ruby-processing
load_library 'context_free'
def setup_the_levy
@levy = ContextFree.define do
rule :start do
levy :brightness => 0.9
end
rule :levy do
square :alpha => 0.1
split do
levy :size => 1/Math.sqrt(2), :rotation => -45, :x => 0.5, :brightness => 0.9
rewind
levy :size => 1/Math.sqrt(2), :rotation => 45, :x => 0.5, :brightness => 0.9
end
end
end
end
def setup
size 400, 400
setup_the_levy
smooth
draw_it
save_frame("levy.png")
end
def draw
# Do nothing.
end
def draw_it
background 255
@levy.render :start, :size => 250, :stop_size => 2,
:start_x => width/4, :start_y => height/2
end
# levy.rb ruby-processing NB: :alpha is now implemented ruby-processing
load_library 'context_free'
def setup_the_levy
@levy = ContextFree.define do
rule :start do
levy :brightness => 0.9
end
rule :levy do
square :alpha => 0.1
split do
levy :size => 1/Math.sqrt(2), :rotation => -45, :x => 0.5, :brightness => 0.9
rewind
levy :size => 1/Math.sqrt(2), :rotation => 45, :x => 0.5, :brightness => 0.9
end
end
end
end
def setup
size 400, 400
setup_the_levy
smooth
draw_it
save_frame("levy.png")
end
def draw
# Do nothing.
end
def draw_it
background 255
@levy.render :start, :size => 250, :stop_size => 2,
:start_x => width/4, :start_y => height/2
end
Labels:
DSL,
Levy curve,
ruby processing
jEdit as a cross platform GUI?
I have created a commando file 'rp5.xml' that allows me to run the file I am editing in jEdit (runs 'rp5 run buffer.rb'), directly from jEdit. You can download my file from the jEdit community downloads. It is easy to edit the commando file, so you could add watch as alternative to run.
You could also use a bsh macro to launch the command file, this is mine:-
new console.commando.CommandoDialog(view,"commando.rp5");
Here is a screenshot of the jedit buffer window a running ruby-processing applet, and the associated console pane.
You could also use a bsh macro to launch the command file, this is mine:-
new console.commando.CommandoDialog(view,"commando.rp5");
Here is a screenshot of the jedit buffer window a running ruby-processing applet, and the associated console pane.
Labels:
gui,
jedit,
ruby processing
Subscribe to:
Posts (Atom)
Followers
About Me
- monkstone
- I have developed JRubyArt and propane new versions of ruby-processing for JRuby-9.1.5.0 and processing-3.2.2





