so small, however, that it goes beyond the range of how MEL calcu-
lates decimals and gets rounded off to 0:
print vec[1]
7.2.17 Returning to the tree() Procedure
The first argument ($vec) is the point of the rotation. The second
$x_axis and $z_axis) is the axis of rotation. The third (deg_to_
) is the angle of rotation that will occur. The rot
command requires radian values, which is why the deg_to_rad
command must be used.
// STEP 3: Translate the vector up the y-axis by branch
// length units
vector $x_axis = <<1,0,0>>;
vector $y_axis = <<0,1,0>>;
vector $z_axis = <<0,0,1>>;
$vec = $vec + <<0, $branchLen, 0>>;
// STEP 4: Rotate the vector by the branch angle
// to find the end of a branch
// STEP 5: Draw a line between the base ($base) of the branch
// and the (relative) end of the branch.
// To do this, we will need to compute the angles needed to
// rotate a vector to align to the y-axis in such a way
// that it aims along a particular vector
// - in this case, the growth direction ($growthDir).
// The aimY procedure was written for this purpose
float $angle[2] = aimY($growthDir);
$vec = rot($vec, $x_axis, deg_to_rad($angle[0]));
$vec = rot($vec, $z_axis, deg_to_rad($angle[1]));
$vec = <<($vec.x), ($vec.y), ($vec.z)>>;
// Locate the end of the branch relative to the
Chapter 7
// base of the branch.
vector $end1 = $base + $vec;
Draw the first curve using the calculated values as arguments for
-point flags:
// STEP 6: Draw a curve that represents the first branch
curve -degree 1
-point ($base.x) ($base.y) ($base.z)
-point ($end1.x) ($end1.y) ($end1.z);
Continue to create the reflected branch and perform recursions to
generate the rest of the limbs:
// STEP 7: Recurse to the next branch
tree($depth - 1, $end1, $vec, $branchAngle, $branchLen * 0.6);
// Finding the second branch:
// STEP 1: Define the second branch as if it were a
// reflection of the first branch, first about the $growthDir
// vector
// The reflect procedure was written for this purpose.
$vec = reflect(-$vec, $growthDir);
$vec = <<($vec.x), ($vec.y), ($vec.z)>>;
// STEP 2: Locate the end of the branch relative to the
// base of the branch.
vector $end2 = $base + $vec;
// STEP 3: Draw the curve segment that represents
// the second branch.
curve -degree 1
-point ($base.x) ($base.y) ($base.z)
-point ($end2.x) ($end2.y) ($end2.z);
// STEP 4: Recurse to the next branch
tree($depth - 1, $end2, $vec, $branchAngle, $branchLen * 0.6);
To test out the script, enter the block of code that follows. When this
many arguments need to be passed it can be easier to store the val-
ues in variables and pass the variables for the arguments.
Chapter 7
Keep in mind the usages of the arguments:
$depth: This is the depth of the recursion and essentially how
complex the tree will be. More recursions mean more branches.
$base: This is the position where the tree will start. For exam-
ple, <<0,0,0>> would be the center of the world.
$growthDir: This is the direction in which the branches will
grow, which is the argument of the aimY() procedure.
$branchAngle: This value controls the spread of the branching,
similar to the cone angle of a spotlight.
$branchLen: This value controls the overall length of the
recurring branches.
vector $begin = <<0,0,0>>;
vector $dir = <<0,1,0>>;
float $spread = 15;
float $len = 2;
tree(7, $begin, $dir, $ spread, $len);
This is when you pop a cigar in your mouth, walk to the nearest
beach, squat down, and say: “I love the smell of recursion in the
morning. Smells like… victory.”
Chapter 7
Figure 7-43

Get Professional MEL Solutions for Production now with O’Reilly online learning.

O’Reilly members experience live online training, plus books, videos, and digital content from 200+ publishers.