It is possible using the control panel of ruby processing (a separate window see below)to adjust your variables interactively. Some on the fly such as resolution (placed within draw), or others built into the rules via a re-run (via some button or "mouse-click"). Here is my proof of concept example, where by changing the triangle constants you can ruin your Sierpinski triangle. Or in this achieve a fantastic transition from a Sierpinski triangle to the 'y' of my previous post, might be worthy of an animation? This is an interactive animation updates as you move the slider (patience there is bit of calculation to be done). For 'y' set slider to 0.5 for Sierpinski set the slider to 1.
load_library 'context_free', 'control_panel'
attr_accessor :factor
T_HEIGHT = Math.sqrt(3)/2 # triangle height
BOTTOM = Math.sqrt(3)/6
def setup_the_triangle factor
@triangle = ContextFree.define do
rule :tri do
triangle :alpha => 0.5
split do
tri :size => 0.5, :y => (BOTTOM - T_HEIGHT) * factor, :x => 0, :brightness => 0.8
rewind
tri :size => 0.5, :y => BOTTOM * factor, :x => -0.5 * factor, :brightness => 0.8
rewind
tri :size => 0.5, :y => BOTTOM * factor, :x => 0.5 * factor, :brightness => 0.8
end
end
end
end
def setup
size 600, 600
no_stroke
color_mode HSB, 1.0
smooth
@factor = 1
control_panel do |p|
p.slider :factor, (0.4...2), 1
end
end
def draw
background 255, 255, 0
setup_the_triangle @factor
@triangle.render :tri, :size => height/1.1, :stop_size => 3.0, :start_y => height/1.65
end
Experiments with ruby-processing (processing-2.2.1) and JRubyArt for processing-3.0
Thursday, 27 August 2009
Monday, 24 August 2009
Sierpinski triangle ruby processing (context free DSL)
Making use of the newly implemented triangle terminal for ruby processing context free DSL (what a mouthful), I've had a go at drawing the Sierpinski triangle:-
# sierpinski.rb ruby-processing
load_library 'context_free'
Y_TOP = -1/Math.sqrt(3)
Y_BOT = Math.sqrt(3)/6
def setup_the_triangle
@triangle = ContextFree.define do
rule :start do
unit :alpha => 0.5
end
rule :unit do
triangle :size => 1.0
split do
unit :size => 0.5, :x => 0, :y => Y_TOP, :brightness => 0.8
rewind
unit :size => 0.5, :x => -0.5, :y => Y_BOT, :brightness => 0.8
rewind
unit :size => 0.5, :x => 0.5, :y => Y_BOT, :brightness => 0.8
end
end
end
end
def setup
size 600, 600
setup_the_triangle
no_stroke
color_mode RGB, 1
smooth
draw_it
save_frame("sierpinski.png")
end
def draw
# Do nothing.
end
def draw_it
background 225, 225, 0
@triangle.render :start, :size => height, :stop_size => 3.0,
:start_x => width/2, :start_y => height * 0.6
end
def mouse_clicked
draw_it
end
I'm quite pleased at this attempt, though there are other ways of doing it.
The fun thing about context free is that even when it goes wrong, you often end up with something interesting like my 'y' here which was supposed to be the Sierpinski triangle, looks a bit like a window to me:
Somewhat inspired by the DSL version I have implemented a Sierspinski triangle using plain old java processing, and also repeated the exercise in ruby-processing.
# sierpinski.rb ruby-processing
load_library 'context_free'
Y_TOP = -1/Math.sqrt(3)
Y_BOT = Math.sqrt(3)/6
def setup_the_triangle
@triangle = ContextFree.define do
rule :start do
unit :alpha => 0.5
end
rule :unit do
triangle :size => 1.0
split do
unit :size => 0.5, :x => 0, :y => Y_TOP, :brightness => 0.8
rewind
unit :size => 0.5, :x => -0.5, :y => Y_BOT, :brightness => 0.8
rewind
unit :size => 0.5, :x => 0.5, :y => Y_BOT, :brightness => 0.8
end
end
end
end
def setup
size 600, 600
setup_the_triangle
no_stroke
color_mode RGB, 1
smooth
draw_it
save_frame("sierpinski.png")
end
def draw
# Do nothing.
end
def draw_it
background 225, 225, 0
@triangle.render :start, :size => height, :stop_size => 3.0,
:start_x => width/2, :start_y => height * 0.6
end
def mouse_clicked
draw_it
end
I'm quite pleased at this attempt, though there are other ways of doing it.
The fun thing about context free is that even when it goes wrong, you often end up with something interesting like my 'y' here which was supposed to be the Sierpinski triangle, looks a bit like a window to me:
Somewhat inspired by the DSL version I have implemented a Sierspinski triangle using plain old java processing, and also repeated the exercise in ruby-processing.
Labels:
context free,
ruby processing,
Sierpinski triangle
Sunday, 23 August 2009
Understanding terminal shapes Context Free
In the C++ implementation of context free the primitive shapes are defined as unit shape with center at the origin (where the convention is that y increases in the Northerly direction, ie toward the top of the page/screen). In processing unusually the convention is that y increases in the Southerly direction. This is reflected in the coordinates of the unit shapes of square, circle (irrelevant) and triangle (important).
NB: Click on image to see full size diagram. The top of triangle y = -1 / √3
and the bottom of the triangle is half that ie y = (√3) / 6
NB: Click on image to see full size diagram. The top of triangle y = -1 / √3
and the bottom of the triangle is half that ie y = (√3) / 6
Labels:
context free,
ruby-processing,
terminal shapes
Friday, 21 August 2009
Triangle now included in Ruby Processing cfdg DSL
Using triangle as terminal variant in ruby processing context free:-
# tri.rb ruby-processing
load_library 'context_free'
def setup_the_sun
@sun = ContextFree.define do
rule :start do
rot = 0
split do
4.times do
legs :rotation => rot
rot += 90
rewind
end
legs :rotation => 360
end
end
rule :legs do
triangle
legs :rotation => 1, :y => 0.1,
:size => 0.965, :color => [0.22, 0.15]
end
end
end
def setup
size 600, 600
setup_the_sun
no_stroke
color_mode HSB, 1.0
smooth
draw_it
save_frame("tri.png")
end
def draw
# Do nothing.
end
def draw_it
background 1.0
@sun.render :start, :size => height/7, :stop_size => 0.8,
:start_x => width/2, :start_y => height/2
end
def mouse_clicked
draw_it
end
# tri.rb ruby-processing
load_library 'context_free'
def setup_the_sun
@sun = ContextFree.define do
rule :start do
rot = 0
split do
4.times do
legs :rotation => rot
rot += 90
rewind
end
legs :rotation => 360
end
end
rule :legs do
triangle
legs :rotation => 1, :y => 0.1,
:size => 0.965, :color => [0.22, 0.15]
end
end
end
def setup
size 600, 600
setup_the_sun
no_stroke
color_mode HSB, 1.0
smooth
draw_it
save_frame("tri.png")
end
def draw
# Do nothing.
end
def draw_it
background 1.0
@sun.render :start, :size => height/7, :stop_size => 0.8,
:start_x => width/2, :start_y => height/2
end
def mouse_clicked
draw_it
end
Labels:
cfdg,
DSL,
ruby-processing
Wednesday, 19 August 2009
Introducing weighted rules (and randomness)
load_library 'context_free'
def setup_the_creature
@creature = ContextFree.define do
rule :start do
split do
11.times do |count| # 11 times increment rotation by 30 degrees
legs :rotation => count * 30
rewind # rewind context
end
legs :rotation => 360
end
end
rule :legs do
circle :hue => 0.15, :saturation => 0.5, :brightness => 1.0, :color => [0.95, 0.15]
legs :y => 0.1, :size => 0.965
end
rule :legs, 0.01 do
circle
split do
legs :rotation => 3
rewind
legs :rotation => -3
end
end
end
end
def setup
size 600, 600
setup_the_creature
no_stroke
color_mode HSB, 1.0
smooth
draw_it
# save_frame("creature.png")
end
def draw
# Do nothing.
end
def draw_it
background -1.0
@creature.render :start, :size => height/5, :stop_size => 0.8,
:start_x => width/2, :start_y => height/3, :color => [0.75, 0.1, 0.9]
end
def mouse_clicked
draw_it
end
Spooky result (makes your processor do a bit of work before it displays)
Labels:
context free,
ruby processing,
weighted rules
Tuesday, 18 August 2009
Rewind in Ruby Processing cfdg DSL
load_library 'context_free'
def setup_the_sun
@sun = ContextFree.define do
rule :start do
split do
12.times do |count|
legs :rotation => count * 30
rewind
end
legs :rotation => 360
end
end
rule :legs do
circle
legs :rotation => 1, :y => 0.1,
:size => 0.973, :color => [0.22, 0.15], :alpha => 0.5
end
end
end
def setup
size 600, 600
setup_the_sun
no_stroke
color_mode HSB, 1.0
smooth
draw_it
end
def draw
# Do nothing.
end
def draw_it
background 0.7
@sun.render :start, :size => height/7, :stop_size => 0.8,
:start_x => width/2, :start_y => height/2
end
def mouse_clicked
draw_it
end
Here is the result a dark sun or maybe a black hole variant:-
Labels:
cfdg,
rewind context,
ruby processing
Monday, 17 August 2009
Context Free Ruby Processing DSL
Here is my first go at writing context free rules in ruby (uses a library to support the DSL).
# shell_spiral.rb ruby-processing
load_library 'context_free'
def setup_the_shell
@shell = ContextFree.define do
rule :start do
shell_spiral :rotation => PI, :hue => 41.1,
:sat => 0.573, :brightness => 0.9238, :alpha => 0.5
end
rule :shell_spiral do
circle
shell_spiral :rotation => -0.50, :x => 0.25,
:size => 0.9985
end
end
end
def setup
size 1000, 1000
setup_the_shell
no_stroke
color_mode HSB, 1.0
smooth
draw_it
end
def draw
# Do nothing.
end
def draw_it
background -1.0
@shell.render :start, :size => height/50, :stop_size => 1,
:start_x => width/3, :start_y => height * 0.9
end
def mouse_clicked
draw_it
end
# shell_spiral.rb ruby-processing
load_library 'context_free'
def setup_the_shell
@shell = ContextFree.define do
rule :start do
shell_spiral :rotation => PI, :hue => 41.1,
:sat => 0.573, :brightness => 0.9238, :alpha => 0.5
end
rule :shell_spiral do
circle
shell_spiral :rotation => -0.50, :x => 0.25,
:size => 0.9985
end
end
end
def setup
size 1000, 1000
setup_the_shell
no_stroke
color_mode HSB, 1.0
smooth
draw_it
end
def draw
# Do nothing.
end
def draw_it
background -1.0
@shell.render :start, :size => height/50, :stop_size => 1,
:start_x => width/3, :start_y => height * 0.9
end
def mouse_clicked
draw_it
end
Labels:
cfdg,
DSL,
ruby processing
Saturday, 15 August 2009
Recursive call with probabalistic endpoint
I've been playing with the 'context free art' program cfdg quite a bit recently. So I've neglected what sent me there in the first place, which was the DSL cfdg ruby-processing implementation by Jeremy Ashkenas. Here I've written a stand alone ruby-processing script that mirrors one of the way infinite recursion is controlled in cfdg. The main way of preventing infinite recursion (which is used a lot in context free art) is to a have a lower size limit for the terminal elements (SQUARE or CIRCLE), and to have them reduce in size during the recursive loop. The second approach, which I have mirrored here is to have a low probability empty rule that will also terminate:-
REDUCE = 0.999;
def setup()
size(400, 400)
translate(100, 330)
rotate(0.3)
fill(255, 0, 0, 0)
background(0)
no_stroke()
smooth()
fill(255, 0, 0, 20) # transparency makes for almost '3d' look
srand = rand(999)
shell(srand, -0.008, 1.5, 25)
end
def shell(first, rot, disp, sz)
sec = rand(999)
if (sec == first) then
save_frame("probability.png")
else
sz *= REDUCE;
disp *= REDUCE;
translate(disp, 0)
rotate(rot)
ellipse(disp, 0, sz, sz)
shell(sec, rot, disp, sz) # recursive call with updated random
end
end
By its probabilistic nature this script will sometimes produce nothing, and occasionally it will crash at the java stack limit, here is one of the successful runs:-
You could always increase the size of the java stack as I did here. There are some instructions on how to do it at the processing discourse (alternative implementations) written by Jeremy Ashkenas:-
.... you can try increasing the java stack size. Create a "data" folder next to all the sketches and the library, and add a "java_args.txt" file in there that reads "-Xss8M".... that should do it, it worked for me.
REDUCE = 0.999;
def setup()
size(400, 400)
translate(100, 330)
rotate(0.3)
fill(255, 0, 0, 0)
background(0)
no_stroke()
smooth()
fill(255, 0, 0, 20) # transparency makes for almost '3d' look
srand = rand(999)
shell(srand, -0.008, 1.5, 25)
end
def shell(first, rot, disp, sz)
sec = rand(999)
if (sec == first) then
save_frame("probability.png")
else
sz *= REDUCE;
disp *= REDUCE;
translate(disp, 0)
rotate(rot)
ellipse(disp, 0, sz, sz)
shell(sec, rot, disp, sz) # recursive call with updated random
end
end
By its probabilistic nature this script will sometimes produce nothing, and occasionally it will crash at the java stack limit, here is one of the successful runs:-
You could always increase the size of the java stack as I did here. There are some instructions on how to do it at the processing discourse (alternative implementations) written by Jeremy Ashkenas:-
.... you can try increasing the java stack size. Create a "data" folder next to all the sketches and the library, and add a "java_args.txt" file in there that reads "-Xss8M".... that should do it, it worked for me.
Labels:
cfdg,
probability,
ruby processing
Subscribe to:
Posts (Atom)
Followers
Blog Archive
-
▼
2009
(50)
-
▼
August
(8)
- Adjusting your context free DSL variables
- Sierpinski triangle ruby processing (context free ...
- Understanding terminal shapes Context Free
- Triangle now included in Ruby Processing cfdg DSL
- Introducing weighted rules (and randomness)
- Rewind in Ruby Processing cfdg DSL
- Context Free Ruby Processing DSL
- Recursive call with probabalistic endpoint
-
▼
August
(8)
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