Draw a Tree in Processing
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 branch angle, len def trunk len
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
push_matrix
rotate angle
line 0 , 0 , len, 0
pop_matrix
end
line 0 , 0 , len, 0
translate len, 0
end
Making the tree a bit more complicated, creating one new function gave the following:-
def branch angle, len def terminal_branch angle, len def trunk len
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
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
push_matrix
rotate angle
line 0 , 0 , len* 0.8 , 0 # reduce length of terminal branch
pop_matrix
end
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:- load_library ' context_free ' def setup_the_tree rule :trunk , 1 do # rule has a probability weighting of 1 rule :branch do rule :scraggle do # without an explicit weighting rule :scraggle do def setup def draw_it
#################################################################
# 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)
#################################################################
@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
branch :size => 0.7 # giving an actual probability = 0.047619
end
split do # split is like a branch, rewind returns original context
trunk :rotation => 10
rewind
trunk :rotation => - 10
end
end
trunk :rotation => 5 # probability of each scraggle rule
end # is 0.5
trunk :rotation => - 5
end
end
end
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
@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.
Source: https://learning-ruby-processing.blogspot.com/2010/04/simple-tree-using-affine-transforms.html
0 Response to "Draw a Tree in Processing"
Post a Comment