boundaryMapA fast search mechanism to find visible elements in a document view In this page: |
In VGLViewer's boundaryMap package, BoundaryMap implements a fast lookup mechanism that stores BoundaryMapElements and allows fast retrieval of those which intersect a given Boundary. As you can see, a BoundaryMap is actually a binary hierarchy implemented using the Composite pattern. The creation of a BoundaryMap is described as follows. A root BoundaryMap is instantiated, then BoundaryMapElements are added to it individually with method putElement. Each BoundaryMap has a Boundary which starts out as inside-out. As each BoundaryMapElement is added to the root BoundaryMap, it is temporarily stored by the root, and the root's Boundary is expanded to enclose the BoundaryMapElement's Boundary. When all BoundaryMapElements are added to the root, the root's Boundary will enclose all of them. Generation of the hierarchy is lazy: the first time we subsequently call getElements on the root BoundaryMap to get BoundaryMapElements intersecting a given Boundary, the root builds a binary sub-hierarchy of BoundaryMaps. The root does this by iterating through the temporarily-stored BoundaryMapElements and inserting then into itself.
INSERT(element : BoundaryMapElement, map : BoundaryMap, axis : INTEGER)
BEGIN
VAR
a, b : Boundary
1. IF element does not intersect map's boundary THEN RETURN
2. IF (axis = 0) THEN
2.1 set a andb to each half of map's boundary, split on X-axis
ELSE
2.2 set a and b to each half of map's boundary split on Y-axis
3. IF element fits inside a THEN
3.1 IF left child of map does not yet exist THEN
3.1.1 create new left child of map, with boundary a
3.2 CALL INSERT(element, left child, (axis+1) MOD 1) /* alternate axis */
3.2.1 RETURN
4. IF element fits inside b THEN
4.1 IF right child of map does not yet exist THEN
4.1.1 create new right child of map, with boundary b
4.2 CALL INSERT(element, right child, (axis+1) MOD 1) /* alternate axis */
4.2.1 RETURN
5. IF element is able to split itself THEN
5.1 Split element about dividing line between a and b, yeilding lists leftFragments and rightFragments
5.2 IF left child of map does not yet exist THEN
5.2.1 create new left child of map, with boundary a
5.3 WITH EACH leftElement in leftElements DO
5.3.1 CALL INSERT(leftElement, left child, (axis+1) MOD 1) /* alternate axis */
5.4 IF right child of map does not yet exist THEN
5.4.1 create new right child of map, with boundary b
5.5 WITH EACH rightElement in rightElements DO
5.5.1 CALL INSERT(rightElement, right child, (axis+1) MOD 1) /* alternate axis */
6. ELSE store element in map
6.1 RETURN
END.
We start with the BoundaryMap root by calling, for each BoundaryMapElement element temporarily stored at it, the pseudo code INSERT(element, root, 0) operation. The last argument, for parameter axis, has a value of 0 to specify the X-axis. Points to note about this algorithm are:
Now we have a binary boundary hierarchy that has at worst, for most elements, a time complexity in the order of log(N) for finding intersectors of a given Boundary. Animated Documents |




Post new comment