Geometric Data Structures for Computer Graphics2006
Authors: Langetepe E. Zachmann G.
Published year: 2005
Pages: 48-49/69
Buy this book on amazon.com >>

8.2. Static Segment Tree

This is a quick recap, so if you are familiar with this classic data structure, you can proceed to the next section.

Given a set S ={ s 1 , , s n } of intervals s i = [ a i , b i ] image from book , and a query point q ˆˆ image from book , we are looking for the subset S ={ s ˆˆ S q ˆˆ s }. This is often called a stabbing query and can be extended trivially to image from book d .

Before describing the data structure, we define an elementary interval (EI). Let X = { a, b a ˆˆ s ˆˆ S, b ˆˆ s ˆˆ S } = { x i } denote the set of endpoints , sorted by increasing value in a list. Then the interval [ x i , x i +1 ) is called an EI. For convenience, we also include the intervals ( ˆ ˆ , x ) and [ x 2 n , ˆ ).

The segment tree is a balanced binary tree over the set of EIs, X . Each leaf i stores one EI Int( i ) := [ x i , x i +1 ). We define the interval of an inner node as Int( ) := Int( 1 ) ˆ Int( 2 ), where 1 , 2 are the two children of . Each node stores the so-called canonical subset S ( ) := { s ˆˆ S Int( ) s, Int(parent( )) image from book s} (in other words, each interval s ˆˆ S is stored with several nodes k in the tree, such that image from book k Int( k ) = s , and such that s is stored as high up as possible). An example is shown in Figure 8.1.

image from book
Figure 8.1: Example of a segment tree.

Algorithm 8.2: Simple algorithm for answering a stabbing query.

image from book


query(






, q




)


output

S

(




)

if





is inner node

then


if


q



Int(





1

)

then

query(





1


, q

)

else

query(





2


, q

)

end if


end if

image from book
 

The construction of a segment tree is very easy: generate and sort X ; construct a skeleton binary tree over 2 n + 1 nodes; compute Int( ) for all nodes in the tree; and sift each segment s top-down through the tree.

The algorithm for answering a stabbing query is quite simple, as shown in Algorithm 8.2.

It is easy to see that such a segment tree needs O ( n log n ) space and O ( n log n ) construction time, and that a query can be answered in time O (log n + k ), where k is the size of the output.

8.3. Kinetic Segment Tree

By turning the static segment tree into a kinetic one, we are moving one step closer to our final goal of a kinetic BSP [de Berg et al. 01].

Now segments (i.e., intervals on image from book ) can move freely they can swap positions , they can shorten or lengthen, etc. Observe, however, that the situation is not as difficult as it might seem, because of the following:

  1. During the construction of the static segment tree, we never really needed to know the exact values of the endpoints of the intervals; it was completely sufficient to know their position in the sorted list of all endpoints;

  2. For each segment s , there is a certain amount image from book > 0 by which we can move s without invalidating the segment tree;

  3. Whatever the position of a certain number segments, the skeleton of the segment tree is always the same. The only thing that changes is the labeling of the nodes with segment IDs.

These observations give rise to the following modifications of the original segment tree data structure:

  • Segments are defined as s i := ( a i , b i ) , a i ,B i ˆˆ image from book , 1 a i , b i 2 n . a i , b i are called the rank of the endpoints;

  • An array R [1 , , 2 n ] stores the current values of the endpoints (so the interval for s i is given by image from book , image from book ). This array is kept sorted by value;

  • With each segment s , we maintain a fragment list image from book ( s ) := { s ˆˆ S ( )}. image from book is kept sorted from left to right;

  • For each elementary interval [ i, i + 1], we store a pointer to its associated leaf i .

The certificates in this KDS are Z i := R i < R i +1 , i = 1 , , 2 n ˆ 1. The proof remains valid until two endpoints swap position in array R . In that case, exactly two certificates are affected. The ranks of all other interval endpoints remain the same, so they are associated with the same nodes in the tree (in other words, their fragment lists remain the same).

Let s be one of the two intervals affected by an endpoint swap. [1] There are four possible cases for which endpoints have swapped and how. Consider the one where before s = [ i, j ] and after the swap s = [ i, j + 1] (and analogously for the other segment).

The nave update algorithm would just delete both segments from all nodes (with the help of array image from book ), and then sift them top-down through the tree. This would yield an O (log n ) complexity.

But we can do better. The idea is to augment the segment s = [ i, j ] by just the EI [ j, j + 1], and then just update the tree starting with j , which is the leaf for [ j, j + 1], and which is now covered by s , too. The pseudocode shown in Algorithm 8.3 gives more details.

Algorithm 8.3: Updating a kinetic segment tree.

image from book
1:












j


{leaf of [

j, j

+ 1]}
2:

repeat

3:






sibling of




4:

if


s




S

(




)

then

5:                    delete

s

from

S

(




)
6:






parent(




)
7:

end if

8:

until


s


image from book


S

(




)
9: insert

s

into

S

(




)
image from book
 

Analogously, we can traverse the segment tree bottom-up in order to augment the other segment by an EI. Note that the test in Step 4 is necessarily false if is a left child.

The running time of Algorithm 8.3 is O ( h ), where h is the height of the node that gets s attached, i.e., [ j, j + 1] ˆˆ Int( ) and s ˆˆ S ( ) (after the update). This is made possible by the array image from book , which allows us to perform Step 4 in Algorithm 8.3 in time O (1). When starting with the leaf of the EI, we just need to inspect the front/back of image from book , and then we work our way through image from book .

Lemma 8.1. Let S be a set of n moving segments on the real line image from book . There is a kinetic segment tree with O ( n log n ) space, which can be updated in expected time O (1) when an event occurs (i.e., two endpoints swap position). The worst-case time is still O (log n ) . The KDS is local and efficient.

Locality and efficiency are given, since any segment participates in at most four certificates, and there are no internal events. The O (1) time bound can be proven fairly easily by showing that the average height in a balanced tree is O (1).

Figure 8.2 shows an example how the labeling changes as a result of an event.

image from book
Figure 8.2: An example of a segment tree over four segments. The dashed segments show the segments 4 and 2, respectively, after two of their endpoints have swapped position. The changes in the tree are highlighted with dashed boxes.

[1] We omit the case where both endpoints belong to the same interval, as this is fairly easy to deal with.

Geometric Data Structures for Computer Graphics2006
Authors: Langetepe E. Zachmann G.
Published year: 2005
Pages: 48-49/69
Buy this book on amazon.com >>