a functor is many things. one way to think about it, its just a function with state. but when it comes to defining for sort and for accessors, its really just a way to exactly specify the "function signature"...<br>
<br>define your accessor<br><br> struct access_location_ptr<br> {<br> typedef double result_type;<br><br> double operator()( const Point & e, int k ) const { return e.location[k]; }<br> double operator()( const Point * e, int k ) const { return e->location[k]; }<br>
};<br><br><br><br><br><br>define your tree.<br><br> typedef KDTree::KDTree<3,Point const*,access_location_ptr> PtrTree;<br><br><br>get your data<br><br>vector<Point> data; lots of .push_backs() to fill the vector<br>
<br>NOTE: you could just use a malloc() or a plain array eg Point points[100]; and use those addresses. just as long as the memory locations don't change once the tree is loaded. Vectors are handy because they manage all the memory alloc/deallocs/resizes for you.<br>
<br><br>fill the tree<br>PtrTree tree;<br>for ( vect::iterator p = data.begin() etc ; ++p )<br> tree.insert( &*p ); // dereference iterator, then take the address<br><br>optimise<br>tree.optimise();<br><br>now, don't allow the vector to move, copy, don't add anything else to the vector or remove anything. the kdtree now points to the items in the vector, if the memory block that the vector manages is moved due to a memory resize, or the items are reordered, then the tree will either be filled with invalidated pointers, or all the items will be mixed up.<br>
<br>note that the accessor has 2 ways of calling it - one with a pointer, one without.<br>useful for<br><br>Point whatnot; // set it up with the location<br>result = tree.find_nearest(whatnot, etc);<br><br>so it can access both whatnot (directly through reference) or via pointers (in the tree).<br>
<br>see ya<br>Paul<br><br>