Skip to content

Commit

Permalink
replaced map with vine
Browse files Browse the repository at this point in the history
  • Loading branch information
jashkenas committed May 31, 2009
1 parent 06eec38 commit 9f822bd
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 125 deletions.
54 changes: 23 additions & 31 deletions context_free.rb
Expand Up @@ -5,13 +5,23 @@ module Processing


class ContextFree class ContextFree


include Processing::Proxy

attr_accessor :rules, :app attr_accessor :rules, :app


STOP_SIZE = 1.5
AVAILABLE_OPTIONS = [:x, :y, :rotation, :size, :flip, :color, :hue, :saturation, :brightness] AVAILABLE_OPTIONS = [:x, :y, :rotation, :size, :flip, :color, :hue, :saturation, :brightness]
HSB_ORDER = {:hue => 0, :saturation => 1, :brightness => 2} HSB_ORDER = {:hue => 0, :saturation => 1, :brightness => 2}




# Define a context-free system. Use this method to create a ContextFree
# object. Call render() on it to make it draw.
def self.define(&block)
cf = ContextFree.new
cf.instance_eval &block
cf
end


# Initialize a bare ContextFree object with empty recursion stacks. # Initialize a bare ContextFree object with empty recursion stacks.
def initialize def initialize
@app = $app @app = $app
Expand All @@ -30,14 +40,6 @@ def initialize
@values[option_name] @values[option_name]
end end
end end


# When you start a context-free drawing, you can initialize the variables
# with starting values.
def setup(some_hash)
@starting_values = some_hash
@starting_values[:stop_size] ||= STOP_SIZE
end




