Coordinate system trees and object hierarchies by sdaferv


									COMP 557 lecture 12                                                                                                   Oct. 7, 2008

Coordinate system trees and object hierarchies
The concept of object hierarchies has come up a few times in the course. It arose when we discussed
various coordinate systems and how they are related to each other.1 For example, an object such as
a person might be defined by a set of parts that are defined with respect to a common coordinate
system. It also arose in the context of efficient ray casting, where we defined a hierarchy of scene
objects and their parts, each of which might have its own bounding box.
    Take the case of a person hierarchy. Various coordinate systems might be defined here, some of
which are shown in the figure below on the left. Transformations between these coordinate systems
are arranged into a tree, sketched on the right. The black nodes indicate coordinate systems. The
(downward) edges indicate transformations between coordinate systems, namely from parent to
child. To draw the person, you draw the parts.
    For example, consider how to draw points on the hand. They would be defined in a coordinate
system that is centered on the wrist. The points on the hand in the wrist coordinate system would
have to be transformed to camera coordinates. This would be done by transforming from wrist
coordinates to person coordinates (the torso coordinates are treated as “person coordinates”)

           Mtorso←wrist = Mtorso←shoulder Mshoulder←elbow Melbow←wrist = T1 R1 T2 R2 T3 R3

and then the person coordinates would have to be transformed to camera coordinates.


                        torso                                                                                               shoulder
                                              shoulder                                   hips
       camera                                                                                                   shoulder

                                                                                                hip joint                      elbow
                                                                     wrist   hip joint
                                                         elbow                                               elbow
                world                                                                                               wrist      wrist
                                hips                                              leg    leg
                                                                                                             hand           hand

    The figure on the right is a sketch of the tree-like structure which relates the various coordinate
systems. A similar tree could be used for any articulated object such as a person, tree or flower,
car, etc.
    In OpenGL, object parts are drawn by traversing the tree. Each branch from parent to child
involves a change in coordinates, typically done with a glRotate and/or glTranslate operation.
Object parts are drawn during the traversal. For example, upper arm is drawn within the shoulder
coordinate system.
    Traversing from parent to child involves a change in the MODELVIEW matrix. If a node has multiple
children below it that correspond to different coordinate systems, then one saves the MODELVIEW
matrix by pushing it on a stack before traversing to each of the children2 . As you have discovered
    This was part of the class discussion in an earlier lecture, but not part of the official lecture notes.
    since, otherwise, the only way to return the MODELVIEW matrix to its current value would be to apply an
inverse of the glRotate or glTranslate – but OpenGL doesn’t do that

COMP 557 lecture 12                                                                           Oct. 7, 2008

with your reading and with the code from Assignment 1, OpenGL has functions glPushMatrix()
and glPopMatrix for pushing and popping the MODELVIEW matrix.
   If we represent the drawing with commands D, and we represent the pushing and popping with
brackets [,], then we can express the sequence of OpenGL commands for drawing a person Dperson
roughly as follows:

              Dtorso [TRDhead ] [TR Dleftleg ][TR Drightleg ][TR Dleftarm] [TR Drightarm ]

   Notice that the draw commands D hide all the details. These commands are function calls. The
head, for example, will generally be a complex object consisting of many parts.

Let’s think of OpenGL program as a string of symbols that represent commands3 , including MOD-
ELVIEW transformations, pushing and popping, and drawing (e.g. glVertex). In the above
example, symbols such as D were placeholders for other sequences of commands – drawing the head
could involve specifying many vertices, and might involve drawing separate parts such as the ears
and eyes, and may involve coordinate transforms as well. To fully specify the program, we would
need to replace each D command by its specific string.
    This idea of replacing strings recursively will be familiar to most of you. It is reminiscent of
formal grammars that are used to define programming languages. 4 . Here we not interested in
characterizing and/or parsing such strings, but rather we are interested only in generating such
    We briefly consider the formalism of L-systems which are named after their inventor Astrid
Lindemayer, who was interested in growth and form of biological structures, in particular, plants.
The idea is that the parts of a plant (stems, leaves, flowers, branches, etc) at any given time can be
described using a tree structure. As the plant grows over time, some parts grow, some parts create
new parts, some parts die.
    In its most basic form, an L-system is defined by a set of symbols (alphabet) A, a special symbol
a ∈ A called an axiom or starting symbol, and a set of production rules

                                                 P : A → A∗

where A∗ is the set of strings over A, which may include the empty string. A production p ∈ P is
where χ ∈ A∗ . If no production is explicitly specified for a symbol a, then we assume the identity
    L-systems are similar to formal grammars that you learn about in COMP 330. The difference
is that with L-systems the productions are applied to each symbol in the string in parallel. With
formal grammars, only one production is applied at each step (and the ordering in which productions
are applied is often important for the analysis).
      we ignore loops here
      and those of you who have taken COMP 302 or 330 should be familiar with such grammars

COMP 557 lecture 12                                                                       Oct. 7, 2008

Example 1: Koch curve
In lecture 10, I discussed several fractal objects, in particular, the Koch curve. These objects
were defined recursively, as a limit, using a production in which each line segment is replaced by a
sequence of smaller line segments. At any depth d, the object – which is an approximation to the
Koch curve – can be drawn using OpenGL commands, namely a sequence of translations, rotations,
scalings, and glVertex commands, etc.
    Let L refer to the drawing of a unit line, and T a unit translation in the x direction. Let S be
