Skip to content

Commit

Permalink
#79 Fix KDTree to handle zero-size bounding box
Browse files Browse the repository at this point in the history
And use pre-calculated bounding box for initialization of KD-tree of super-geometry
  • Loading branch information
artem-ogre committed Apr 26, 2022
1 parent 0ddf2d6 commit cda399c
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 12 deletions.
10 changes: 2 additions & 8 deletions CDT/include/CDT.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,10 +184,7 @@ void Triangulation<T, TNearPointLocator>::eraseTrianglesAtIndices(
template <typename T, typename TNearPointLocator>
void Triangulation<T, TNearPointLocator>::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;
}
Expand Down Expand Up @@ -416,10 +413,7 @@ void Triangulation<T, TNearPointLocator>::addSuperTriangle(const Box2d<T>& 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 <typename T, typename TNearPointLocator>
Expand Down
26 changes: 25 additions & 1 deletion CDT/include/KDTree.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -372,4 +396,4 @@ class KDTree

} // namespace KDTree

#endif // header guard
#endif // header guard
25 changes: 22 additions & 3 deletions CDT/include/LocatorKDTree.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,25 @@ template <
class LocatorKDTree
{
public:
/// Add point to R-tree
/// Initialize KD-tree with points
void initialize(const std::vector<V2d<TCoordType> >& points)
{
typedef V2d<TCoordType> V2d_t;
V2d_t min = points.front();
V2d_t max = min;
typedef typename std::vector<V2d_t>::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<V2d<TCoordType> >& points)
{
m_kdTree.insert(i, points);
Expand All @@ -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
Expand Down

0 comments on commit cda399c

Please sign in to comment.