Experiments with ruby-processing (processing-2.2.1) and JRubyArt for processing-3.0

Thursday 27 August 2009

Adjusting your context free DSL variables

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

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.

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

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


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)

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:-

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


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.

Followers

Blog Archive

About Me

My photo
I have developed JRubyArt and propane new versions of ruby-processing for JRuby-9.1.5.0 and processing-3.2.2