diff --git a/Spatial_searching/test/Spatial_searching/Circular_query.cpp b/Spatial_searching/test/Spatial_searching/Circular_query.cpp index 4b6ca65a341..72bc4da436f 100644 --- a/Spatial_searching/test/Spatial_searching/Circular_query.cpp +++ b/Spatial_searching/test/Spatial_searching/Circular_query.cpp @@ -1,95 +1,123 @@ -// file : test/Spatial_searching/Circular_query.C // test whether circular queries are computed correctly for random data // // 1) generate list of query points using report_all // 2) remove and check reported points from these list // 3) check if no remaining points should have been reported +#include "Point_with_info.h" + #include -#include + #include #include #include -#include -#include #include + +#include #include -#include "Point_with_info.h" +#include + +#include + +#include +#include +#include +#include + +typedef CGAL::Cartesian K; +typedef K::FT FT; +typedef K::Point_2 Point; + +typedef CGAL::Random_points_in_square_2 Random_points_iterator; +typedef CGAL::Counting_iterator N_Random_points_iterator; +typedef CGAL::Search_traits_2 Traits; -typedef CGAL::Cartesian K; -typedef K::Point_2 Point; -typedef CGAL::Random_points_in_square_2 Random_points_iterator; -typedef CGAL::Counting_iterator N_Random_points_iterator; -typedef CGAL::Search_traits_2 Traits; //for Point_with_info -typedef Point_with_info_helper::type Point_with_info; -typedef Point_property_map Ppmap; -typedef CGAL::Search_traits_adapter Traits_with_info; +typedef Point_with_info_helper::type Point_with_info; +typedef Point_property_map Ppmap; +typedef CGAL::Search_traits_adapter Traits_with_info; -template -void run(std::list all_points){ - typedef CGAL::Fuzzy_sphere Fuzzy_circle; - typedef CGAL::Kd_tree Tree; +template +void run_with_fuzziness(std::list all_points, // intentional copy + const Tree& tree, + const Point& center, + const FT radius, + const FT fuzziness) +{ + typedef CGAL::Fuzzy_sphere Fuzzy_circle; - // Insert also the N points in the tree - Tree tree( - boost::make_transform_iterator(all_points.begin(),Create_point_with_info()), - boost::make_transform_iterator(all_points.end(),Create_point_with_info()) - ); + Fuzzy_circle default_range(typename SearchTraits::Point_d(center), radius); + std::list result; + tree.search(std::back_inserter(result), default_range); - // define exact circular range query (fuzziness=0) - Point center(0.25, 0.25); - Fuzzy_circle exact_range(typename Traits::Point_d(center), 0.25); - - std::list result; - tree.search(std::back_inserter( result ), exact_range); - - typedef std::vector V; + typedef std::vector V; V vec; vec.resize(result.size()); - typename V::iterator it = tree.search(vec.begin(), exact_range); + typename V::iterator it = tree.search(vec.begin(), default_range); assert(it == vec.end()); - - tree.search(CGAL::Emptyset_iterator(), Fuzzy_circle(center, 0.25) ); //test compilation when Point != Traits::Point_d - - // test the results of the exact query - std::list copy_all_points(all_points); - for (typename std::list::iterator pt=result.begin(); (pt != result.end()); ++pt) { - // a point with distance d to the center may be reported if d <= r - assert(CGAL::squared_distance(center, get_point(*pt)) <= 0.0625); - copy_all_points.remove(get_point(*pt)); - } - - for (std::list::iterator pt=copy_all_points.begin(); (pt != copy_all_points.end()); ++pt) { - if(CGAL::squared_distance(center, *pt) < 0.0625){ - // all points with a distance d < r must be reported - std::cout << "we missed " << *pt << " with distance = " << CGAL::squared_distance(center,*pt) << std::endl; - } - assert(CGAL::squared_distance(center, *pt) >= 0.0625); - } - result.clear(); - // approximate range searching using value 0.125 for fuzziness parameter - Fuzzy_circle approximate_range(typename Traits::Point_d(center), 0.25, 0.125); - tree.search(std::back_inserter( result ), approximate_range); - // test the results of the approximate query - for (typename std::list::iterator pt=result.begin(); (pt != result.end()); ++pt) { - // a point with distance d to the center may be reported if d <= r + eps - assert(CGAL::squared_distance(center,get_point(*pt))<=0.140625); // (0.25 + 0.125)² + std::cout << "test with center: " << center << " radius: " << radius << " eps: " << fuzziness << "... "; + + tree.search(CGAL::Emptyset_iterator(), Fuzzy_circle(center, radius) ); //test compilation when Point != Traits::Point_d + + // range searching + Fuzzy_circle approximate_range(typename SearchTraits::Point_d(center), radius, fuzziness); + tree.search(std::back_inserter(result), approximate_range); + std::cout << result.size() << " hits... Verifying correctness..."; + + // test the results + const FT sq_inner_radius = (fuzziness > radius) ? 0 : (radius - fuzziness) * (radius - fuzziness); + const FT sq_outer_radius = (radius + fuzziness) * (radius + fuzziness); + + for(typename std::list::iterator pt=result.begin(); (pt != result.end()); ++pt) + { + // a point with distance d to the center can only be reported if d <= r + eps + bool is_correct = (CGAL::squared_distance(center, get_point(*pt)) <= sq_outer_radius); + if(!is_correct) + std::cout << get_point(*pt) << " at distance = " << CGAL::squared_distance(center, get_point(*pt)) + << " should not have been reported (max is: " << sq_outer_radius << ")" << std::endl; + assert(is_correct); all_points.remove(get_point(*pt)); } - for (std::list::iterator pt=all_points.begin(); (pt != all_points.end()); ++pt) { - // all points with a distance d < r - eps must be reported - if(CGAL::squared_distance(center, *pt) < 0.015625){ // (0.25 - 0.125)² - std::cout << "we missed " << *pt << " with distance = " << CGAL::squared_distance(center,*pt) << std::endl; - } - assert(CGAL::squared_distance(center,*pt) >= 0.015625); + for(std::list::const_iterator pt=all_points.begin(); (pt != all_points.end()); ++pt) + { + // all points with a distance d <= r - eps must have been reported + bool is_correct = (CGAL::squared_distance(center,*pt) > sq_inner_radius); + if(!is_correct) + std::cout << "missed " << *pt << " with distance = " << CGAL::squared_distance(center,*pt) << std::endl; + + assert(is_correct); } + std::cout << "done" << std::endl; } +template +void run(std::list all_points) // intentional copy +{ + typedef CGAL::Kd_tree Tree; + + // Insert also the N points in the tree + Tree tree( + boost::make_transform_iterator(all_points.begin(), Create_point_with_info()), + boost::make_transform_iterator(all_points.end(), Create_point_with_info()) + ); + + Point center(0.25, 0.25); + run_with_fuzziness(all_points, tree, center, 0. /*radius*/, 0. /*fuzziness*/); + run_with_fuzziness(all_points, tree, center, 0.25 /*radius*/, 0. /*fuzziness*/); + run_with_fuzziness(all_points, tree, center, 0.25 /*radius*/, 0.125 /*fuzziness*/); + run_with_fuzziness(all_points, tree, center, 0.25 /*radius*/, 0.25 /*fuzziness*/); + run_with_fuzziness(all_points, tree, center, 0.25 /*radius*/, 1. /*fuzziness*/); + run_with_fuzziness(all_points, tree, center, 1. /*radius*/, 0. /*fuzziness*/); + run_with_fuzziness(all_points, tree, center, 1. /*radius*/, 0.25 /*fuzziness*/); + run_with_fuzziness(all_points, tree, center, 10. /*radius*/, 0. /*fuzziness*/); + run_with_fuzziness(all_points, tree, center, 10. /*radius*/, 10. /*fuzziness*/); + run_with_fuzziness(all_points, tree, center, 10. /*radius*/, 100. /*fuzziness*/); +} + int main() { const int N=1000; @@ -101,6 +129,12 @@ int main() { std::list all_points(N_Random_points_iterator(rpit,0), N_Random_points_iterator(N)); + // add some interesting points + all_points.push_back(Point(0.25, 0.25)); + all_points.push_back(Point(0.375, 0.25)); + all_points.push_back(Point(0.5, 0.25)); + all_points.push_back(Point(1.25, 0.25)); + run(all_points); run(all_points); diff --git a/Spatial_searching/test/Spatial_searching/Iso_rectangle_2_query.cpp b/Spatial_searching/test/Spatial_searching/Iso_rectangle_2_query.cpp index 15abb583eb1..0218ecf8717 100644 --- a/Spatial_searching/test/Spatial_searching/Iso_rectangle_2_query.cpp +++ b/Spatial_searching/test/Spatial_searching/Iso_rectangle_2_query.cpp @@ -1,98 +1,158 @@ -// file: Iso_rectangle_2_query.C +// test whether box queries are computed correctly for random data +// +// 1) generate list of query points using report_all +// 2) remove and check reported points from these list +// 3) check if no remaining points should have been reported #include -#include + +#include "Point_with_info.h" + #include #include #include -#include #include -#include -#include "Point_with_info.h" +#include +#include + +#include #include #include -typedef CGAL::Simple_cartesian K; -typedef K::Point_2 Point; -typedef K::Vector_2 Vector; -typedef K::Iso_rectangle_2 Iso_rectangle; -typedef CGAL::Random_points_in_square_2 Random_points_iterator; -typedef CGAL::Counting_iterator N_Random_points_iterator; -typedef CGAL::Search_traits_2 Traits; -typedef Point_with_info_helper::type Point_with_info; -typedef Point_property_map Ppmap; -typedef CGAL::Search_traits_adapter Traits_with_info; +typedef CGAL::Simple_cartesian K; +typedef K::FT FT; +typedef K::Point_2 Point; +typedef K::Vector_2 Vector; +typedef K::Iso_rectangle_2 Iso_rectangle; -template -void run(std::list all_points) +typedef CGAL::Random_points_in_square_2 Random_points_iterator; +typedef CGAL::Counting_iterator N_Random_points_iterator; +typedef CGAL::Search_traits_2 Traits; +typedef Point_with_info_helper::type Point_with_info; +typedef Point_property_map Ppmap; +typedef CGAL::Search_traits_adapter Traits_with_info; + +template +void run_with_fuzziness(std::list all_points, const Tree& tree, + const Point& p, const Point& q, const FT fuzziness) { typedef CGAL::Fuzzy_iso_box Fuzzy_box; - // Insert also the N points in the tree - CGAL::Kd_tree tree( - boost::make_transform_iterator(all_points.begin(),Create_point_with_info()), - boost::make_transform_iterator(all_points.end(),Create_point_with_info()) - ); + tree.search(CGAL::Emptyset_iterator(), Fuzzy_box(p,q)); //test compilation when Point != Traits::Point_d - Point p(0.1, 0.2); - Point q(0.3, 0.5); typename SearchTraits::Point_d pp(p); typename SearchTraits::Point_d qq(q); + std::cout << "test with box: [" << p << " || " << q << "] and eps: " << fuzziness << "... "; - Iso_rectangle ic(p,q); - - Fuzzy_box default_range(pp,qq); - + // approximate range searching std::list result; - // Searching the box ic - tree.search( std::back_inserter( result ), default_range); + Fuzzy_box approximate_range(pp, qq, fuzziness); + tree.search(std::back_inserter(result), approximate_range); + std::cout << result.size() << " hits... Verifying correctness..."; - tree.search(CGAL::Emptyset_iterator(), Fuzzy_box(p,q) ); //test compilation when Point != Traits::Point_d - - // test the results of the default query - std::list copy_all_points(all_points); - for (typename std::list::iterator pt=result.begin(); (pt != result.end()); ++pt) { - assert(! ic.has_on_unbounded_side(get_point(*pt)) || ic.has_on_boundary(get_point(*pt))); - copy_all_points.remove(get_point(*pt)); - } - - for (std::list::iterator pt=copy_all_points.begin(); (pt != copy_all_points.end()); ++pt) { - assert(ic.has_on_unbounded_side(*pt) || ic.has_on_boundary(*pt)); - } - - - result.clear(); - // approximate range searching using value 0.1 for fuzziness parameter - Fuzzy_box approximate_range(pp,qq,0.05); - Iso_rectangle inner_ic(p+ 0.05*Vector(1,1),q-0.05*Vector(1,1)); - Iso_rectangle outer_ic(p- 0.05*Vector(1,1),q+0.05*Vector(1,1)); - - tree.search(std::back_inserter( result ), approximate_range); // test the results of the approximate query - for (typename std::list::iterator pt=result.begin(); (pt != result.end()); ++pt) { - // a point we found may be slighlty outside the isorectangle - assert(! outer_ic.has_on_unbounded_side(get_point(*pt)) || outer_ic.has_on_boundary(get_point(*pt))); + Iso_rectangle inner_ic(p + fuzziness*Vector(1,1), q - fuzziness*Vector(1,1)); + Iso_rectangle outer_ic(p - fuzziness*Vector(1,1), q + fuzziness*Vector(1,1)); + + // If the fuziness is greater than half of the largest dimension of the box, + // then the inner box does not exist + const FT max_box_edge_length = (std::max)(q[1] - p[1], q[0] - p[0]); + const bool is_inner_c_empty = (fuzziness > 0.5 * max_box_edge_length); + if(is_inner_c_empty) + std::cout << " (empty inner box)... "; + + for (typename std::list::iterator pt=result.begin(); (pt != result.end()); ++pt) + { + // a point can only be reported if it is in the outer box + bool is_correct = outer_ic.has_on_bounded_side(get_point(*pt)) || outer_ic.has_on_boundary(get_point(*pt)); + if(!is_correct) + std::cout << get_point(*pt) << " should have not been reported" << std::endl; + assert(is_correct); all_points.remove(get_point(*pt)); } - for (std::list::iterator pt=all_points.begin(); (pt != all_points.end()); ++pt) { - assert(inner_ic.has_on_unbounded_side(*pt) || inner_ic.has_on_boundary(*pt)); + // nothing to test if the inner box is empty because everything is on the unbounded side + if(!is_inner_c_empty) + { + for (std::list::iterator pt=all_points.begin(); (pt != all_points.end()); ++pt) + { + // all points that have not been reported must be outside the inner box + bool is_correct = inner_ic.has_on_unbounded_side(*pt); + if(!is_correct) + std::cout << *pt << " should have been reported" << std::endl; + + assert(is_correct); + } } + std::cout << "done" << std::endl; } -int main() { +template +void run(std::list all_points) // intentional copy +{ + // Insert also the N points in the tree + CGAL::Kd_tree tree( + boost::make_transform_iterator(all_points.begin(), Create_point_with_info()), + boost::make_transform_iterator(all_points.end(), Create_point_with_info()) + ); + // bigger box + Point p0(-10., -10.); + Point q0( 10., 10.); + + // a subset + Point p1(-CGAL_PI/10., -CGAL_PI/10.); + Point q1( CGAL_PI/10., CGAL_PI/10.); + + // another subset + Point p2(0.1, 0.2); + Point q2(0.3, 0.4); + + // degenerate + Point p3(0., 0.); + Point q3(0., 0.); + + run_with_fuzziness(all_points, tree, p0, q0, 0. /*fuzziness*/); + run_with_fuzziness(all_points, tree, p0, q0, 0.1 /*fuzziness*/); + run_with_fuzziness(all_points, tree, p0, q0, 1. /*fuzziness*/); + run_with_fuzziness(all_points, tree, p0, q0, 10. /*fuzziness*/); + + run_with_fuzziness(all_points, tree, p1, q1, 0. /*fuzziness*/); + run_with_fuzziness(all_points, tree, p1, q1, 0.1 /*fuzziness*/); + run_with_fuzziness(all_points, tree, p1, q1, 1. /*fuzziness*/); + run_with_fuzziness(all_points, tree, p1, q1, 10. /*fuzziness*/); + + run_with_fuzziness(all_points, tree, p2, q2, 0. /*fuzziness*/); + run_with_fuzziness(all_points, tree, p2, q2, 0.1 /*fuzziness*/); + run_with_fuzziness(all_points, tree, p2, q2, 0.4 /*fuzziness*/); + + run_with_fuzziness(all_points, tree, p3, q3, 0. /*fuzziness*/); + run_with_fuzziness(all_points, tree, p3, q3, 0.33 /*fuzziness*/); + run_with_fuzziness(all_points, tree, p3, q3, 1. /*fuzziness*/); +} + +int main() +{ const int N=10000; // generator for random data points in the square ( (-1,-1), (1,1) ) - Random_points_iterator rpit( 1.0); + Random_points_iterator rpit(1.0); // construct list containing N random points std::list all_points(N_Random_points_iterator(rpit,0), - N_Random_points_iterator(N)); + N_Random_points_iterator(N)); + + // add some interesting points + all_points.push_back(Point(0., 0.)); + all_points.push_back(Point(-CGAL_PI/10.+0.1, -CGAL_PI/10.+0.1)); + all_points.push_back(Point(1., 1.)); + all_points.push_back(Point(0., 1.)); + all_points.push_back(Point(0.3, 0.4)); + all_points.push_back(Point(0.2, 0.3)); + all_points.push_back(Point(0., 0.1)); run(all_points); run(all_points);