mirror of https://github.com/CGAL/cgal
Replace incremental search with a range query and a k-neighbor search
This commit is contained in:
parent
f5343911a6
commit
728b4a2f5f
|
|
@ -24,6 +24,10 @@
|
|||
#include "tbb/parallel_for.h"
|
||||
#endif // CGAL_LINKED_WITH_TBB
|
||||
|
||||
#include <boost/function_output_iterator.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template < class Gt, class FS, class Sh, class wA, class Ct >
|
||||
|
|
@ -71,6 +75,21 @@ public:
|
|||
}; // In_surface_tester
|
||||
|
||||
|
||||
struct Inc {
|
||||
unsigned int * i;
|
||||
|
||||
Inc(unsigned int& i)
|
||||
: i(&i)
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
void operator()(const T&) const
|
||||
{
|
||||
++(*i);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Compute the number of neighbors of a point that lie within a fixed radius.
|
||||
template < class Gt, class FS, class Sh, class wA, class Ct >
|
||||
class
|
||||
|
|
@ -85,13 +104,19 @@ private:
|
|||
|
||||
const Pointset& _pts;
|
||||
const Search_tree& _tree;
|
||||
const FT& _sq_rd;
|
||||
const FT _sq_rd;
|
||||
CountVec& _nn;
|
||||
|
||||
public:
|
||||
ComputeNN(const Pointset& points, const Search_tree& tree,
|
||||
const FT& sq_radius, CountVec& nn)
|
||||
: _pts(points), _tree(tree), _sq_rd(sq_radius), _nn(nn) {}
|
||||
: _pts(points), _tree(tree), _sq_rd(
|
||||
#if 1
|
||||
sqrt(sq_radius)
|
||||
#else
|
||||
sq_radius
|
||||
#endif
|
||||
), _nn(nn) {}
|
||||
|
||||
#ifdef CGAL_LINKED_WITH_TBB
|
||||
void operator()( const tbb::blocked_range< std::size_t >& range ) const {
|
||||
|
|
@ -100,12 +125,26 @@ public:
|
|||
}
|
||||
#endif // CGAL_LINKED_WITH_TBB
|
||||
void operator()( const std::size_t& i ) const {
|
||||
#if 1
|
||||
Sphere sp(_pts[i], _sq_rd, 0);
|
||||
|
||||
Inc inc(_nn[i]);
|
||||
_tree.search(boost::make_function_output_iterator(inc),sp);
|
||||
#endif
|
||||
#if 0
|
||||
// Iterate over the neighbors until the first one is found that is too far.
|
||||
Dynamic_search search( _tree, _pts[i] );
|
||||
for( typename Dynamic_search::iterator nit = search.begin();
|
||||
nit != search.end() && compare( _pts[i], nit->first, _sq_rd ) != LARGER;
|
||||
++nit )
|
||||
++_nn[i];
|
||||
/*
|
||||
if(count != _nn[i]){
|
||||
std::string s = boost::lexical_cast<std::string>(count) + " != " + boost::lexical_cast<std::string>(_nn[i]) + "\n";
|
||||
std::cerr << s;
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
}
|
||||
}; // class ComputeNN
|
||||
|
||||
|
|
@ -141,7 +180,16 @@ public:
|
|||
// If the neighborhood is too small, the vertex is not moved.
|
||||
if( _nn[i] < 4 )
|
||||
return;
|
||||
|
||||
#if 1
|
||||
Static_search search(_tree, _pts[i], _nn[i]);
|
||||
Approximation pca( _nn[i] );
|
||||
unsigned int column = 0;
|
||||
for( typename Static_search::iterator nit = search.begin();
|
||||
nit != search.end() && column < _nn[i];
|
||||
++nit, ++column ) {
|
||||
pca.set_point( column, nit->first, 1.0 / _nn[ _ind.at( nit->first ) ] );
|
||||
}
|
||||
#else
|
||||
// Collect the vertices within the ball and their weights.
|
||||
Dynamic_search search( _tree, _pts[i] );
|
||||
Approximation pca( _nn[i] );
|
||||
|
|
@ -152,6 +200,7 @@ public:
|
|||
pca.set_point( column, nit->first, 1.0 / _nn[ _ind.at( nit->first ) ] );
|
||||
}
|
||||
CGAL_assertion( column == _nn[i] );
|
||||
#endif
|
||||
|
||||
// Compute the weighted least-squares planar approximation of the point set.
|
||||
if( !pca.compute() )
|
||||
|
|
@ -409,7 +458,11 @@ increase_scale( unsigned int iterations ) {
|
|||
// This can be done concurrently.
|
||||
CountVec neighbors( _tree.size(), 0 );
|
||||
try_parallel( ComputeNN( _points, _tree, _squared_radius, neighbors ), 0, _tree.size() );
|
||||
|
||||
/*
|
||||
for(int i =0; i < neighbors.size(); i++){
|
||||
std::cerr << neighbors[i] << std::endl;
|
||||
}
|
||||
*/
|
||||
// Construct a mapping from each point to its index.
|
||||
PIMap indices;
|
||||
std::size_t index = 0;
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include <CGAL/Search_traits_3.h>
|
||||
#include <CGAL/Orthogonal_incremental_neighbor_search.h>
|
||||
#include <CGAL/Orthogonal_k_neighbor_search.h>
|
||||
#include <CGAL/Fuzzy_sphere.h>
|
||||
#include <CGAL/Random.h>
|
||||
|
||||
#include <CGAL/Scale_space_reconstruction_3/Shape_construction_3.h>
|
||||
|
|
@ -109,7 +110,7 @@ private:
|
|||
typedef Orthogonal_incremental_neighbor_search< Search_traits >
|
||||
Dynamic_search;
|
||||
typedef typename Dynamic_search::Tree Search_tree;
|
||||
|
||||
typedef Fuzzy_sphere< Search_traits > Sphere;
|
||||
typedef CGAL::Random Random;
|
||||
|
||||
// Constructing the surface.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <CGAL/Kd_tree.h>
|
||||
#include <CGAL/Fuzzy_sphere.h>
|
||||
#include <CGAL/Search_traits_3.h>
|
||||
|
||||
const int D = 3;
|
||||
|
||||
typedef CGAL::Simple_cartesian<double> K;
|
||||
typedef K::Point_3 Point_d;
|
||||
typedef CGAL::Search_traits_d<K,CGAL::Dimension_tag<D> > Traits;
|
||||
typedef CGAL::Random_points_in_cube_d<Point_d> Random_points_iterator;
|
||||
typedef CGAL::Counting_iterator<Random_points_iterator> N_Random_points_iterator;
|
||||
typedef CGAL::Kd_tree<Traits> Tree;
|
||||
typedef CGAL::Fuzzy_sphere<Traits> Fuzzy_sphere;
|
||||
typedef CGAL::Fuzzy_iso_box<Traits> Fuzzy_iso_box;
|
||||
|
||||
int main() {
|
||||
|
||||
const int N = 1000;
|
||||
// generator for random data points in the square ( (-1000,-1000), (1000,1000) )
|
||||
Random_points_iterator rpit(4, 1000.0);
|
||||
|
||||
// Insert N points in the tree
|
||||
Tree tree(N_Random_points_iterator(rpit,0),
|
||||
N_Random_points_iterator(rpit,N));
|
||||
|
||||
// define range query objects
|
||||
double pcoord[D] = { 300, 300, 300, 300 };
|
||||
double qcoord[D] = { 900.0, 900.0, 900.0, 900.0 };
|
||||
Point_d p(D, pcoord+0, pcoord+D);
|
||||
Point_d q(D, qcoord+0, qcoord+D);
|
||||
Fuzzy_sphere fs(p, 700.0, 100.0);
|
||||
Fuzzy_iso_box fib(p, q, 100.0);
|
||||
|
||||
std::cout << "points approximately in fuzzy spherical range query" << std::endl;
|
||||
std::cout << "with center (300, 300, 300, 300)" << std::endl;
|
||||
std::cout << "and fuzzy radius [600, 800] are:" << std::endl;
|
||||
tree.search(std::ostream_iterator<Point_d>(std::cout, "\n"), fs);
|
||||
|
||||
std::cout << "points approximately in fuzzy rectangular range query ";
|
||||
std::cout << "[[200, 400], [800,1000]]^4 are:" << std::endl;
|
||||
|
||||
tree.search(std::ostream_iterator<Point_d>(std::cout, "\n"), fib);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -120,8 +120,8 @@ namespace CGAL {
|
|||
else {
|
||||
Internal_node_const_handle node =
|
||||
static_cast<Internal_node_const_handle>(this);
|
||||
it=node->lower()->tree_items(it);
|
||||
it=node->upper()->tree_items(it);
|
||||
it=node->lower()->tree_items(it);
|
||||
it=node->upper()->tree_items(it);
|
||||
}
|
||||
return it;
|
||||
}
|
||||
|
|
@ -173,7 +173,7 @@ namespace CGAL {
|
|||
if (node->size()>0)
|
||||
for (iterator i=node->begin(); i != node->end(); i++)
|
||||
if (q.contains(*i))
|
||||
{*it=*i; ++it;}
|
||||
{*it++=*i;}
|
||||
}
|
||||
else {
|
||||
Internal_node_const_handle node =
|
||||
|
|
|
|||
|
|
@ -0,0 +1,86 @@
|
|||
# Created by the script cgal_create_CMakeLists
|
||||
# This is the CMake script for compiling a set of CGAL applications.
|
||||
|
||||
project( Spatial_searching )
|
||||
|
||||
|
||||
cmake_minimum_required(VERSION 2.6.2)
|
||||
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" VERSION_GREATER 2.6)
|
||||
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}" VERSION_GREATER 2.8.3)
|
||||
cmake_policy(VERSION 2.8.4)
|
||||
else()
|
||||
cmake_policy(VERSION 2.6)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set( CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true )
|
||||
|
||||
if ( COMMAND cmake_policy )
|
||||
|
||||
cmake_policy( SET CMP0003 NEW )
|
||||
|
||||
endif()
|
||||
|
||||
# CGAL and its components
|
||||
find_package( CGAL QUIET COMPONENTS )
|
||||
|
||||
if ( NOT CGAL_FOUND )
|
||||
|
||||
message(STATUS "This project requires the CGAL library, and will not be compiled.")
|
||||
return()
|
||||
|
||||
endif()
|
||||
|
||||
# include helper file
|
||||
include( ${CGAL_USE_FILE} )
|
||||
|
||||
|
||||
# Boost and its components
|
||||
find_package( Boost REQUIRED )
|
||||
|
||||
if ( NOT Boost_FOUND )
|
||||
|
||||
message(STATUS "This project requires the Boost library, and will not be compiled.")
|
||||
|
||||
return()
|
||||
|
||||
endif()
|
||||
|
||||
# include for local directory
|
||||
|
||||
# include for local package
|
||||
include_directories( BEFORE ../../include )
|
||||
|
||||
|
||||
# Creating entries for all .cpp/.C files with "main" routine
|
||||
# ##########################################################
|
||||
|
||||
include( CGAL_CreateSingleSourceCGALProgram )
|
||||
|
||||
create_single_source_cgal_program( "Building_kd_tree_with_ddim_points.cpp" )
|
||||
|
||||
create_single_source_cgal_program( "Building_kd_tree_with_own_pointtype.cpp" )
|
||||
|
||||
create_single_source_cgal_program( "Circular_query.cpp" )
|
||||
|
||||
create_single_source_cgal_program( "Compare_methods.cpp" )
|
||||
|
||||
create_single_source_cgal_program( "Iso_rectangle_2_query.cpp" )
|
||||
|
||||
create_single_source_cgal_program( "iso_rectangle_2_query_2.cpp" )
|
||||
|
||||
create_single_source_cgal_program( "K_neighbor_search_manhattan_distance_isobox_point.cpp" )
|
||||
|
||||
create_single_source_cgal_program( "K_neighbor_search_with_circle.cpp" )
|
||||
|
||||
create_single_source_cgal_program( "Orthogonal_incremental_neighbor_search.cpp" )
|
||||
|
||||
create_single_source_cgal_program( "Orthogonal_k_neighbor_search.cpp" )
|
||||
|
||||
create_single_source_cgal_program( "Range_searching.cpp" )
|
||||
|
||||
create_single_source_cgal_program( "rangeVSincremental.cpp" )
|
||||
|
||||
create_single_source_cgal_program( "Splitters.cpp" )
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <fstream>
|
||||
#include <CGAL/Orthogonal_incremental_neighbor_search.h>
|
||||
#include <CGAL/Search_traits_3.h>
|
||||
#include <CGAL/Fuzzy_sphere.h>
|
||||
#include <boost/function_output_iterator.hpp>
|
||||
|
||||
typedef CGAL::Simple_cartesian<double> K;
|
||||
typedef CGAL::Search_traits_3<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;
|
||||
#include <vector>
|
||||
|
||||
|
||||
typedef CGAL::Simple_cartesian<double> K;
|
||||
typedef K::Point_3 Point;
|
||||
|
||||
struct Inc {
|
||||
unsigned int * i;
|
||||
|
||||
Inc(unsigned int& i)
|
||||
: i(&i)
|
||||
{}
|
||||
|
||||
// template <typename T>
|
||||
void operator()(const Point& t) const
|
||||
{
|
||||
std::cout << t << std::endl;
|
||||
++(*i);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
|
||||
std::cout.precision(17);
|
||||
std::ifstream in(argv[1]);
|
||||
std::vector<Point> points;
|
||||
Point p;
|
||||
while(in >> p){
|
||||
points.push_back(p);
|
||||
}
|
||||
|
||||
Tree tree;
|
||||
tree.insert(points.begin(), points.end());
|
||||
|
||||
Point query(5,2,1);
|
||||
|
||||
NN_incremental_search NN(tree, query);
|
||||
|
||||
double sd = 0;
|
||||
std::cout << "The first 20 nearest neighbours with positive x-coord are: " << std::endl;
|
||||
NN_iterator it = NN.begin();
|
||||
for (int i=0; i<20; i++){
|
||||
sd = (*it).second;
|
||||
std::cout << (*it).first << " at squared distance = " << (*it).second << std::endl;
|
||||
++it;
|
||||
}
|
||||
|
||||
CGAL::Fuzzy_sphere<TreeTraits> fs(query,sqrt(sd));
|
||||
std::vector<Point> result;
|
||||
tree.search(std::back_inserter(result), fs);
|
||||
for(int i=0; i < result.size(); i++){
|
||||
std::cout << result[i] << " " << squared_distance(query, result[i]) << std::endl;
|
||||
}
|
||||
|
||||
|
||||
unsigned int count = 0;
|
||||
Inc inc(count);
|
||||
tree.search(boost::make_function_output_iterator(inc),fs);
|
||||
std::cout << count << std::endl;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in New Issue