G4KDTree Class Reference

#include <G4KDTree.hh>


Public Member Functions

 G4KDTree (int dim=3)
virtual ~G4KDTree ()
void Clear ()
int GetDim ()
void SetDataDestructor (void(*fDestr)(void *))
int GetNbNodes ()
G4KDNodeGetRoot ()
G4KDNodeInsert (const double *pos, void *data)
G4KDNodeInsert (const double &x, const double &y, const double &z, void *data)
G4KDTreeResultHandle Nearest (const double *pos)
G4KDTreeResultHandle Nearest (const double &x, const double &y, const double &z)
G4KDTreeResultHandle Nearest (G4KDNode *node)
G4KDTreeResultHandle NearestInRange (const double *pos, const double &range)
G4KDTreeResultHandle NearestInRange (const double &x, const double &y, const double &z, const double &range)
G4KDTreeResultHandle NearestInRange (G4KDNode *node, const double &range)

Protected Member Functions

void __Clear_Rec (G4KDNode *node)
int __NearestInRange (G4KDNode *node, const double *pos, const double &range_sq, const double &range, G4KDTreeResult &list, int ordered, G4KDNode *source_node=0)
void __NearestToPosition (G4KDNode *node, const double *pos, G4KDNode *&result, double *result_dist_sq, struct HyperRect *fRect)
void __NearestToNode (G4KDNode *source_node, G4KDNode *node, const double *pos, std::vector< G4KDNode * > &result, double *result_dist_sq, struct HyperRect *fRect, int &nbresult)

Protected Attributes

G4KDNodefRoot

Friends

class G4KDNode


Detailed Description

G4KDTree is used by the ITManager to locate the neareast neighbours. A kdtree sorts out node in such a way that it reduces the number of node check. The results of this search can be retrieved by G4KDTreeResultHandle.

Definition at line 60 of file G4KDTree.hh.


Constructor & Destructor Documentation

G4KDTree::G4KDTree ( int  dim = 3  ) 

Definition at line 169 of file G4KDTree.cc.

References fRoot.

00170 {
00171     fDim = k;
00172     fRoot = 0;
00173     fDestr = 0;
00174     fRect = 0;
00175     fNbNodes = 0;
00176 }

G4KDTree::~G4KDTree (  )  [virtual]

Definition at line 178 of file G4KDTree.cc.

References __Clear_Rec(), and fRoot.

00179 {
00180     if(fRoot) __Clear_Rec(fRoot);
00181     fRoot = 0;
00182 
00183     if (fRect)
00184     {
00185         delete fRect;
00186         fRect = 0;
00187     }
00188 }


Member Function Documentation

void G4KDTree::__Clear_Rec ( G4KDNode node  )  [protected]

Definition at line 203 of file G4KDTree.cc.

References G4KDNode::GetData(), G4KDNode::GetLeft(), G4KDNode::GetRight(), and G4KDNode::SetData().

Referenced by Clear(), and ~G4KDTree().

00204 {
00205     if(!node) return;
00206 
00207     if(node->GetLeft())  __Clear_Rec(node->GetLeft());
00208     if(node->GetRight()) __Clear_Rec(node->GetRight());
00209 
00210     if(fDestr)
00211     {
00212         if(node->GetData())
00213         {
00214             fDestr(node->GetData());
00215             node->SetData(0);
00216         }
00217     }
00218     delete node;
00219 }

int G4KDTree::__NearestInRange ( G4KDNode node,
const double *  pos,
const double &  range_sq,
const double &  range,
G4KDTreeResult list,
int  ordered,
G4KDNode source_node = 0 
) [protected]

Definition at line 261 of file G4KDTree.cc.

References DBL_MAX, G4KDNode::GetAxis(), GetData(), G4KDNode::GetLeft(), G4KDNode::GetPosition(), G4KDNode::GetRight(), G4KDTreeResult::Insert(), and sqr().

Referenced by NearestInRange().

