diff --git a/CDT/include/CDT.hpp b/CDT/include/CDT.hpp index 563296cf..7ccadf7a 100644 --- a/CDT/include/CDT.hpp +++ b/CDT/include/CDT.hpp @@ -184,10 +184,7 @@ void Triangulation::eraseTrianglesAtIndices( template void Triangulation::initializedWithCustomSuperGeometry() { - for(std::size_t i = 0; i < vertices.size(); ++i) - { - m_nearPtLocator.addPoint(VertInd(i), vertices); - } + m_nearPtLocator.initialize(vertices); m_nTargetVerts = vertices.size(); m_superGeomType = SuperGeometryType::Custom; } @@ -416,10 +413,7 @@ void Triangulation::addSuperTriangle(const Box2d& box) {VertInd(0), VertInd(1), VertInd(2)}, {noNeighbor, noNeighbor, noNeighbor}}; addTriangle(superTri); - - m_nearPtLocator.addPoint(VertInd(0), vertices); - m_nearPtLocator.addPoint(VertInd(1), vertices); - m_nearPtLocator.addPoint(VertInd(2), vertices); + m_nearPtLocator.initialize(vertices); } template diff --git a/CDT/include/KDTree.h b/CDT/include/KDTree.h index f84cf677..b39e982e 100644 --- a/CDT/include/KDTree.h +++ b/CDT/include/KDTree.h @@ -91,6 +91,17 @@ class KDTree m_root = addNewNode(); } + /// Constructor with bounding box known in advance + KDTree(const point_type& min, const point_type& max) + : m_rootDir(NodeSplitDirection::X) + , m_min(min) + , m_max(max) + , m_isRootBoxInitialized(true) + , m_tasksStack(InitialStackDepth, NearestTask()) + { + m_root = addNewNode(); + } + /// Insert a point into kd-tree /// @note external point-buffer is used to reduce kd-tree's memory footprint /// @param iPoint index of point in external point-buffer @@ -333,6 +344,19 @@ class KDTree m_max = point_type::make( std::max(m_max.x, p.x), std::max(m_max.y, p.y)); } + // Make sure bounding box does not have a zero size by adding padding: + // zero-size bounding box cannot be extended properly + const TCoordType padding(1); + if(m_min.x == m_max.x) + { + m_min.x -= padding; + m_max.x += padding; + } + if(m_min.y == m_max.y) + { + m_min.y -= padding; + m_max.y += padding; + } m_isRootBoxInitialized = true; } @@ -372,4 +396,4 @@ class KDTree } // namespace KDTree -#endif // header guard \ No newline at end of file +#endif // header guard diff --git a/CDT/include/LocatorKDTree.h b/CDT/include/LocatorKDTree.h index f128b54e..5227ec05 100644 --- a/CDT/include/LocatorKDTree.h +++ b/CDT/include/LocatorKDTree.h @@ -25,7 +25,25 @@ template < class LocatorKDTree { public: - /// Add point to R-tree + /// Initialize KD-tree with points + void initialize(const std::vector >& points) + { + typedef V2d V2d_t; + V2d_t min = points.front(); + V2d_t max = min; + typedef typename std::vector::const_iterator Cit; + for(Cit it = points.begin(); it != points.end(); ++it) + { + min = V2d_t::make(std::min(min.x, it->x), std::min(min.y, it->y)); + max = V2d_t::make(std::max(max.x, it->x), std::max(max.y, it->y)); + } + m_kdTree = KDTree_t(min, max); + for(VertInd i = 0; i < points.size(); ++i) + { + m_kdTree.insert(i, points); + } + } + /// Add point to KD-tree void addPoint(const VertInd i, const std::vector >& points) { m_kdTree.insert(i, points); @@ -39,12 +57,13 @@ class LocatorKDTree } private: - KDTree::KDTree< + typedef KDTree::KDTree< TCoordType, NumVerticesInLeaf, InitialStackDepth, StackDepthIncrement> - m_kdTree; + KDTree_t; + KDTree_t m_kdTree; }; } // namespace CDT