#include <quad_tree.h>
A template CQuadTree.
This first implementation support real-time quad node split, but never merge the quad node. The possibility to merge (delete) empty quads, when an element erase occurs, will be added later.
The quadtree is geometrically delimited. By default, his size is 1*1, centered on (0,0,0). If an element which is out this zone is inserted, then it will ALWAYS be considered selected in select*() methods. By default, the quad tree is aligned on XZ.
Sample code using CQuadTree:
// My quad tree CQuadTree<myType> quadTree; // My min and max BoundingBox corner of each element CVector minPoint[elementCount]=...; CVector maxPoint[elementCount]=...; // My values myType value[elementCount]=...; // Init the quadTree with recursions depth = 6 (so max 64*64 cells) // centered in (0,0,0) with a max size of 10 in the plane XZ quadTree.create (6, CVector (0.f, 0.f, 0.f), 10.f); // Insert element in the quadTree for (int i=0; i<elementCount; i++) quadTree.insert (minPoint[i], maxPoint[i], value[i]); // [...] // Clear the selection quadTree.clearSelection (); // Select an element with the X axis as a 3d ray quadTree.selectRay (CVector (0,0,0), CVector (1,0,0)); // Get first selected nodes.. CQuadTree<myType>::CIterator it=quadTree.begin(); while (it!=quadTree.end()) { // Check what you want... // Next selected element it++; }
Definition at line 96 of file quad_tree.h.
Public Member Functions | |
CQuadTree () | |
Default constructor, use axes XZ. | |
~CQuadTree () | |
dtor. | |
Selection | |
CIterator | begin () |
void | clearSelection () |
CIterator | end () |
void | select (const std::vector< NLMISC::CPlane > &BVolume) |
void | select (const NLMISC::CVector &bboxmin, const NLMISC::CVector &bboxmax) |
void | selectAll () |
void | selectRay (const NLMISC::CVector &source, const NLMISC::CVector &dir) |
void | selectSegment (const NLMISC::CVector &source, const NLMISC::CVector &dest) |
Initialization | |
void | changeBase (const NLMISC::CMatrix &base) |
void | create (uint DepthMax, const NLMISC::CVector ¢er, float size) |
Container operation | |
void | clear () |
Clear the container. Elements are deleted, and the quadtree too (create() is undone). | |
void | erase (CIterator it) |
void | eraseAll () |
CIterator | insert (const NLMISC::CVector &bboxmin, const NLMISC::CVector &bboxmax, const T &val) |
Private Attributes | |
NLMISC::CMatrix | _ChangeBasis |
uint | _DepthMax |
CQuadNode | _QuadRoot |
CBaseNode | _Selection |
float | _Size |
Friends | |
class | CConstIterator |
class | CIterator |
|
Default constructor, use axes XZ.
Definition at line 658 of file quad_tree.h. References NL3D::CQuadTree< T >::_DepthMax, NL3D::CQuadTree< T >::_QuadRoot, NL3D::CQuadTree< T >::CQuadNode::BBoxMax, NL3D::CQuadTree< T >::CQuadNode::BBoxMin, NLMISC::CMatrix::identity(), NL3D::CQuadTree< T >::CBaseNode::Next, and NLMISC::CVector::set().
|
|
dtor.
|
|
Return the first iterator of the selected element list. begin and end are valid till the next insert. Definition at line 884 of file quad_tree.h. References NL3D::CQuadTree< T >::CBaseNode::Next. Referenced by NL3D::CQuadTree< T >::eraseAll().
00885 { 00886 return (CNode*)(_Selection.Next); 00887 } |
|
Change the base matrix of the quad tree. For exemple this code init the quad tree in the plane XY:
Definition at line 669 of file quad_tree.h.
00670 { 00671 _ChangeBasis=base; 00672 } |
|
Clear the container. Elements are deleted, and the quadtree too (create() is undone).
Definition at line 679 of file quad_tree.h. References NL3D::CQuadTree< T >::_QuadRoot, NL3D::CQuadTree< T >::CQuadNode::clear(), and NL3D::CQuadTree< T >::CBaseNode::Next. Referenced by NL3D::CQuadTree< T >::create().
00680 { 00681 _QuadRoot.clear(); 00682 _Selection.Next= NULL; 00683 } |
|
Clear the selection list Definition at line 775 of file quad_tree.h. References NL3D::CQuadTree< T >::CBaseNode::Next, and NL3D::CQuadTree< T >::CBaseNode::Prev. Referenced by NL3D::CQuadTree< T >::select(), and NL3D::CQuadTree< T >::selectAll().
00776 { 00777 CBaseNode *p; 00778 while(p=_Selection.Next) 00779 { 00780 // On retire ce noeud de la selection. Ce qui va modifier implicitement _Selection.Next. 00781 if(p->Prev) p->Prev->Next= p->Next; 00782 if(p->Next) p->Next->Prev= p->Prev; 00783 p->Prev=p->Next=NULL; 00784 } 00785 } |
|
Init the container
Definition at line 685 of file quad_tree.h. References NL3D::CQuadTree< T >::_DepthMax, NL3D::CQuadTree< T >::_QuadRoot, NL3D::CQuadTree< T >::CQuadNode::BBoxMax, NL3D::CQuadTree< T >::CQuadNode::BBoxMin, NL3D::CQuadTree< T >::clear(), size, and uint.
00686 { 00687 NLMISC::CVector mycenter=_ChangeBasis*center; 00688 clear(); 00689 _DepthMax= DepthMax; 00690 _Size= size; 00691 _QuadRoot.BBoxMin= mycenter-NLMISC::CVector(size/2, 0 , size/2); 00692 _QuadRoot.BBoxMax= mycenter+NLMISC::CVector(size/2, 0 , size/2); 00693 } |
|
Return the end iterator of the selected element list. begin and end are valid till the next insert. Definition at line 889 of file quad_tree.h. References NL3D::CQuadTree< T >::CIterator. Referenced by NL3D::CQuadTree< T >::eraseAll().
00890 { 00891 return CIterator(NULL); 00892 } |
|
Erase an interator from the container
Definition at line 723 of file quad_tree.h. References NL3D::CQuadTree< T >::const_iterator::_Ptr, and NL3D::CQuadTree< T >::CBaseNode::clear(). Referenced by NL3D::CQuadTree< T >::eraseAll().
00724 { 00725 CNode *p=it._Ptr; 00726 if(p) 00727 { 00728 // Clear links. 00729 p->clear(); 00730 00731 // delete it!! 00732 delete p; 00733 } 00734 } |
|
Erase all elements from the container Definition at line 704 of file quad_tree.h. References NL3D::CQuadTree< T >::begin(), NL3D::CQuadTree< T >::end(), NL3D::CQuadTree< T >::erase(), NL3D::CQuadTree< T >::selectAll(), and sint.
00705 { 00706 CIterator it; 00707 std::vector<CIterator> its; 00708 00709 // First, make a copy of all elements. 00710 selectAll(); 00711 for(it= begin();it!=end();it++) 00712 { 00713 its.push_back(it); 00714 } 00715 00716 // Then erase them. Must do it OUTSIDE the select loop. 00717 for(sint i=0;i<(sint)its.size();i++) 00718 { 00719 erase(its[i]); 00720 } 00721 } |
|
Insert a new element in the container. The bounding box of the element MUST be included in the bounding box of the quadtree.
Definition at line 736 of file quad_tree.h. References NL3D::CQuadTree< T >::_DepthMax, NL3D::CQuadTree< T >::_QuadRoot, NL3D::CQuadTree< T >::CIterator, NL3D::CQuadTree< T >::CQuadNode::insert(), nlassert, uint, NLMISC::CVector::x, NLMISC::CVector::y, and NLMISC::CVector::z.
00737 { 00738 NLMISC::CVector myboxmin2=_ChangeBasis*bboxmin; 00739 NLMISC::CVector myboxmax2=_ChangeBasis*bboxmax; 00740 NLMISC::CVector myboxmin (std::min (myboxmin2.x, myboxmax2.x), std::min (myboxmin2.y, myboxmax2.y), std::min (myboxmin2.z, myboxmax2.z)); 00741 NLMISC::CVector myboxmax (std::max (myboxmin2.x, myboxmax2.x), std::max (myboxmin2.y, myboxmax2.y), std::max (myboxmin2.z, myboxmax2.z)); 00742 00743 CNode *newNode=new CNode(val); 00744 00745 nlassert(myboxmax.x>=myboxmin.x); 00746 nlassert(myboxmax.y>=myboxmin.y); 00747 nlassert(myboxmax.z>=myboxmin.z); 00748 00749 float boxsize= std::max(myboxmax.x-myboxmin.x, myboxmax.z-myboxmin.z ); 00750 // Prevent float precision problems. Increase bbox size a little. 00751 boxsize*=1.01f; 00752 // We must find the level quad which is just bigger. 00753 float wantsize=_Size; 00754 uint wantdepth=0; 00755 while(boxsize<wantsize/2 && wantdepth<_DepthMax) 00756 { 00757 wantsize/=2; 00758 wantdepth++; 00759 } 00760 00761 _QuadRoot.insert(myboxmin, myboxmax, wantdepth, newNode); 00762 00763 return CIterator(newNode); 00764 } |
|
Select element with multiple planes. Intersect with a polytope convex made of planes. The normals of planes must be directed outwards the polytope.
Definition at line 804 of file quad_tree.h. References NL3D::CQuadTree< T >::_QuadRoot, NL3D::CQuadTree< T >::clearSelection(), and NL3D::CQuadTree< T >::CQuadNode::select().
00805 { 00806 std::vector<NLMISC::CPlane> BVolumeCopy; 00807 BVolumeCopy.resize (BVolume.size()); 00808 for (int i=0; i<(int)BVolumeCopy.size(); i++) 00809 { 00810 BVolumeCopy[i]=BVolume[i]*((_ChangeBasis).inverted()); 00811 } 00812 00813 clearSelection(); 00814 _QuadRoot.select(_Selection, BVolumeCopy); 00815 } |
|
Select element intersecting a bounding box
Definition at line 793 of file quad_tree.h. References NL3D::CQuadTree< T >::_QuadRoot, NL3D::CQuadTree< T >::clearSelection(), NL3D::CQuadTree< T >::CQuadNode::select(), NLMISC::CVector::x, NLMISC::CVector::y, and NLMISC::CVector::z. Referenced by NL3D::CQuadTree< T >::selectRay(), and NL3D::CQuadTree< T >::selectSegment().
00794 { 00795 NLMISC::CVector myboxmin2=_ChangeBasis*bboxmin; 00796 NLMISC::CVector myboxmax2=_ChangeBasis*bboxmax; 00797 NLMISC::CVector bboxminCopy (std::min (myboxmin2.x, myboxmax2.x), std::min (myboxmin2.y, myboxmax2.y), std::min (myboxmin2.z, myboxmax2.z)); 00798 NLMISC::CVector bboxmaxCopy (std::max (myboxmin2.x, myboxmax2.x), std::max (myboxmin2.y, myboxmax2.y), std::max (myboxmin2.z, myboxmax2.z)); 00799 00800 clearSelection(); 00801 _QuadRoot.select(_Selection, bboxminCopy, bboxmaxCopy); 00802 } |
|
Select all the container Definition at line 787 of file quad_tree.h. References NL3D::CQuadTree< T >::_QuadRoot, NL3D::CQuadTree< T >::clearSelection(), and NL3D::CQuadTree< T >::CQuadNode::selectAll(). Referenced by NL3D::CQuadTree< T >::eraseAll().
00788 { 00789 clearSelection(); 00790 _QuadRoot.selectAll(_Selection); 00791 } |
|
Select element with a ray
Definition at line 817 of file quad_tree.h. References NLMISC::CMatrix::getJ(), NLMISC::CMatrix::getK(), NLMISC::CMatrix::identity(), NLMISC::CPlane::make(), NLMISC::CMatrix::normalize(), NL3D::CQuadTree< T >::select(), and NLMISC::CMatrix::setRot().
00818 { 00819 NLMISC::CMatrix mat; 00820 mat.identity (); 00821 00822 // Set a wrong matrix 00823 NLMISC::CVector vTmp=dir^((fabs(vTmp*CVector(1,0,0))>0.f)?CVector(1,0,0):CVector(0,1,0)); 00824 mat.setRot (dir, vTmp, dir^vTmp); 00825 00826 // Normalize it Yoyo! 00827 mat.normalize (NLMISC::CMatrix::XYZ); 00828 00829 // Get the planes.. 00830 std::vector<NLMISC::CPlane> BVolume; 00831 BVolume.reserve (4); 00832 00833 // Setup the planes 00834 NLMISC::CPlane plane; 00835 plane.make (mat.getJ(), source); 00836 BVolume.push_back (plane); 00837 plane.make (mat.getK(), source); 00838 BVolume.push_back (plane); 00839 plane.make (-mat.getJ(), source); 00840 BVolume.push_back (plane); 00841 plane.make (-mat.getK(), source); 00842 BVolume.push_back (plane); 00843 00844 // Select the nodes 00845 select (BVolume); 00846 } |
|
Select element with a segment
Definition at line 848 of file quad_tree.h. References NLMISC::CMatrix::getI(), NLMISC::CMatrix::getJ(), NLMISC::CMatrix::getK(), NLMISC::CMatrix::identity(), NLMISC::CPlane::make(), NLMISC::CMatrix::normalize(), NL3D::CQuadTree< T >::select(), and NLMISC::CMatrix::setRot().
00849 { 00850 NLMISC::CMatrix mat; 00851 mat.identity (); 00852 00853 // Set a wrong matrix 00854 CVector dir=dest-source; 00855 NLMISC::CVector vTmp=dir^((fabs(vTmp*CVector(1,0,0))>0.f)?CVector(1,0,0):CVector(0,1,0)); 00856 mat.setRot (dir, vTmp, dir^vTmp); 00857 00858 // Normalize it Yoyo! 00859 mat.normalize (NLMISC::CMatrix::XYZ); 00860 00861 // Get the planes.. 00862 std::vector<NLMISC::CPlane> BVolume; 00863 BVolume.reserve (4); 00864 00865 // Setup the planes 00866 NLMISC::CPlane plane; 00867 plane.make (mat.getJ(), source); 00868 BVolume.push_back (plane); 00869 plane.make (mat.getK(), source); 00870 BVolume.push_back (plane); 00871 plane.make (-mat.getJ(), source); 00872 BVolume.push_back (plane); 00873 plane.make (-mat.getK(), source); 00874 BVolume.push_back (plane); 00875 plane.make (mat.getI(), dest); 00876 BVolume.push_back (plane); 00877 plane.make (-mat.getI(), source); 00878 BVolume.push_back (plane); 00879 00880 // Select the nodes 00881 select (BVolume); 00882 } |
|
Definition at line 105 of file quad_tree.h. |
|
Definition at line 102 of file quad_tree.h. Referenced by NL3D::CQuadTree< T >::end(), and NL3D::CQuadTree< T >::insert(). |
|
Definition at line 581 of file quad_tree.h. |
|
Definition at line 579 of file quad_tree.h. Referenced by NL3D::CQuadTree< T >::CQuadTree(), NL3D::CQuadTree< T >::create(), and NL3D::CQuadTree< T >::insert(). |
|
Definition at line 577 of file quad_tree.h. Referenced by NL3D::CQuadTree< T >::clear(), NL3D::CQuadTree< T >::CQuadTree(), NL3D::CQuadTree< T >::create(), NL3D::CQuadTree< T >::insert(), NL3D::CQuadTree< T >::select(), and NL3D::CQuadTree< T >::selectAll(). |
|
Definition at line 578 of file quad_tree.h. |
|
Definition at line 580 of file quad_tree.h. |