00263 {
00264     if(!node) return 0;
00265 
00266     double dist_sq(DBL_MAX), dx(DBL_MAX);
00267     int ret(-1), added_res(0);
00268 
00269     if(node-> GetData() && node != source_node)
00270     {
00271         bool do_break = false ;
00272         dist_sq = 0;
00273         for(int i=0; i<fDim; i++)
00274         {
00275             dist_sq += sqr(node->GetPosition()[i] - pos[i]);
00276             if(dist_sq > range_sq)
00277             {
00278                 do_break = true;
00279                 break;
00280             }
00281         }
00282         if(!do_break && dist_sq <= range_sq)
00283         {
00284             list.Insert(dist_sq, node);
00285             added_res = 1;
00286         }
00287     }
00288 
00289     dx = pos[node->GetAxis()] - node->GetPosition()[node->GetAxis()];
00290 
00291     ret = __NearestInRange(dx <= 0.0 ? node->GetLeft() : node->GetRight(), pos, range_sq, range, list, ordered, source_node);
00292     if(ret >= 0 && fabs(dx) <= range)
00293     {
00294         added_res += ret;
00295         ret = __NearestInRange(dx <= 0.0 ? node->GetRight() : node->GetLeft(), pos, range_sq, range, list, ordered, source_node);
00296     }
00297 
00298     if(ret == -1)
00299     {
00300         return -1;
00301     }
00302     added_res += ret;
00303 
00304     return added_res;
00305 }

void G4KDTree::__NearestToNode ( G4KDNode source_node,
G4KDNode node,
const double *  pos,
std::vector< G4KDNode * > &  result,
double *  result_dist_sq,
struct HyperRect fRect,
int &  nbresult 
) [protected]

Definition at line 420 of file G4KDTree.cc.

References HyperRect::CompareDistSqr(), G4KDNode::GetAxis(), G4KDNode::GetData(), G4KDNode::GetLeft(), HyperRect::GetMax(), HyperRect::GetMin(), G4KDNode::GetPosition(), G4KDNode::GetRight(), and sqr().

Referenced by Nearest().

00423 {
00424     int dir = node->GetAxis();
00425     double dummy, dist_sq;
00426     G4KDNode *nearer_subtree (0), *farther_subtree (0);
00427     double *nearer_hyperrect_coord (0), *farther_hyperrect_coord (0);
00428 
00429     /* Decide whether to go left or right in the tree */
00430     dummy = pos[dir] - node->GetPosition()[dir];
00431     if (dummy <= 0)
00432     {
00433         nearer_subtree = node->GetLeft();
00434         farther_subtree = node->GetRight();
00435         nearer_hyperrect_coord = rect->GetMax() + dir;
00436         farther_hyperrect_coord = rect->GetMin() + dir;
00437     }
00438     else
00439     {
00440         nearer_subtree = node->GetRight();
00441         farther_subtree = node->GetLeft();
00442         nearer_hyperrect_coord = rect->GetMin() + dir;
00443         farther_hyperrect_coord = rect->GetMax() + dir;
00444     }
00445 
00446     if (nearer_subtree)
00447     {
00448         /* Slice the hyperrect to get the hyperrect of the nearer subtree */
00449         dummy = *nearer_hyperrect_coord;
00450         *nearer_hyperrect_coord = node->GetPosition()[dir];
00451         /* Recurse down into nearer subtree */
00452         __NearestToNode(source_node, nearer_subtree, pos, result, result_dist_sq, rect, nbresult);
00453         /* Undo the slice */
00454         *nearer_hyperrect_coord = dummy;
00455     }
00456 
00457     /* Check the distance of the point at the current node, compare it
00458      * with our best so far */
00459     if(node->GetData() && node != source_node)
00460     {
00461         dist_sq = 0;
00462         bool do_break = false;
00463         for(int i=0; i < fDim; i++)
00464         {
00465             dist_sq += sqr(node->GetPosition()[i] - pos[i]);
00466             if(dist_sq > *result_dist_sq)
00467             {
00468                 do_break = true;
00469                 break ;
00470             }
00471         }
00472         if(!do_break)
00473         {
00474             if (dist_sq < *result_dist_sq)
00475             {
00476                 result.clear();
00477                 nbresult = 1 ;
00478                 result.push_back(node);
00479                 *result_dist_sq = dist_sq;
00480             }
00481             else if(dist_sq == *result_dist_sq)
00482             {
00483                 result.push_back(node);
00484                 nbresult++;
00485             }
00486         }
00487     }
00488 
00489     if (farther_subtree)
00490     {
00491         /* Get the hyperrect of the farther subtree */
00492         dummy = *farther_hyperrect_coord;
00493         *farther_hyperrect_coord = node->GetPosition()[dir];
00494         /* Check if we have to recurse down by calculating the closest
00495          * point of the hyperrect and see if it's closer than our
00496          * minimum distance in result_dist_sq. */
00497         //        if (hyperrect_dist_sq(rect, pos) < *result_dist_sq)
00498         if (rect->CompareDistSqr(pos,result_dist_sq))
00499         {
00500             /* Recurse down into farther subtree */
00501             __NearestToNode(source_node, farther_subtree, pos, result, result_dist_sq, rect, nbresult);
00502         }
00503         /* Undo the slice on the hyperrect */
00504         *farther_hyperrect_coord = dummy;
00505     }
00506 }

