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

cheeksacto1948.blogspot.com

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

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel