Assuming we will be able to initialize the traversal algorithm, we focus first on how to do an efficient traversal. This traversal is conceptually simple, however the use of triangles complicates the indexing. For each cell entered, the microtriangle is generated. If it is hit, the traversal is over, if it is missed, the next cell must be determined and a new microtriangle generated. The new triangle will differ from the previous triangle by exactly one vertex. This means that for each step through the grid we need only evaluate the expensive displacement function once.
![]() |
A position in the grid
will be labeled by a triple,
, corresponding to the
lines of constant barycentric coordinates
. The indices sum to either
or
depending
upon whether the triangle is a lower triangle or an
upper triangle as shown in Figure 6. The
classification into lower and upper determines how the vertices are
generated given the indices. For a lower triangle, the barycentric
lines corresponding to indices are the edges of the triangle. For an
upper triangle, the barycentric lines corresponding to the indices
touch the triangle only at the vertices.
This is not as neat as other possible numbering schemes, however it
means that each triangle differs from its neighbors by one in exactly
one index.
![]() |
Each microtriangle is represented by three displaced points,
,
, and
, with the order chosen such that the ray is assumed
to have entered the cell passing through the side corresponding to
edge
![]()
![]()
.
The next cell to be tested can be marked based on which index will
change and if the index will be incremented or decremented. This flag
can be represented as
iplus, jminus,
kplus, iminus, jplus, kminus
, and depends upon the orientation of the
current triangle and which side of the cell the ray exits through. By
knowing how the ray entered the current cell, there are usually only two
options for how the ray leaves the cell. The exception for
when the ray exits through the face it enters is
handled by the initialization code and will be discussed later.
These options can be checked by seeing on which side of the line
determined by
![]()
![]()
![]()
(the far point and its normal) the ray
passes, as shown in Figure 7. If the
above list of choices is viewed as a ring, the next possible choice is
either the next flag in the ring, or the previous flag in the
ring.
The traversal can be terminated by checking if the
values
are the same as the stop cell
determined by the
initialization phase. We also terminate the traversal if the ray
exits the volume. The traversal loop can be expressed in pseudocode
as follows:
Comments: Brian Smits