Tree
Define a tree --- both graphically and as a data structure.
In this sample, the motif is a single line\index{line}. The focus here
is more on the geometric layout and data structure and less
on the resulting pattern.
The motif transformation places two copies of the motif,
each starting at the end point of the original motif. The
copies are rotated by the parameter $rot$ and scaled by the parameter $scale$.
As for any recursive function, you need to make sure that
the recursion will stop. As in the prior sample, the
stopping condition is set by the depth of the recursion.
With the hindsight gained by seeing the recursion in
operation, we can gain a good idea of what this particular
function will produce under a variety of settings of the
parameters $rot$ and $scale$. With compound motifs and more
complex transformations, such intuitions completely
dissolve \ref{Carlson94}
A tree is a data structure\index{data structure!tree} that has branches. Each branch is
either null or itself a tree. The data structure produced
is sensitive to the details of the recursive
function. Usually, the preferred structure is one that
provides a *path* to each of the motifs that mirrors
the geometric structure. For example, a sensible path might
be one that starts with the root of the tree and that
records which branch of the tree is followed to reach the
motif. Thus, for a tree with depth $4$
(with the base motif at depth $0$), one
path to a node would be $tree[1][2][2][1]$. Interpret this as taking
the right branch on a $1$ and the left
branch on a $2$. The data structure is
thus a list where the $first$ item
in the list is the right branch of the tree and the $secon$ item in the list is the left
branch of the tree. The motif itself is must be stored
somewhere and is assigned to the $zeroth$ branch of the data
structure. So a path to a motif needs an index of $0$ at its end, for example, $tree[1][2][2][1][0]$.
\newpage
treeFn function (CoordinateSystem cs,
Line startLine,
int depth,
double rotation, double scale)
{
Line resultLine = {};
if (depth < 1){
resultLine[0] = null;
resultLine[1] = null;
}
else{
CoordinateSystem rightCS = new CoordinateSystem();
rightCS.ByOriginRotationAboutCoordinateSystem
(startLine.EndPoint,
cs,
rotation,
AxisOption.Y);
CoordinateSystem leftCS = new CoordinateSystem();
leftCS.ByOriginRotationAboutCoordinateSystem
(startLine.EndPoint,
cs,
-rotation,
AxisOption.Y);
Line rightLine = new Line();
rightLine.ByStartPointDirectionLength
(rightCS,
rightCS.ZDirection,
startLine.Length*scale);
Line leftLine = new Line();
leftLine.ByStartPointDirectionLength
(leftCS,
leftCS.ZDirection,
startLine.Length*scale);
resultLine[0]=treeFn(rightCS,
rightLine,
depth-1,
rotation,
scale);
resultLine[1]=treeFn(leftCS,
leftLine,
depth-1,
rotation,
scale);
}
resultLine[2]=startLine;
return resultLine;
};

Note the calls to the treeFn function. The two
separate calls ensure that the right and left branches of
the tree are themselves trees. The base case of the
recursion occurs when the depth is less than one and results
in a tree with null branches being returned. At the end of
the function, the motif is stored in the $second$ member of
resultLine, completing the data structure, which
now stored both the tree structure and all the motifs.
A word to the wise. Writing recursive functions so that they
return appropriate data structures is careful, error-prone
work. Doing it well is key to making effective use of the
results.
Click to download RecuTree.gct