# Here's the first serious method: A Rule has an # Here's the first serious method: A Rule has an
Expand All @@ -57,7 +59,7 @@ def rule(rule_name, prob=1, &proc)
def #{rule_name}(options) def #{rule_name}(options)
merge_options(@values, options) merge_options(@values, options)
pick = determine_rule(#{rule_name.inspect}) pick = determine_rule(#{rule_name.inspect})
@finished = true if @values[:size] < STOP_SIZE @finished = true if @values[:size] < @values[:stop_size]
unless @finished unless @finished
get_ready_to_draw get_ready_to_draw
pick[1].call(options) pick[1].call(options)
Expand Down Expand Up @@ -159,16 +161,19 @@ def rewind


# Render the is method that kicks it all off, initializing the options # Render the is method that kicks it all off, initializing the options
# and calling the first rule. # and calling the first rule.
def render(rule_name) def render(rule_name, starting_values={})
@values = {:x => 0, :y => 0, @values = {:x => 0, :y => 0,
:rotation => 0, :flip => false, :rotation => 0, :flip => false,
:size => 20, :width => 20, :height => 20, :size => 20, :width => 20, :height => 20,
:color => [0.5, 0.5, 0.5]} :color => [0.5, 0.5, 0.5],
@values.merge!(@starting_values) :stop_size => 1.5}
@values.merge!(starting_values)
@finished = false @finished = false
@app.reset_matrix @app.reset_matrix
@app.rect_mode CENTER
@app.ellipse_mode CENTER
@app.no_stroke @app.no_stroke
@app.color_mode(App::HSB, 1.0) @app.color_mode HSB, 1.0
@app.translate @values[:start_x], @values[:start_y] @app.translate @values[:start_x], @values[:start_y]
self.send(rule_name, {}) self.send(rule_name, {})
end end
Expand Down Expand Up @@ -196,40 +201,27 @@ def get_shape_values(some_options)
# methods, but hopefully triangles will be added soon. # methods, but hopefully triangles will be added soon.
def square(some_options=nil) def square(some_options=nil)
size, options = *get_shape_values(some_options) size, options = *get_shape_values(some_options)
@app.rect(-(size/2), -(size/2), size, size) @app.rect(0, 0, size, size)
end end




def circle(some_options=nil) def circle(some_options=nil)
size, options = *get_shape_values(some_options) size, options = *get_shape_values(some_options)
@app.ellipse(-(size/2), -(size/2), size, size) @app.ellipse(0, 0, size, size)
end end




def ellipse(some_options=nil) def ellipse(some_options={})
rot = some_options[:rotation] rot = some_options[:rotation]
@app.rotate(rot) if rot @app.rotate(rot) if rot
size, options = *get_shape_values(some_options) size, options = *get_shape_values(some_options)
width = options[:width] || options[:size] width = options[:width] || options[:size]
height = options[:height] || options[:size] height = options[:height] || options[:size]
@app.oval(options[:x], options[:y], width, height) @app.oval(options[:x] || 0, options[:y] || 0, width, height)
@app.rotate(-rot) if rot @app.rotate(-rot) if rot
end end
alias_method :oval, :ellipse alias_method :oval, :ellipse


end end



# Processing::App gets a context_free method, as a hook for defining the rules.
class App

# Instantiate and setup a new ContextFree object.
def context_free(&block)
drawing = ContextFree.new
drawing.instance_eval &block
return drawing
end

end

end end
39 changes: 23 additions & 16 deletions samples/city.rb
@@ -1,57 +1,64 @@
load_library 'context_free' load_library 'context_free'


def setup_the_city def setup_the_city
@city = context_free do
rule :whole do @city = ContextFree.define do

rule :neighborhood do
split do split do
quad :x => -0.25, :y => -0.25 block :x => -0.25, :y => -0.25
rewind rewind
quad :x => 0.25, :y => -0.25 block :x => 0.25, :y => -0.25
rewind rewind
quad :x => 0.25, :y => 0.25 block :x => 0.25, :y => 0.25
rewind rewind
quad :x => -0.25, :y => 0.25 block :x => -0.25, :y => 0.25
end end
end end


rule :quad do rule :block do
fill :size => 0.85 buildings :size => 0.85
end end


rule :quad, 5 do rule :block, 5 do
whole :size => 0.5, :rotation => rand(4), :hue => rand(2), :brightness => rand(3) neighborhood :size => 0.5, :rotation => rand(8)-4, :hue => rand(2), :brightness => rand + 0.75
end end


rule :quad, 0.1 do rule :block, 0.1 do
# Do nothing # Do nothing
end end


rule :fill do rule :buildings do
square square
end end

end end

end end




def setup def setup
size 600, 600 size 600, 600
setup_the_city
smooth smooth
setup_the_city
@background = color 255, 255, 255 @background = color 255, 255, 255
the_color = [0.1, 0.1, 0.1]
@city.setup :start_x => width/2, :start_y => height/2, :size => height/3, :color => the_color
draw_it draw_it
end end



def draw def draw
# Do nothing # Do nothing
end end



def draw_it def draw_it
background @background background @background
@city.render :whole @city.render :neighborhood,
:start_x => width/2, :start_y => height/2,
:size => height/2.5, :color => [0.1, 0.1, 0.1]
end end



def mouse_clicked def mouse_clicked
draw_it draw_it
end end
1 change: 1 addition & 0 deletions samples/data/java_args.txt
@@ -0,0 +1 @@
-Xss8M
71 changes: 0 additions & 71 deletions samples/map.rb

This file was deleted.

14 changes: 7 additions & 7 deletions samples/tree.rb
Expand Up @@ -9,7 +9,8 @@ def setup_the_trees
c.slider :srand, 0..100 c.slider :srand, 0..100
end end


@tree = context_free do @tree = ContextFree.define do

rule :seed do rule :seed do
square square
leaf :y => 0 if size < 4.5 && rand < 0.018 leaf :y => 0 if size < 4.5 && rand < 0.018
Expand Down Expand Up @@ -37,17 +38,18 @@ def setup_the_trees
the_size = rand(25) the_size = rand(25)
the_x = [1, 0, 0, 0][rand(4)] the_x = [1, 0, 0, 0][rand(4)]
circle :size => the_size, :hue => 0.15, :saturation => 1.25, circle :size => the_size, :hue => 0.15, :saturation => 1.25,
:brightness => 1.9, :x => the_x, :color => [0.3, 0.5] :brightness => 1.9, :x => the_x, :color => [0.95, 0.15]
end end


rule :flower do rule :flower do
split :brightness => rand(1.3)+4.7, :set_width => rand(15)+10, :set_height => rand(2)+2 do split :saturation => 0, :brightness => rand(1.3)+4.7, :set_width => rand(15)+10, :set_height => rand(2)+2 do
oval :rotation => 0 oval :rotation => 0
oval :rotation => 45 oval :rotation => 45
oval :rotation => 90 oval :rotation => 90
oval :rotation => 135 oval :rotation => 135
end end
end end

end end


end end
Expand All @@ -59,13 +61,11 @@ def setup
no_stroke no_stroke
smooth smooth
frame_rate 5 frame_rate 5
the_color = [0.5, 0.7, 0.8]
@tree.setup :start_x => width/2, :start_y => height+20, :size => height/60, :color => the_color
draw_it draw_it
end end


def draw def draw

# Do nothing.
end end


def draw_the_background def draw_the_background
Expand All @@ -85,7 +85,7 @@ def draw_the_background
def draw_it def draw_it
Kernel::srand(@srand) if @srand Kernel::srand(@srand) if @srand
draw_the_background draw_the_background
@tree.render :seed @tree.render :seed, :start_x => width/2, :start_y => height+20, :size => height/60, :color => [0.7, 0.15, 0.8]
end end


def mouse_clicked def mouse_clicked
Expand Down
59 changes: 59 additions & 0 deletions samples/vine.rb
@@ -0,0 +1,59 @@
load_library 'context_free'

def setup_the_vine

@vine = ContextFree.define do

shrink = 0.961

rule :root do
split do
shoot :y => 1
rewind
shoot :rotation => 180
end
end

rule :shoot do
square
shoot :y => 0.98, :rotation => 5, :size => shrink + rand * 0.05, :brightness => 0.990
end

rule :shoot, 0.02 do
square
split do
shoot :rotation => 90
rewind
shoot :rotation => -90
end
end

end
end


def setup
size 700, 700
setup_the_vine
no_stroke
color_mode HSB, 1.0
smooth
draw_it
end


def draw
# Do nothing.
end


def draw_it
background 0.75, 1.0, 0.15
@vine.render :root, :size => height/75, :color => [0.75, 0.1, 0.9],
:start_x => width/2, :start_y => height/2
end


def mouse_clicked
draw_it
end

0 comments on commit 9f822bd

Please sign in to comment.