#ifndef __HV_KDTREE_HPP #define __HV_KDTREE_HPP #include #include "config.hpp" #include "bqueue.hpp" namespace CosmoTool { template struct KDDef { typedef CType CoordType; typedef float KDCoordinates[N]; }; template struct KDCell { bool active; ValType val; typename KDDef::KDCoordinates coord; }; class NotEnoughCells: public Exception { public: NotEnoughCells() : Exception() {} ~NotEnoughCells() throw () {} }; template struct KDTreeNode { KDCell *value; KDTreeNode *children[2]; typename KDDef::KDCoordinates minBound, maxBound; #ifdef __KD_TREE_NUMNODES uint32_t numNodes; #endif }; template class RecursionInfoCells { public: typename KDDef::KDCoordinates x; typename KDDef::CoordType r, r2; KDCell **cells; typename KDDef::CoordType *distances; uint32_t currentRank; uint32_t numCells; }; template class RecursionMultipleInfo { public: const typename KDDef::KDCoordinates& x; BoundedQueue< KDCell *, typename KDDef::CoordType> queue; int traversed; RecursionMultipleInfo(const typename KDDef::KDCoordinates& rx, KDCell **cells, uint32_t numCells) : x(rx), queue(cells, numCells, INFINITY),traversed(0) { } }; template class KDTree { public: typedef typename KDDef::CoordType CoordType; typedef typename KDDef::KDCoordinates coords; typedef KDCell Cell; typedef KDTreeNode Node; KDTree(Cell *cells, uint32_t Ncells); ~KDTree(); uint32_t getIntersection(const coords& x, CoordType r, Cell **cells, uint32_t numCells) throw (NotEnoughCells); uint32_t getIntersection(const coords& x, CoordType r, Cell **cells, CoordType *distances, uint32_t numCells) throw (NotEnoughCells); Cell *getNearestNeighbour(const coords& x); void getNearestNeighbours(const coords& x, uint32_t NumCells, Cell **cells); void getNearestNeighbours(const coords& x, uint32_t NumCells, Cell **cells, CoordType *distances); Node *getRoot() { return root; } void optimize(); Node *getAllNodes() { return nodes; } uint32_t getNumNodes() const { return lastNode; } uint32_t countActives() const; #ifdef __KD_TREE_NUMNODES uint32_t getNumberInNode(const Node *n) const { return n->numNodes; } #else uint32_t getNumberInNode(const Node *n) const { if (n == 0) return 0; return 1+getNumberInNode(n->children[0])+getNumberInNode(n->children[1]); } #endif protected: Node *nodes; uint32_t numNodes; uint32_t lastNode; Node *root; Cell **sortingHelper; Node *buildTree(Cell **cell0, uint32_t NumCells, uint32_t depth, coords minBound, coords maxBound); void recursiveIntersectionCells(RecursionInfoCells& info, Node *node, int level) throw (NotEnoughCells); CoordType computeDistance(const Cell *cell, const coords& x) const; void recursiveNearest(Node *node, int level, const coords& x, CoordType& R2, Cell*& cell); void recursiveMultipleNearest(RecursionMultipleInfo& info, Node *node, int level); }; template uint32_t gatherActiveCells(KDCell **cells, uint32_t numCells); }; #include "mykdtree.tcc" #endif