void G4KDTree::__NearestToPosition ( G4KDNode node,
const double *  pos,
G4KDNode *&  result,
double *  result_dist_sq,
struct HyperRect fRect 
) [protected]

Definition at line 308 of file G4KDTree.cc.

References HyperRect::CompareDistSqr(), G4KDNode::GetAxis(), G4KDNode::GetData(), G4KDNode::GetLeft(), HyperRect::GetMax(), HyperRect::GetMin(), G4KDNode::GetPosition(), G4KDNode::GetRight(), and sqr().

Referenced by Nearest().

00310 {
00311     int dir = node->GetAxis();
00312     int i;
00313     double dummy(0.), dist_sq(-1.);
00314     G4KDNode *nearer_subtree(0), *farther_subtree (0);
00315     double *nearer_hyperrect_coord(0),*farther_hyperrect_coord(0);
00316 
00317     /* Decide whether to go left or right in the tree */
00318     dummy = pos[dir] - node->GetPosition()[dir];
00319     if (dummy <= 0)
00320     {
00321         nearer_subtree = node->GetLeft();
00322         farther_subtree = node->GetRight();
00323 
00324         nearer_hyperrect_coord = rect->GetMax() + dir;
00325         farther_hyperrect_coord = rect->GetMin() + dir;
00326     }
00327     else
00328     {
00329         nearer_subtree = node->GetRight();
00330         farther_subtree = node->GetLeft();
00331         nearer_hyperrect_coord = rect->GetMin() + dir;
00332         farther_hyperrect_coord = rect->GetMax() + dir;
00333     }
00334 
00335     if (nearer_subtree)
00336     {
00337         /* Slice the hyperrect to get the hyperrect of the nearer subtree */
00338         dummy = *nearer_hyperrect_coord;
00339         *nearer_hyperrect_coord = node->GetPosition()[dir];
00340         /* Recurse down into nearer subtree */
00341         __NearestToPosition(nearer_subtree, pos, result, result_dist_sq, rect);
00342         /* Undo the slice */
00343         *nearer_hyperrect_coord = dummy;
00344     }
00345 
00346     /* Check the distance of the point at the current node, compare it
00347      * with our best so far */
00348     if(node->GetData())
00349     {
00350         dist_sq = 0;
00351         bool do_break = false ;
00352         for(i=0; i < fDim; i++)
00353         {
00354             dist_sq += sqr(node->GetPosition()[i] - pos[i]);
00355             if(dist_sq > *result_dist_sq)
00356             {
00357                 do_break = true;
00358                 break ;
00359             }
00360         }
00361         if (!do_break && dist_sq < *result_dist_sq)
00362         {
00363             result = node;
00364             *result_dist_sq = dist_sq;
00365         }
00366     }
00367 
00368     if (farther_subtree)
00369     {
00370         /* Get the hyperrect of the farther subtree */
00371         dummy = *farther_hyperrect_coord;
00372         *farther_hyperrect_coord = node->GetPosition()[dir];
00373         /* Check if we have to recurse down by calculating the closest
00374          * point of the hyperrect and see if it's closer than our
00375          * minimum distance in result_dist_sq. */
00376         if (rect->CompareDistSqr(pos,result_dist_sq))
00377         {
00378             /* Recurse down into farther subtree */
00379             __NearestToPosition(farther_subtree, pos, result, result_dist_sq, rect);
00380         }
00381         /* Undo the slice on the hyperrect */
00382         *farther_hyperrect_coord = dummy;
00383     }
00384 }

