Search code examples
c++functorcgal

Modifying functor variable when using incremental spatial searching with cgal


I've modified an example given by the computational geometry cgal library (link) that demonstrates incremental searching on a 2D plane (Section 49.3.2). The example uses a functor to set spatial bounds for searching only positive points on the plane.

I would like to modify the functor so that k can be passed in, as demonstrated by struct X_not_positive_k. The complete example program below below shows the modified code and the original code.

#include <CGAL/Simple_cartesian.h>
#include <CGAL/Orthogonal_incremental_neighbor_search.h>
#include <CGAL/Search_traits_2.h>

typedef CGAL::Simple_cartesian<double> K;
typedef K::Point_2 Point_d;
typedef CGAL::Search_traits_2<K> TreeTraits;
typedef CGAL::Orthogonal_incremental_neighbor_search<TreeTraits> NN_incremental_search;
typedef NN_incremental_search::iterator NN_iterator;
typedef NN_incremental_search::Tree Tree;

int main() {

    Tree tree;
    tree.insert(Point_d(0,0));
    tree.insert(Point_d(1,1));
    tree.insert(Point_d(0,1));
    tree.insert(Point_d(10,110));
    tree.insert(Point_d(45,0));
    tree.insert(Point_d(0,2340));
    tree.insert(Point_d(0,30));

    Point_d query(0,0);

    // A functor that returns true, iff the x-coordinate of a dD point is not positive
    // [ORIGINAL CODE]
    struct X_not_positive {
        bool operator()(const NN_iterator& it) { return ((*it).first)[0]<0;  }
    };

    // [MODIFIED CODE]
    // This does not work when used below.
    struct X_not_positive_k {
    public:
        void assign_k(int k) {this->k = k; }
        bool operator()(const NN_iterator& it) { return ((*it).first)[0] < k;  }
    private:
        int k;
    };
    X_not_positive_k Xk;
    Xk.assign_k(1);

    // An iterator that only enumerates dD points with positive x-coordinate
    // [ORIGINAL CODE]
    // typedef CGAL::Filter_iterator<NN_iterator, X_not_positive> NN_positive_x_iterator;

    // [MODIFIED CODE]
    typedef CGAL::Filter_iterator<NN_iterator, X_not_positive_k> NN_positive_x_iterator;

    NN_incremental_search NN(tree, query);

    // [ORIGINAL CODE]
    // NN_positive_x_iterator it(NN.end(), X_not_positive(), NN.begin()), end(NN.end(), X_not_positive());

    // [MODIFIED CODE]
    NN_positive_x_iterator it(NN.end(), Xk(), NN.begin()), end(NN.end(), Xk()); 
    // error occurs here

    std::cout <<  "The first 5 nearest neighbours with positive x-coord are: " << std::endl;
    for (int j=0; (j < 5)&&(it!=end); ++j,++it)
        std::cout <<   (*it).first << "  at squared distance = " << (*it).second << std::endl;

return 0;
}

However, compiling this program (Windows 7 with Visual Studio 2010) causes the following compiler error. The location of the error is marked in the code above.

2>..\main.cpp(56): error C2064: term does not evaluate to a function taking 0 arguments
2>          class does not define an 'operator()' or a user defined conversion operator to a pointer-to-function or reference-to-function that takes appropriate number of arguments
2>..\main.cpp(56): error C2064: term does not evaluate to a function taking 0 arguments
2>          class does not define an 'operator()' or a user defined conversion operator to a pointer-to-function or reference-to-function that takes appropriate number of arguments
2>

What can be done to get rid of the error? Is there another way to be able to set the k variable?


Solution

  • Just replace your Xk() with Xk in this line 56

    alternatively replace assign(k) with constructor argument, then replace Xk() with X_not_positive_k(1)

    actually real trouble is functor's name! replace name X_not_positive_k with X_less_than - so call to X_less_than(1) looks nice in line 56

    like this:

    struct X_less_than {
    public:
        X_less_than(int i)
          : k(i)
        {
        }
        bool operator()(const NN_iterator& it) { return ((*it).first)[0] < k;  }
    private:
        int k;
    };