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

Sunday 6 June 2010

Towards an Escher Bird Tiling (Ruby processing context-free DSL)


load_libraries 'context_free'

def setup_the_birds


  @birds= ContextFree.define do
 
    ############ Begin defining custom terminal, an wavy_triangle triangle        
    class << self     
      define_method(:wavy_diamond) do |some_options# wavy_triangle triangle
        size, options = *self.get_shape_values(some_options)
        rot = options[:rotation]
        x0 = options[:x]
        y0 = options[:y]
        disp = options[:disp]
        pts = Array.new(16)
        pts[0] = PVector.new(x0 - 0.25 * size, y0 - size/Math.sqrt(3))     # A
        pts[2] = PVector.new(x0 + 0.75 * size, y0 - size/Math.sqrt(3))     # B
        pts[4] = PVector.new(x0 + 0.25 * size, y0 + (Math.sqrt(3)*size)/6) # C
        pts[6] = PVector.new(x0 - 0.75 * size, y0 + (Math.sqrt(3)*size)/6) # D
        pts[1] = get_mid_point(pts[0], pts[2])#Ab
        pts[3] = get_mid_point(pts[2], pts[4])#Bc
        pts[5] = get_mid_point(pts[4], pts[6])#Cd
        pts[7] = get_mid_point(pts[6], pts[0])#Da
        pts[8] = get_mid_point(pts[0], pts[1])#Aba
        adjust_bezier(pts[8], PI/2, -disp * size)#Aba
        pts[9] = get_mid_point(pts[1], pts[2])
        adjust_bezier(pts[9], PI/2, disp * size)
        pts[10] = get_mid_point(pts[2], pts[3])
        adjust_bezier(pts[10], PI/3, disp * size)
        pts[11] = get_mid_point(pts[3], pts[4])
        adjust_bezier(pts[11], PI/3, -disp * size)
        pts[12] = get_mid_point(pts[4], pts[5])
        adjust_bezier(pts[12], PI/2, disp * size)
        pts[13] = get_mid_point(pts[5], pts[6])
        adjust_bezier(pts[13], PI/2, -disp * size)
        pts[14] = get_mid_point(pts[6], pts[7])
        adjust_bezier(pts[14], PI/3, -disp * size)
        pts[15] = get_mid_point(pts[7], pts[0])
        adjust_bezier(pts[15], PI/3, disp * size)
        rotate(rot) if rot
        smooth
        stroke 0
        begin_shape
        vertex(pts[0].x, pts[0].y)
        bezier_vertex(pts[0].x, pts[0].y, pts[8].x, pts[8].y, pts[1].x, pts[1].y)
        bezier_vertex(pts[1].x, pts[1].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[3].x, pts[3].y)
        bezier_vertex(pts[3].x, pts[3].y, pts[11].x, pts[11].y, pts[4].x, pts[4].y)
        bezier_vertex(pts[4].x, pts[4].y, pts[12].x, pts[12].y, pts[5].x, pts[5].y)
        bezier_vertex(pts[5].x, pts[5].y, pts[13].x, pts[13].y, pts[6].x, pts[6].y)
        bezier_vertex(pts[6].x, pts[6].y, pts[14].x, pts[14].y, pts[7].x, pts[7].y)
        bezier_vertex(pts[7].x, pts[7].y, pts[15].x, pts[15].y, pts[0].x, pts[0].y)
        vertex(pts[0].x, pts[0].y)
        end_shape(CLOSE)        
        rotate(-rot) if rot
      end
   
      private
      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
    end
 
    ########### End definition of custom terminal 'wavy_diamond' shape
    rule :birds do
      10.times do |i|
        10.times do |j|
          wavy_diamond :size => 1, :x => (i*2 + 0.5 * j%2), :y => j * 0.9
        end
      end
    end
  end
end

def setup
  size 400, 400
  smooth
  setup_the_birds
  draw_it
end

def draw_it
  background 255
  @birds.render :birds, :start_x => -50, :start_y => 20,
  :size => height/6, :color => [0, 0.8, 0.8, 1], :disp => 0.32
end

def draw
  # do nothing
end




No comments:

Post a Comment

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