6 * $Date: 2012-07-06 15:04:28 +0200 (Fr, 06. Jul 2012) $
7 ***************************************************************/
10 * \brief Declaration of class LinearQuadtree.
12 * \author Martin Gronemann
15 * This file is part of the Open Graph Drawing Framework (OGDF).
19 * See README.txt in the root directory of the OGDF installation for details.
22 * This program is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU General Public License
24 * Version 2 or 3 as published by the Free Software Foundation;
25 * see the file LICENSE.txt included in the packaging of this file
29 * This program is distributed in the hope that it will be useful,
30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 * GNU General Public License for more details.
35 * You should have received a copy of the GNU General Public
36 * License along with this program; if not, write to the Free
37 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
38 * Boston, MA 02110-1301, USA.
40 * \see http://www.gnu.org/copyleft/gpl.html
41 ***************************************************************/
43 #ifndef OGDF_LINEAR_QUADTREE_H
44 #define OGDF_LINEAR_QUADTREE_H
46 #include "FastUtils.h"
47 #include "FMEFunctional.h"
49 #define M2L_MIN_BOUND 8
50 #define WSPD_BRANCH_BOUND 16
55 class LinearQuadtreeBuilder
;
60 friend class LinearQuadtreeBuilder
;
61 friend class LinearQuadtreeBuilderList
;
63 typedef unsigned int NodeID
;
64 typedef unsigned int PointID
;
66 struct LQPoint
// 16 byte
68 MortonNR mortonNr
; // 8 byte
69 __uint32 node
; // 4 byte
70 __uint32 ref
; // 4 byte
73 struct LQNode
// 27 byte
75 __uint32 level
; // 4 byte
76 NodeID next
; // 4 byte
77 NodeID child
[4]; // 4 byte *4 = 16 byte
78 __uint32 numChilds
; // 4 byte
79 PointID firstPoint
; // 4 byte
80 __uint32 numPoints
; // 4 byte
86 LQWSPair(NodeID c
, NodeID d
) : a(c
), b(d
) {};
91 struct is_fence_condition_functor
93 const LinearQuadtree
& tree
;
94 is_fence_condition_functor(const LinearQuadtree
& t
) : tree(t
) { }
95 inline bool operator()(NodeID u
) { return tree
.isFence(u
); }
99 inline is_fence_condition_functor
is_fence_condition() const { return is_fence_condition_functor(*this); }
102 struct is_leaf_condition_functor
104 const LinearQuadtree
& tree
;
105 is_leaf_condition_functor(const LinearQuadtree
& t
) : tree(t
) { }
106 inline bool operator()(NodeID u
) { return tree
.isLeaf(u
); }
110 inline is_leaf_condition_functor
is_leaf_condition() const { return is_leaf_condition_functor(*this); }
113 //! simple functor for iterating over all nodes
115 struct forall_tree_nodes_functor
117 const LinearQuadtree
& tree
;
122 forall_tree_nodes_functor(const LinearQuadtree
& t
, F f
, NodeID b
, __uint32 num
) : tree(t
), func(f
), begin(b
), numNodes(num
) { }
124 inline void operator()()
127 for (__uint32 i
=0; i
<numNodes
; i
++)
130 it
= tree
.nextNode(it
);
137 inline forall_tree_nodes_functor
<F
> forall_tree_nodes(F f
, NodeID begin
, __uint32 num
) const
139 return forall_tree_nodes_functor
<F
>(*this, f
, begin
, num
);
142 //! simple functor for iterating over all children of a node
144 struct forall_children_functor
146 const LinearQuadtree
& tree
;
149 forall_children_functor(const LinearQuadtree
& t
, F f
) : tree(t
), func(f
) { }
151 inline void operator()(NodeID u
)
153 if (tree
.isLeaf(u
)) return;
154 for (__uint32 i
= 0; i
< tree
.numberOfChilds(u
); i
++) func(tree
.child(u
, i
));
160 inline forall_children_functor
<F
> forall_children(F f
) const
162 return forall_children_functor
<F
>(*this, f
);
166 //! simple functor for iterating over all points of a node
167 template<typename Func
>
168 struct forall_points_functor
170 const LinearQuadtree
& tree
;
173 forall_points_functor(const LinearQuadtree
& t
, const Func
& f
) : tree(t
), func(f
) { }
175 inline void operator()(NodeID u
)
177 PointID firstPoint
= tree
.firstPoint(u
);
178 PointID end
= firstPoint
+ tree
.numberOfPoints(u
);
179 for (PointID i
= firstPoint
; i
< end
; i
++)
185 template<typename Func
>
186 inline forall_points_functor
<Func
> forall_points(const Func
& func
) const
188 return forall_points_functor
<Func
>(*this, func
);
191 //! functor for iterating over all ordered pairs of children of a node
193 struct forall_ordered_pairs_of_children_functor
195 const LinearQuadtree
& tree
;
198 forall_ordered_pairs_of_children_functor(const LinearQuadtree
& t
, F f
) : tree(t
), func(f
) { }
200 inline void operator()(NodeID u
)
202 if (tree
.isLeaf(u
)) return;
203 for (__uint32 i
= 0; i
< tree
.numberOfChilds(u
); i
++)
204 for (__uint32 j
= i
+1; j
< tree
.numberOfChilds(u
); j
++)
205 func(tree
.child(u
, i
), tree
.child(u
, j
));
211 inline forall_ordered_pairs_of_children_functor
<F
> forall_ordered_pairs_of_children(F f
) const
213 return forall_ordered_pairs_of_children_functor
<F
>(*this, f
);
216 //! top down traversal of the subtree of a given node
217 template<typename F
, typename CondType
= true_condition
>
218 struct top_down_traversal_functor
220 const LinearQuadtree
& tree
;
224 top_down_traversal_functor(const LinearQuadtree
& t
, F f
) : tree(t
), func(f
) { }
225 top_down_traversal_functor(const LinearQuadtree
& t
, F f
, CondType c
) : tree(t
), func(f
), cond(c
) { }
227 inline void operator()(NodeID u
)
229 if (cond(u
)) { func(u
); tree
.forall_children(*this)(u
); };
235 inline top_down_traversal_functor
<F
> top_down_traversal(F f
) const
237 return top_down_traversal_functor
<F
>(*this, f
);
241 template<typename F
, typename Cond
>
242 inline top_down_traversal_functor
<F
, Cond
> top_down_traversal(F f
, Cond cond
) const
244 return top_down_traversal_functor
<F
, Cond
>(*this, f
, cond
);
248 //! bottom up traversal of the subtree of a given node
249 template<typename F
, typename CondType
= true_condition
>
250 struct bottom_up_traversal_functor
252 const LinearQuadtree
& tree
;
256 bottom_up_traversal_functor(const LinearQuadtree
& t
, F f
) : tree(t
), func(f
) { }
257 bottom_up_traversal_functor(const LinearQuadtree
& t
, F f
, CondType c
) : tree(t
), func(f
), cond(c
) { }
259 inline void operator()(NodeID u
)
261 if (cond(u
)) { tree
.forall_children(*this)(u
); func(u
); };
267 inline bottom_up_traversal_functor
<F
> bottom_up_traversal(F f
) const
269 return bottom_up_traversal_functor
<F
>(*this, f
);
273 template<typename F
, typename Cond
>
274 inline bottom_up_traversal_functor
<F
, Cond
> bottom_up_traversal(F f
, Cond cond
) const
276 return bottom_up_traversal_functor
<F
, Cond
>(*this, f
, cond
);
280 template<typename WSPairFuncType
, typename DPairFuncType
, typename DNodeFuncType
, typename BranchCondType
= true_condition
>
283 const LinearQuadtree
& tree
;
284 WSPairFuncType WSFunction
;
285 DPairFuncType DPairFunction
;
286 DNodeFuncType DNodeFunction
;
287 BranchCondType BranchCondFunction
;
289 wspd_functor(const LinearQuadtree
& t
, WSPairFuncType
& wsf
, DPairFuncType
& dpf
, DNodeFuncType
& dnf
) : tree(t
), WSFunction(wsf
), DPairFunction(dpf
), DNodeFunction(dnf
) { }
291 wspd_functor(const LinearQuadtree
& t
, WSPairFuncType
& wsf
, DPairFuncType
& dpf
, DNodeFuncType
& dnf
, BranchCondType
& bc
) : tree(t
), WSFunction(wsf
), DPairFunction(dpf
), DNodeFunction(dnf
), BranchCondFunction(bc
) { }
293 inline void operator()(NodeID u
)
295 if (BranchCondFunction(u
))
297 if (tree
.isLeaf(u
) || (tree
.numberOfPoints(u
) <= WSPD_BOUND
))
299 if (tree
.numberOfPoints(u
) > 1)
303 tree
.forall_children(*this)(u
);
304 tree
.forall_ordered_pairs_of_children(*this)(u
);
310 inline void operator()(NodeID u
, NodeID v
)
314 if ((tree
.numberOfPoints(u
) < M2L_MIN_BOUND
) && (tree
.numberOfPoints(v
) < M2L_MIN_BOUND
))
321 if (((tree
.numberOfPoints(u
) <= WSPD_BRANCH_BOUND
) && (tree
.numberOfPoints(v
) <= WSPD_BRANCH_BOUND
)) ||
322 (tree
.isLeaf(u
) || tree
.isLeaf(v
)))
328 if (tree
.level(u
) >= tree
.level(v
))
329 tree
.forall_children(pair_call(*this, v
))(u
);
331 tree
.forall_children(pair_call(*this, u
))(v
);
337 template<typename A
, typename B
, typename C
, typename ConditionType
>
338 inline wspd_functor
<A
, B
, C
, ConditionType
> forall_well_separated_pairs(A a
, B b
, C c
, ConditionType cond
)
340 return wspd_functor
<A
, B
, C
, ConditionType
>(*this, a
, b
, c
, cond
);
343 template<typename A
, typename B
, typename C
>
344 inline wspd_functor
<A
, B
, C
> forall_well_separated_pairs(A a
, B b
, C c
)
346 return wspd_functor
<A
, B
, C
>(*this, a
, b
, c
);
349 struct StoreWSPairFunctor
351 LinearQuadtree
& tree
;
352 StoreWSPairFunctor(LinearQuadtree
& t
) : tree(t
) { }
353 inline void operator()(NodeID a
, NodeID b
) { tree
.addWSPD(a
, b
); }
356 StoreWSPairFunctor
inline StoreWSPairFunction() { return StoreWSPairFunctor(*this); }
359 struct StoreDirectPairFunctor
361 LinearQuadtree
& tree
;
362 StoreDirectPairFunctor(LinearQuadtree
& t
) : tree(t
) { }
363 inline void operator()(NodeID a
, NodeID b
) { tree
.addDirectPair(a
, b
); }
366 StoreDirectPairFunctor
inline StoreDirectPairFunction() { return StoreDirectPairFunctor(*this); }
369 struct StoreDirectNodeFunctor
371 LinearQuadtree
& tree
;
372 StoreDirectNodeFunctor(LinearQuadtree
& t
) : tree(t
) { }
373 inline void operator()(NodeID a
) { tree
.addDirect(a
); }
376 StoreDirectNodeFunctor
inline StoreDirectNodeFunction() { return StoreDirectNodeFunctor(*this); }
378 inline NodeID
level(NodeID node
) const
380 return m_tree
[node
].level
;
383 inline NodeID
nextNode(NodeID node
) const
385 return m_tree
[node
].next
;
388 inline void setNextNode(NodeID node
, NodeID next
)
390 m_tree
[node
].next
= next
;
393 inline void setLevel(NodeID node
, __uint32 level
)
395 m_tree
[node
].level
= level
;
398 inline PointID
firstPoint(NodeID node
) const
400 return m_tree
[node
].firstPoint
;
403 inline void setFirstPoint(NodeID node
, PointID firstPoint
)
405 m_tree
[node
].firstPoint
= firstPoint
;
408 inline LQPoint
& point(PointID pointID
)
410 return m_points
[pointID
];
413 inline const LQPoint
& point(PointID pointID
) const
415 return m_points
[pointID
];
418 inline MortonNR
mortonNr(PointID point
) const
420 return m_points
[point
].mortonNr
;
423 //! returns the number of children of node node. for an inner node this is 1..4 and
424 //! can be accessed by child(i). For a leaf the number of points in this leaf is returned
425 //! starting with point child(0)
426 inline __uint32
numberOfChilds(NodeID node
) const
428 return m_tree
[node
].numChilds
;
431 //! sets the number of children of a node
432 inline void setNumberOfChilds(NodeID node
, __uint32 numChilds
)
434 m_tree
[node
].numChilds
= numChilds
;
437 //! returns the i th child index of node node
438 inline NodeID
child(NodeID node
, __uint32 i
) const
440 return m_tree
[node
].child
[i
];
443 //! sets the i-th child index of node node
444 inline void setChild(NodeID node
, __uint32 i
, NodeID c
)
446 m_tree
[node
].child
[i
] = c
;
449 //! returns true if the given node index is a leaf
450 inline bool isLeaf(NodeID node
) const
452 return !m_tree
[node
].numChilds
;
455 //! sets the fence flag for node
456 inline bool isFence(NodeID node
) const
458 return m_tree
[node
].fence
;
461 //! returns the number of points contained in the subtree of node
462 inline __uint32
numberOfPoints(NodeID node
) const
464 return m_tree
[node
].numPoints
;
467 //! sets the number of nodes containted in node
468 inline void setNumberOfPoints(NodeID node
, __uint32 numPoints
)
470 m_tree
[node
].numPoints
= numPoints
;
473 //! returns the index of the root
474 inline NodeID
root() const
479 //! returns the number of points in this tree
480 inline __uint32
numberOfPoints() const
485 //! returns the number of nodes in this tree
486 inline __uint32
numberOfNodes() const
488 return m_numInnerNodes
+ m_numLeaves
;
491 //! the upper bound for a compressed quadtree (2*numPoints)
492 inline __uint32
maxNumberOfNodes() const
494 return m_maxNumNodes
;
500 //! constructor. required tree mem will be allocated
501 LinearQuadtree(__uint32 n
, float* origXPos
, float* origYPos
, float* origSize
);
503 //! destructor. tree mem will be released
504 ~LinearQuadtree(void);
506 __uint64
sizeInBytes() const;
508 inline NodeID
pointLeaf(PointID point
) const
510 return m_points
[point
].node
;
513 inline void setPointLeaf(PointID point
, NodeID leaf
)
515 m_points
[point
].node
= leaf
;
518 inline float pointX(PointID point
) const { return m_pointXPos
[point
]; }
520 inline float pointY(PointID point
) const { return m_pointYPos
[point
]; }
522 inline float pointSize(PointID point
) const { return m_pointSize
[point
]; }
524 inline float* pointX() const { return m_pointXPos
; }
526 inline float* pointY() const { return m_pointYPos
; }
528 inline float* pointSize() const { return m_pointSize
; }
530 inline float nodeX(NodeID node
) const { return m_nodeXPos
[node
]; }
532 inline void setNodeX(NodeID node
, float x
) { m_nodeXPos
[node
] = x
; }
534 inline float nodeY(NodeID node
) const { return m_nodeYPos
[node
]; }
536 inline void setNodeY(NodeID node
, float y
) { m_nodeYPos
[node
] = y
; }
538 inline float nodeSize(NodeID node
) const { return m_nodeSize
[node
]; }
540 inline void setNodeSize(NodeID node
, float size
) { m_nodeSize
[node
] = size
; }
542 void setPoint(PointID id
, float x
, float y
, __uint32 ref
)
546 m_points
[id
].ref
= ref
;
549 void updatePointPositionSize(PointID id
)
551 __uint32 ref
= m_points
[id
].ref
;
552 m_pointXPos
[id
] = m_origXPos
[ref
];
553 m_pointYPos
[id
] = m_origYPos
[ref
];
554 m_pointSize
[id
] = m_origSize
[ref
];
557 void setPoint(PointID id
, float x
, float y
, float r
, __uint32 ref
)
562 m_points
[id
].ref
= ref
;
565 void setPoint(PointID id
, float x
, float y
, float r
)
572 inline __uint32
refOfPoint(PointID id
) const
574 return m_points
[id
].ref
;
577 inline NodeID
nodeOfPoint(PointID id
) const
579 return m_points
[id
].node
;
582 inline void nodeFence(NodeID node
)
584 m_tree
[node
].fence
= true;
587 inline bool isWS(NodeID a
, NodeID b
) const
589 float s
= 0.00000001f
;
590 float dx
= nodeX(a
) - nodeX(b
);
591 float dy
= nodeY(a
) - nodeY(b
);
592 float d_sq
= dx
*dx
+dy
*dy
;
593 float l
= max(nodeSize(a
), nodeSize(b
));
594 return (d_sq
>(s
*0.5 + 1)*(s
*0.5 + 1)* 2 * l
* l
);
599 void computeWSPD(NodeID n
);
601 inline NodeID
firstInnerNode() const { return m_firstInner
; }
603 inline __uint32
numberOfInnerNodes() const { return m_numInnerNodes
; }
605 inline NodeID
firstLeaf() const { return m_firstLeaf
; }
607 inline __uint32
numberOfLeaves() const { return m_numLeaves
; }
610 __uint32
numberOfWSP() const { return m_numWSP
; }
612 __uint32
numberOfDirectPairs() const { return m_numNotWSP
; }
614 __uint32
numberOfDirectNodes() const { return m_numDirectNodes
; }
616 inline NodeID
directNode(__uint32 i
) const { return m_directNodes
[i
]; }
618 inline NodeID
directNodeA(__uint32 i
) const { return m_notWspd
[i
].a
; }
620 inline NodeID
directNodeB(__uint32 i
) const { return m_notWspd
[i
].b
; }
623 WSPD
* wspd() const{ return m_WSPD
; };
625 void init(float min_x
, float min_y
, float max_x
, float max_y
);
626 inline float minX() const { return m_min_x
; }
627 inline float minY() const { return m_min_y
; }
628 inline float maxX() const { return m_max_x
; }
629 inline float maxY() const { return m_max_y
; }
630 inline double scaleInv() const { return m_scaleInv
; }
633 inline void computeCoords(NodeID nodeIndex
)
636 __uint32 level
= this->level(nodeIndex
);
637 float s
= (float)(m_cellSize
* (1 << level
));
638 this->setNodeSize(nodeIndex
, s
);
639 MortonNR mnr
= this->mortonNr(this->firstPoint(nodeIndex
));
640 mnr
= mnr
>> (level
* 2);
641 mnr
= mnr
<< (level
* 2);
642 mortonNumberInv
<__uint64
, __uint32
>(mnr
, ix
, iy
);
643 this->setNodeX(nodeIndex
, (float)((m_sideLengthPoints
*((float)ix
)-0.5)/m_sideLengthGrid
+ (float)m_min_x
+ (float)s
*0.5f
));
644 this->setNodeY(nodeIndex
, (float)((m_sideLengthPoints
*((float)iy
)-0.5)/m_sideLengthGrid
+ (float)m_min_y
+ (float)s
*0.5f
));
647 LQPoint
* pointArray() { return m_points
; }
649 PointID
findFirstPointInCell(PointID somePointInCell
) const;
652 //! helper function for allocating the array's
653 void allocate(__uint32 n
);
655 //! helper function for releasing memory
658 inline void initLeaf(NodeID leaf
, PointID firstPoint
, __uint32 numPoints
, NodeID next
)
660 m_tree
[leaf
].numChilds
= 0;
661 m_tree
[leaf
].next
= next
;
662 m_tree
[leaf
].fence
= 0;
663 m_tree
[leaf
].level
= 0;
664 m_tree
[leaf
].firstPoint
= firstPoint
;
665 m_tree
[leaf
].numPoints
= numPoints
;
668 inline void initInnerNode(NodeID node
, NodeID leftChild
, NodeID rightChild
, __uint32 level
, NodeID next
)
670 m_tree
[node
].numChilds
= 2;
671 m_tree
[node
].child
[0] = leftChild
;
672 m_tree
[node
].child
[1] = rightChild
;
673 m_tree
[node
].next
= next
;
674 m_tree
[node
].fence
= 0;
675 m_tree
[node
].level
= level
;
676 m_tree
[node
].firstPoint
= leftChild
;
677 m_tree
[node
].numPoints
= rightChild
- leftChild
;
680 //! appends one child index. Assumes childCount < 4 and not leaf
681 inline void nodeAppendChild(NodeID node
, NodeID child
)
683 m_tree
[node
].child
[m_tree
[node
].numChilds
++] = child
;
684 m_tree
[node
].numPoints
+= m_tree
[child
].numPoints
;
687 //! appends an successing point by simply increasing childcount of a leaf. Assumes isLeaf
688 inline void leafAppendPoint(NodeID leaf
, PointID point
)
690 m_points
[point
].node
= leaf
;
691 m_tree
[leaf
].numPoints
++;
694 //! adds a well-separated pair to the wspd
695 void addWSPD(NodeID s
, NodeID t
);
697 //! add a direct pair to the array list of direct pairs
698 void addDirectPair(NodeID s
, NodeID t
);
700 //! add a direct node to the array list of direct nodes
701 void addDirect(NodeID s
);
703 //! the x coordinate of the left most point
706 //! the y coordinate of the bottom most point
709 //! the x coordinate of the right most point
712 //! the y coordinate of the top most point
715 //! the height and width of a grid cell
718 //! the inverse scale to transform
721 //! the maximum of height and width
722 double m_sideLengthPoints
;
724 //! the resulting side length of the grid (constant)
725 double m_sideLengthGrid
;
727 //! point x coord in graph order
730 //! point y coord in graph order
733 //! point size in graph order
736 //! point x coord in tree order
739 //! point y coord in tree order
742 //! point size in tree order
755 //! the main tree array containing all nodes (including leaves)
758 //! the maximum number of nodes (2*n here instead of 2*n-1)
759 __uint32 m_maxNumNodes
;
761 //! the point order in tree order
764 //! number of points this quadtree is based on
765 __uint32 m_numPoints
;
770 __uint32 m_numNotWSP
;
772 NodeID
* m_directNodes
;
773 __uint32 m_numDirectNodes
;
775 //! the wspd of this quadtree
778 //! the root of the tree
781 //! first leaf in the leaf chain
784 //! number of leaves in the chain
785 __uint32 m_numLeaves
;
787 //! first inner node in the inner node chain
790 //! number of inner nodes in the chain
791 __uint32 m_numInnerNodes
;
795 inline void swap(ogdf::LinearQuadtree::LQPoint
& b
, ogdf::LinearQuadtree::LQPoint
& a
)
797 ogdf::LinearQuadtree::LQPoint t
= a
;
802 inline bool LQPointComparer(const LinearQuadtree::LQPoint
& a
, const LinearQuadtree::LQPoint
& b
)
804 return a
.mortonNr
< b
.mortonNr
;
807 } // end of namespace ogdf