void G4KDTree::Clear (  ) 

Definition at line 190 of file G4KDTree.cc.

References __Clear_Rec(), and fRoot.

00191 {
00192     __Clear_Rec(fRoot);
00193     fRoot = 0;
00194     fNbNodes = 0;
00195 
00196     if (fRect)
00197     {
00198         delete fRect;
00199         fRect = 0;
00200     }
00201 }

int G4KDTree::GetDim (  )  [inline]

Definition at line 136 of file G4KDTree.hh.

References HyperRect::fDim.

Referenced by G4KDNode::GetDim(), and G4KDTreeResult::GetItem().

00137 {
00138     return fDim ;
00139 }

int G4KDTree::GetNbNodes (  )  [inline]

Definition at line 80 of file G4KDTree.hh.

00080 { return fNbNodes;  }

G4KDNode* G4KDTree::GetRoot (  )  [inline]

Definition at line 81 of file G4KDTree.hh.

References fRoot.

00081 { return fRoot ;    }

G4KDNode * G4KDTree::Insert ( const double &  x,
const double &  y,
const double &  z,
void *  data 
)

Definition at line 251 of file G4KDTree.cc.

References Insert().

00252 {
00253     double buf[3];
00254     buf[0] = x;
00255     buf[1] = y;
00256     buf[2] = z;
00257     return Insert(buf, data);
00258 }

G4KDNode * G4KDTree::Insert ( const double *  pos,
void *  data 
)

Definition at line 221 of file G4KDTree.cc.

References HyperRect::Extend(), fRoot, G4KDNode, and G4KDNode::Insert().

Referenced by Insert().

00222 {
00223     G4KDNode* node = 0 ;
00224     if(!fRoot)
00225     {
00226         fRoot =  new G4KDNode(this,pos,data,0, 0);
00227         node = fRoot;
00228         fNbNodes = 0;
00229         fNbNodes++;
00230     }
00231     else
00232     {
00233         if((node=fRoot->Insert(pos, data)))
00234         {
00235             fNbNodes++;
00236         }
00237     }
00238 
00239     if (fRect == 0)
00240     {
00241         fRect = new HyperRect(fDim,pos,pos);
00242     }
00243     else
00244     {
00245         fRect->Extend(pos);
00246     }
00247 
00248     return node;
00249 }

G4KDTreeResultHandle G4KDTree::Nearest ( G4KDNode node  ) 

Definition at line 508 of file G4KDTree.cc.

References __NearestToNode(), DBL_MAX, fRoot, G4cout, G4endl, and G4KDNode::GetPosition().

00509 {
00510 //    G4cout << "Nearest(node)" << G4endl ;
00511     if (!fRect)
00512     {
00513         G4cout << "Tree empty" << G4endl ;
00514         return 0;
00515     }
00516 
00517     const double* pos = node->GetPosition();
00518     std::vector<G4KDNode*> result;
00519     double dist_sq = DBL_MAX;
00520 
00521     /* Duplicate the bounding hyperrectangle, we will work on the copy */
00522     HyperRect *newrect = new HyperRect(*fRect);
00523 
00524     /* Search for the nearest neighbour recursively */
00525     int nbresult = 0 ;
00526 
00527     __NearestToNode(node, fRoot, pos, result, &dist_sq, newrect, nbresult);
00528 
00529     /* Free the copy of the hyperrect */
00530     delete newrect;
00531 
00532     /* Store the result */
00533     if (!result.empty())
00534     {
00535         G4KDTreeResultHandle rset(new G4KDTreeResult(this));
00536         int j = 0 ;
00537         while (j<nbresult)
00538         {
00539             rset->Insert(dist_sq, result[j]);
00540             j++;
00541         }
00542         rset->Rewind();
00543 
00544         return rset;
00545     }
00546     else
00547     {
00548         return 0;
00549     }
00550 }

G4KDTreeResultHandle G4KDTree::Nearest ( const double &  x,
const double &  y,
const double &  z 
)