scaling by a factor 3 . Let R+ be a rotation by 60 degrees clockwise and let R− be a rotation 60
degrees counterclockwise. The first step of approximating a Koch curve is just to draw a line of
length 1, so the string is just L. In the second step, the string L is replaced by the production,

                                 L → [SLTR+ LTR− R− LTR+ LT]

In the third step, each occurence of L in the second step is replaced by the same production, etc.
You can do the same thing with the Sierpinski carpet and the other fractals we discussed.
    Note that this recursion, as written, doesn’t terminate. Later this lecture we will see how to
terminate such recursions using parametric L systems.

Example 2: tree
Consider the two productions:

                                 p1 : X → D[R+ X]D[R− X]R+ X
                                 p2 : D → DD

where D draws a unit length straight line in the y direction and translates by a distance 1 in the y
direction (so we don’t explicitly include the translate symbol), and R+ and R− are rotations by 20
degrees in the clockwise and counter-clockwise directions, respectively.
    As with the Koch curve, the above production define an infinite recursion. If we stop the
recursion after a certain number of steps, then you need to say what to do with the X symbols. For
the moment, let’s just suppose that we use a production

                                           p3   :   X → D.

Later in the lecture we will see how it is possible to extend the definition of L-systems to allow two
productions to the same left side.
    Shown below are four stages of the tree. (I have not included then zeroth stage, in which there
is a single vertical line.) I also have shrunk the tree at stage i by a factor 2−i , in order to present
the trees side by side. To undo this shrinking we need to rescale by the factor shown beneath each
    This example was taken from the book “The Algorithmic Beauty of Plants” by Przemyslaw
Prusinkiewicz and Astrid Lindemayer. The book was published in 1990 and is now out of print, but
it is available online at Other similar examples
can be found in Chapter 1 (p. 25) of that book.

COMP 557 lecture 12                                                                   Oct. 7, 2008

                                      ×2                  ×4                  ×8

Example 3: probabilistic L-systems
Many variations of L-systems have been invented to give them more power. For example, suppose
one has more than one production with the identical symbol on the left side. One can define
a probability for each of these productions, such that the probabilities sum to 1. For example,
suppose the first branch of the above L-system could branch clockwise or counterclockwise with
probabilitities 0.4 and 0.6, respecitively. Then we could write the productions as:

                                    p1 : X → D[R+ X] : 0.4
                                    p2 : X → D[R− X] : 0.6

Notice that we have increased the notation to specify the probabilities.

Example 4: parametric L-systems
Another variation is that the symbols can have parameters associated with them. Since the symbols
are basically just functions calls, these parameters would act just as function parameters. Here we
will be more explicit about stopping the recursion.
    For example, here is an L-system that produces a vertically growing plant, such that you get a
pair of unit length branches coming off the main vertical axis. These branch pairs occur every unit

                         p1 : X(n) : n > 1 → D[R+ D][R− D]X(n − 1)
                         p2 : X(n) : n = 0 → D

   A slightly more interesting L-system would put a leaf L at the end of each branch, and would
put a little flower F at the top of the plant when the recursion terminates.

                        p1 : X(n) : n > 1 → D[R+ DL][R− DL]X(n − 1)
                        p2 : X(n) : n = 0 → F

COMP 557 lecture 12                                                                             Oct. 7, 2008

   Parametric L-systems allow for delays to be built into the system. A certain production might
occur only after a delay of t time steps.
                                           X(n) : n > 0 → X(n − 1)
                                           X(n) : n = 0 → ....
where ..... indicates the production that you should do once the counter has decreased to zero.

Context sensitive L-systems
The L-systems we have seen up to now are “context free” in that each production is applied based
on looking at an individual symbol only (and possibly a probability). “Context sensitive” L-systems
allow for more general choice of productions. The general form is:
id:     lc   < pred > rc :        cond   ----->     succ     :   prob
which means that the production id is defined by replacing a predecessor symbol pred by a successor
symbol succ if the symbol on the left of the predecessor is lc and the symbol on the right of the
predecessor is rc and the condition cond holds.
   For example,
                         w    :   A(1)B(3)A(5)
                         p1   :   A(x) → A(x + 1) : 0.4
                         p2   :   A(x) → B(x − 1) : 0.6
                         p3   :   A(x) < B(y) > A(z) : y < 4 → B(x + z)[A(y)]
      For example, we might have the following:
                                   A(1)B(3)A(5) → A(2)B(6)[A(3)]B(4)

Open L-systems
Another powerful technique is to allow the productions to depend on global variables. This allows
plants to interact with each other and with the environment. For example, suppose we consider the
roots of a plant growing into the ground. We could define a 2D array5 water(x,y) that represents
the amount of water at each point in the soil. As the roots grow, the plant absorbs water from
the soil. At each time step, a root growth production could occur if there is a sufficient amount of
water present in the grid cell closest to the tip of the root. Moreover, as the root grows, it could
decrease the amount of water in that grid cell.6
    Another idea, similar to what you will explore in Assignment 2, is to allow a branches to grow
only if they receive a sufficient amount of light from the sky. At each time step, you could cast a
set of rays toward the sky and count the percentage of rays that do not intersect branches or leaves
above. If the number of rays that “reach the sky” is sufficiently large, then you could allow the
growth production to occur; otherwise, not.
    In Assignment 2, you will do something slightly simpler which is to choose the brightness (color)
of a leaf to be proportional to the percentage of cast rays that reach the sky.
    or 3D array if we are in 3D
    For examples, see Radomir Mech and Przemyslaw Prusinkiewicz. Visual models of plants interacting with their
environment. Proceedings of SIGGRAPH 96, pp. 397-410.


To top