Another query on the discourse was how can I draw a line of fixed length, but with a random angle, someone else came up with standard cos(theta)*x, sin(theta)*y solution (that I usually favour), so I gave this as alternative, or at least a pointer to it. I also pointed out that truly random a angle would be a bad idea, but I neglected to point out the upside-down coordinate system in processing.
def setup
size(300, 300)
length = 70
stroke_weight 3
translate(width/2, height - 20)
rotate(-PI/2)
line(0, 0, length, 0)
translate(length, 0)
push_matrix
rotate(PI/4)
line(0, 0, length, 0)
pop_matrix
push_matrix
rotate(-PI/4)
line(0, 0, length, 0)
pop_matrix
line(0, 0, length, 0)
translate(length, 0)
push_matrix
rotate(PI/4)
line(0, 0, length, 0)
pop_matrix
push_matrix
rotate(-PI/4)
line(0, 0, length, 0)
pop_matrix
line(0, 0, length, 0)
end
Then I thought it would be a bit of fun to develop a kind of tree tutorial, so moving from this very procedural approach I thought the least I could do would be to extract a couple of functions. One to produce a trunk element and another to produce a branch element:-
def setup
size(300, 300)
length = 70
stroke_weight 3
translate(width/2, height - 20)
rotate(-PI/2)
trunk length
branch PI/4, length
branch -PI/4, length
trunk length
length *= 0.8 # reduce length
branch PI/4, length
branch -PI/4, length
trunk length
end
def branch angle, len
push_matrix
rotate angle
line 0, 0, len, 0
pop_matrix
end
def trunk len
line 0, 0, len, 0
translate len, 0
end
Making the tree a bit more complicated, creating one new function gave the following:-
def setup
size(300, 300)
length = 70
stroke_weight 3
translate(width/2, height - 20)
rotate(-PI/2)
trunk length
branch PI/4, length
branch -PI/4, length
length *= 0.9 # reduce overall length
branch 0, length
trunk length
branch 0, length
save_frame "tree3.png"
end
def branch angle, len
push_matrix
rotate angle
trunk len
angle = PI/4 if angle == 0 # then vertical branch element
terminal_branch angle, len
terminal_branch -angle, len
trunk len
pop_matrix
end
def terminal_branch angle, len
push_matrix
rotate angle
line 0, 0, len*0.8, 0 # reduce length of terminal branch
pop_matrix
end
def trunk len
line 0, 0, len, 0
translate len, 0
end
Now there has got to be easier way to do this and there are several. One way is to use LSystems to describe the tree, and another is to use recursion like in context free art.
Here are some context free rules (by curran) run with the c++ program cfdg with variation set to JIQ
rule tree 20 {
CIRCLE{ size 0.25 }
scraggle { y 0.1 }
}
rule scraggle {
tree { rotate 5 }
}
rule scraggle {
tree { rotate -5 }
}
rule tree 1 {
branch { size 0.7}
}
rule branch {
tree { rotate -10 }
tree { rotate 10 }
}
Here are the cfdg rules above translated to run as ruby-processing context-free DSL script:-
#################################################################
# A non deterministic sketch run it until you get a result you like
# uncomment "srand 5" to get a more deterministic result. It looked
# pretty good on my linux box (however I'm not sure how universal the
# random seeding is in jruby)
#################################################################
load_library 'context_free'
def setup_the_tree
@tree = ContextFree.define do
rule :trunk, 20 do # rule has a probability weighting of 20
circle :size => 0.25, :brightness => 0 # giving an actual probability = 0.952381
scraggle :y => -0.1 # the minus is require by the upside down coordinate system
end
rule :trunk, 1 do # rule has a probability weighting of 1
branch :size => 0.7 # giving an actual probability = 0.047619
end
rule :branch do
split do # split is like a branch, rewind returns original context
trunk :rotation => 10
rewind
trunk :rotation => -10
end
end
rule :scraggle do # without an explicit weighting
trunk :rotation => 5 # probability of each scraggle rule
end # is 0.5
rule :scraggle do
trunk :rotation => -5
end
end
end
def setup
size 600, 600
# srand 5
smooth
setup_the_tree
background 255 # NB color mode here is "RGB 255", within context free definition
draw_it # the color mode is "HSB 1.0", supports :hue, :saturation, :brightness
end
def draw_it
@tree.render :trunk,
:start_x => width/2, :start_y => height * 0.9,
:size => height/18
end
Follow this link to see an LSystem tree implementation
Context free programs run with multiple definitions of a rule are non-deterministic, so it is quite usual to get different results each time the program is run.
Experiments with ruby-processing (processing-2.2.1) and JRubyArt for processing-3.0
Saturday, 17 April 2010
Subscribe to:
Post Comments (Atom)
Followers
Blog Archive
-
▼
2010
(73)
-
▼
April
(10)
- Using the Voronoi library in ruby processing
- Moire patterns from custom bar shape Context free DSL
- Faux barcode using ruby-processing Context Free DSL
- Adding a custom terminal in ruby-processing contex...
- How to Draw a Tree in Processing
- Terse Code to use file chooser in Ruby Processing
- Another funky random sketch with perlin noise
- An Translation Exercise (Very Clever Pseudo 3D Ani...
- Live Editing Ruby-Processing from jEdit
- Plasma fractal (and carpet)
-
▼
April
(10)
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
No comments:
Post a Comment