Definition at line 552 of file G4KDTree.cc.

References Nearest().

00553 {
00554     double pos[3];
00555     pos[0] = x;
00556     pos[1] = y;
00557     pos[2] = z;
00558     return Nearest(pos);
00559 }

G4KDTreeResultHandle G4KDTree::Nearest ( const double *  pos  ) 

Definition at line 386 of file G4KDTree.cc.

References __NearestToPosition(), DBL_MAX, and fRoot.

Referenced by Nearest().

00387 {
00388 //    G4cout << "Nearest(pos)" << G4endl ;
00389 
00390     if (!fRect) return 0;
00391 
00392     G4KDNode *result(0);
00393     double dist_sq = DBL_MAX;
00394 
00395     /* Duplicate the bounding hyperrectangle, we will work on the copy */
00396     HyperRect *newrect = new HyperRect(*fRect);
00397 
00398     /* Our first guesstimate is the root node */
00399     /* Search for the nearest neighbour recursively */
00400     __NearestToPosition(fRoot, pos, result, &dist_sq, newrect);
00401 
00402     /* Free the copy of the hyperrect */
00403     delete newrect;
00404 
00405     /* Store the result */
00406     if (result)
00407     {
00408         G4KDTreeResultHandle rset = new G4KDTreeResult(this);
00409         rset->Insert(dist_sq, result);
00410         rset -> Rewind();
00411         return rset;
00412     }
00413     else
00414     {
00415         return 0;
00416     }
00417 }

G4KDTreeResultHandle G4KDTree::NearestInRange ( G4KDNode node,
const double &  range 
)

Definition at line 590 of file G4KDTree.cc.

References __NearestInRange(), fRoot, G4KDNode::GetPosition(), and sqr().

00591 {
00592     if(!node) return 0 ;
00593     int ret(-1);
00594 
00595     G4KDTreeResult *rset = new G4KDTreeResult(this);
00596 
00597     const double range_sq = sqr(range) ;
00598 
00599     if((ret = __NearestInRange(fRoot, node->GetPosition(), range_sq, range, *rset, 0, node)) == -1)
00600     {
00601         delete rset;
00602         return 0;
00603     }
00604     rset->Sort();
00605     rset->Rewind();
00606     return rset;
00607 }

G4KDTreeResultHandle G4KDTree::NearestInRange ( const double &  x,
const double &  y,
const double &  z,
const double &  range 
)

Definition at line 578 of file G4KDTree.cc.

References NearestInRange().

00582 {
00583     double buf[3];
00584     buf[0] = x;
00585     buf[1] = y;
00586     buf[2] = z;
00587     return NearestInRange(buf, range);
00588 }

G4KDTreeResultHandle G4KDTree::NearestInRange ( const double *  pos,
const double &  range 
)

Definition at line 561 of file G4KDTree.cc.

References __NearestInRange(), fRoot, and sqr().

Referenced by NearestInRange().

00562 {
00563     int ret(-1);
00564 
00565     const double range_sq = sqr(range) ;
00566 
00567     G4KDTreeResultHandle rset = new G4KDTreeResult(this);
00568     if((ret = __NearestInRange(fRoot, pos, range_sq, range, *(rset()), 0)) == -1)
00569     {
00570         rset = 0;
00571         return rset;
00572     }
00573     rset->Sort();
00574     rset->Rewind();
00575     return rset;
00576 }

void G4KDTree::SetDataDestructor ( void(*)(void *)  fDestr  )  [inline]

Definition at line 141 of file G4KDTree.hh.

00142 {
00143     fDestr = fct;
00144 }


Friends And Related Function Documentation

friend class G4KDNode [friend]

Definition at line 62 of file G4KDTree.hh.

Referenced by Insert().


Field Documentation

G4KDNode* G4KDTree::fRoot [protected]

Definition at line 69 of file G4KDTree.hh.

Referenced by Clear(), G4KDTree(), GetRoot(), Insert(), Nearest(), NearestInRange(), and ~G4KDTree().


The documentation for this class was generated from the following files:
Generated on Mon May 27 17:52:21 2013 for Geant4 by  doxygen 1.4.7