tdtree_invariants.hpp

Back to Temporal kd-tree

pastel/geometry/tdtree/

#ifndef PASTELGEOMETRY_TDTREE_INVARIANTS_HPP
#define PASTELGEOMETRY_TDTREE_INVARIANTS_HPP

#include "pastel/geometry/tdtree/tdtree_invariants.h"

namespace Pastel
{

    namespace TdTree_
    {

        template <
            typename Settings,
            template <typename> class Customization> 
        bool testInvariants(
            const TdTree<Settings, Customization>& tree,
            const typename TdTree<Settings, Customization>::Cursor& parent,
            bool right,
            const typename TdTree<Settings, Customization>::Cursor& node,
            integer depth)
        {
            using Tree = TdTree<Settings, Customization>;

            if (node == tree.endNode())
            {
                return true;
            }

            if (node.splitAxis() < 0 ||
                node.splitAxis() >= tree.dimension())
            {
                // The split-axis must be in the
                // range [0, d[, where d is the
                // dimension of the tree.
                return false;
            }

            if (node.min() > node.max() ||
                node.prevMin() > node.prevMax())
            {
                // Node-bound minimum must not
                // exceed node-bound maximum.
                return false;
            }

            if (node.prevMin() > node.min() ||
                node.prevMax() < node.max())
            {
                // The previous node-bounds must enclose the
                // current node-bounds.
                return false;
            }

            if (parent != tree.endNode() &&
                node.points() > parent.points())
            {
                // The number of points in a child-node
                // must not exceed that in the parent-node.
                return false;
            }

            // Recurse to children.

            if (!testInvariants(tree, node, false, node.left(), depth + 1))
            {
                return false;
            }

            if (!testInvariants(tree, node, true, node.right(), depth + 1))
            {
                return false;
            }

            return true;
        }

    }

    template <
        typename Settings,
        template <typename> class Customization> 
    bool testInvariants(
        const TdTree<Settings, Customization>& tree)
    {
        if (tree.empty() != (tree.size() == 0))
        {
            // The tree is empty if and only if
            // the size is zero.
            return false;
        }

        if (tree.size() != tree.root().points())
        {
            // The number of points in the tree
            // must equal the number of points
            // in the root node.
            return false;
        }

        return TdTree_::testInvariants(tree, tree.endNode(), false, tree.root(), 0);
    }

}

#endif