diff --git a/Nef_3/include/CGAL/Nef_polyhedron_3.h b/Nef_3/include/CGAL/Nef_polyhedron_3.h index 82f2166a398..9f3c59bfae1 100644 --- a/Nef_3/include/CGAL/Nef_polyhedron_3.h +++ b/Nef_3/include/CGAL/Nef_polyhedron_3.h @@ -1555,7 +1555,8 @@ protected: SVertex_iterator sv; CGAL_forall_svertices(sv, snc()) { - sv->out_sedge() = sv->out_sedge()->twin(); + if (!sv->is_isolated()) + sv->out_sedge() = sv->out_sedge()->twin(); } SHalfedge_iterator se; diff --git a/Spatial_searching/include/CGAL/Kd_tree.h b/Spatial_searching/include/CGAL/Kd_tree.h index 39a4b77823b..57c4b54b873 100644 --- a/Spatial_searching/include/CGAL/Kd_tree.h +++ b/Spatial_searching/include/CGAL/Kd_tree.h @@ -163,17 +163,25 @@ private: nh->set_separator(sep); int cd = nh->cutting_dimension(); - if(!c_low.empty()) - nh->low_val = c_low.tight_bounding_box().max_coord(cd); - else - nh->low_val = c_low.bounding_box().min_coord(cd); - if(!c.empty()) - nh->high_val = c.tight_bounding_box().min_coord(cd); - else - nh->high_val = c.bounding_box().max_coord(cd); + if(!c_low.empty()){ + nh->lower_low_val = c_low.tight_bounding_box().min_coord(cd); + nh->lower_high_val = c_low.tight_bounding_box().max_coord(cd); + } + else{ + nh->lower_low_val = nh->cutting_value(); + nh->lower_high_val = nh->cutting_value(); + } + if(!c.empty()){ + nh->upper_low_val = c.tight_bounding_box().min_coord(cd); + nh->upper_high_val = c.tight_bounding_box().max_coord(cd); + } + else{ + nh->upper_low_val = nh->cutting_value(); + nh->upper_high_val = nh->cutting_value(); + } - CGAL_assertion(nh->cutting_value() >= nh->low_val); - CGAL_assertion(nh->cutting_value() <= nh->high_val); + CGAL_assertion(nh->cutting_value() >= nh->lower_low_val); + CGAL_assertion(nh->cutting_value() <= nh->upper_high_val); if (c_low.size() > split.bucket_size()){ nh->lower_ch = create_internal_node_use_extension(c_low); diff --git a/Spatial_searching/include/CGAL/Kd_tree_node.h b/Spatial_searching/include/CGAL/Kd_tree_node.h index 87f3b0492c4..a2fec1e838d 100644 --- a/Spatial_searching/include/CGAL/Kd_tree_node.h +++ b/Spatial_searching/include/CGAL/Kd_tree_node.h @@ -345,8 +345,11 @@ namespace CGAL { // private variables for extended internal nodes - FT low_val; - FT high_val; + FT upper_low_val; + FT upper_high_val; + FT lower_low_val; + FT lower_high_val; + public: @@ -414,18 +417,31 @@ namespace CGAL { // members for extended internal node only inline FT - low_value() const - { - return low_val; - } - - inline - FT - high_value() const + upper_low_value() const { - return high_val; + return upper_low_val; + } + + inline + FT + upper_high_value() const + { + return upper_high_val; + } + + inline + FT + lower_low_value() const + { + return lower_low_val; + } + + inline + FT + lower_high_value() const + { + return lower_high_val; } - /*Separator& separator() diff --git a/Spatial_searching/include/CGAL/Orthogonal_incremental_neighbor_search.h b/Spatial_searching/include/CGAL/Orthogonal_incremental_neighbor_search.h index 54eb4f568d9..13eca80ece1 100644 --- a/Spatial_searching/include/CGAL/Orthogonal_incremental_neighbor_search.h +++ b/Spatial_searching/include/CGAL/Orthogonal_incremental_neighbor_search.h @@ -174,7 +174,7 @@ namespace CGAL { else{ distance_to_root= Orthogonal_distance_instance.max_distance_to_rectangle(q, - tree.bounding_box()); + tree.bounding_box(), dists); Node_with_distance *The_Root = new Node_with_distance(tree.root(), distance_to_root, dists); PriorityQueue.push(The_Root); @@ -283,8 +283,8 @@ namespace CGAL { int new_cut_dim=node->cutting_dimension(); FT new_rd,dst = dists[new_cut_dim]; FT val = *(query_point_it + new_cut_dim); - FT diff1 = val - node->high_value(); - FT diff2 = val - node->low_value(); + FT diff1 = val - node->upper_low_value(); + FT diff2 = val - node->lower_high_value(); if (diff1 + diff2 < FT(0.0)) { new_rd= Orthogonal_distance_instance.new_distance(copy_rd,dst,diff1,new_cut_dim); @@ -369,13 +369,12 @@ namespace CGAL { int new_cut_dim=node->cutting_dimension(); FT new_rd,dst = dists[new_cut_dim]; FT val = *(query_point_it + new_cut_dim); - FT diff1 = val - node->high_value(); - FT diff2 = val - node->low_value(); + FT diff1 = val - node->upper_low_value(); + FT diff2 = val - node->lower_high_value(); if (diff1 + diff2 < FT(0.0)) { + diff1 = val - node->upper_high_value(); new_rd= Orthogonal_distance_instance.new_distance(copy_rd,dst,diff1,new_cut_dim); - - CGAL_assertion(new_rd >= copy_rd); Node_with_distance *Lower_Child = new Node_with_distance(node->lower(), copy_rd, dists); PriorityQueue.push(Lower_Child); @@ -385,8 +384,8 @@ namespace CGAL { } else { // compute new distance + diff2 = val - node->lower_low_value(); new_rd=Orthogonal_distance_instance.new_distance(copy_rd,dst,diff2,new_cut_dim); - CGAL_assertion(new_rd >= copy_rd); Node_with_distance *Upper_Child = new Node_with_distance(node->upper(), copy_rd, dists); PriorityQueue.push(Upper_Child); diff --git a/Spatial_searching/include/CGAL/Orthogonal_k_neighbor_search.h b/Spatial_searching/include/CGAL/Orthogonal_k_neighbor_search.h index 0fe9226b186..308d2937247 100644 --- a/Spatial_searching/include/CGAL/Orthogonal_k_neighbor_search.h +++ b/Spatial_searching/include/CGAL/Orthogonal_k_neighbor_search.h @@ -83,8 +83,8 @@ private: typename Base::Node_const_handle bestChild, otherChild; FT new_off; FT val = *(query_object_it + new_cut_dim); - FT diff1 = val - node->high_value(); - FT diff2 = val - node->low_value(); + FT diff1 = val - node->upper_low_value(); + FT diff2 = val - node->lower_high_value(); if ( (diff1 + diff2 < FT(0.0)) ) { new_off = diff1; @@ -141,19 +141,23 @@ private: typename Base::Node_const_handle bestChild, otherChild; FT new_off; FT val = *(query_object_it + new_cut_dim); - FT diff1 = val - node->high_value(); - FT diff2 = val - node->low_value(); + FT diff1 = val - node->lower_high_value(); + FT diff2 = val - node->upper_low_value(); if ( (diff1 + diff2 >= FT(0.0)) ) { - new_off= diff2; - bestChild = node->upper(); - otherChild = node->lower(); + new_off = 2*val < node->upper_low_value()+node->upper_high_value() ? + val - node->upper_high_value(): + val - node->upper_low_value(); + bestChild = node->lower(); + otherChild = node->upper(); } else // compute new distance { - new_off= diff1; - bestChild = node->lower(); - otherChild = node->upper(); + new_off = 2*val < node->lower_low_value()+node->lower_high_value() ? + val - node->lower_high_value(): + val - node->lower_low_value(); + bestChild = node->upper(); + otherChild = node->lower(); } compute_furthest_neighbors_orthogonally(bestChild,rd); FT dst=dists[new_cut_dim]; diff --git a/Spatial_searching/test/Spatial_searching/Orthogonal_incremental_neighbor_search.cpp b/Spatial_searching/test/Spatial_searching/Orthogonal_incremental_neighbor_search.cpp index 18551a3aa92..3489ce6ae54 100644 --- a/Spatial_searching/test/Spatial_searching/Orthogonal_incremental_neighbor_search.cpp +++ b/Spatial_searching/test/Spatial_searching/Orthogonal_incremental_neighbor_search.cpp @@ -13,7 +13,7 @@ #include #include #include "Point_with_info.h" - +#include #ifdef TWO typedef CGAL::Simple_cartesian K; @@ -32,8 +32,8 @@ typedef CGAL::Search_traits_3 TreeTraits; typedef std::vector Vector; -//typedef CGAL::Orthogonal_incremental_neighbor_search Orthogonal_incremental_neighbor_search; -typedef CGAL::Incremental_neighbor_search Orthogonal_incremental_neighbor_search; +typedef CGAL::Orthogonal_incremental_neighbor_search Orthogonal_incremental_neighbor_search; +typedef CGAL::Incremental_neighbor_search Incremental_neighbor_search; typedef Orthogonal_incremental_neighbor_search::Distance Distance; typedef Orthogonal_incremental_neighbor_search::iterator NN_iterator; typedef Orthogonal_incremental_neighbor_search::Point_with_transformed_distance Point_with_transformed_distance; @@ -42,7 +42,8 @@ typedef Point_with_info_helper::type typedef Point_property_map Ppmap; typedef CGAL::Search_traits_adapter Traits_with_info; typedef CGAL::Distance_adapter Distance_adapter; -typedef CGAL::Incremental_neighbor_search Orthogonal_incremental_neighbor_search_with_info; +typedef CGAL::Orthogonal_incremental_neighbor_search Orthogonal_incremental_neighbor_search_with_info; +typedef CGAL::Incremental_neighbor_search Incremental_neighbor_search_with_info; template @@ -100,14 +101,99 @@ void run() std::cout << "done" << std::endl; - } +template +bool search(bool nearest) +{ + std::vector points; + Random_points g(1); + CGAL::cpp11::copy_n( g, 1000, std::back_inserter(points)); + + typename K_search::Tree tree( + boost::make_transform_iterator(points.begin(),Create_point_with_info()), + boost::make_transform_iterator(points.end(),Create_point_with_info()) + ); + Point query(0,0,0); + + K_search search(tree, query, 0.0, nearest); + + std::vector result, diff; + // report the N/2 furthest neighbors and their distance + + //std::copy(search.begin(), search.end(), std::back_inserter(result)); + int k=0; + for(typename K_search::iterator nit = search.begin(); + k< 500; ++nit, ++k) + { + result.push_back(get_point(nit->first)); + } + + std::sort(points.begin(), points.end()); + std::sort(result.begin(), result.end()); + std::set_difference(points.begin(), points.end(), + result.begin(), result.end(), + std::back_inserter(diff)); + + std::cout << "|result| = " << result.size() << " |diff| = " << diff.size() << std::endl; + double sep_dist = (nearest)?0:(std::numeric_limits::max)(); + { + for(std::vector::iterator it = result.begin(); + it != result.end(); + it++){ + double dist = CGAL::squared_distance(query, *it); + if(nearest){ + if(dist > sep_dist) sep_dist = dist; + } else { + if(dist < sep_dist) sep_dist = dist; + } + } + } + + bool res=true; + // the other points must be further/closer than min_dist + { + for(std::vector::iterator it = diff.begin(); + it != diff.end(); + it++){ + double dist = CGAL::squared_distance(query, *it); + if(nearest){ + if(dist < sep_dist){ + std::cout << "Error: Point " << *it << " at distance " << dist << " < " << sep_dist << std::endl; + res=false; + } + } else { + if(dist > sep_dist){ + std::cout << "Error: Point " << *it << " at distance " << dist << " > " << sep_dist << std::endl; + res=false; + } + } + } + } + return res; +} + + int main() { + bool OK=true; + std::cout << "Testing Incremental_neighbor_search\n"; + run(); + run(); + OK&=search(true); + OK&=search(false); + OK&=search(true); + OK&=search(false); + + std::cout << "Testing Orthogonal_incremental_neighbor_search\n"; run(); run(); - return 0; + OK&=search(true); + OK&=search(false); + OK&=search(true); + OK&=search(false); + + return OK ? 0 : 1; } diff --git a/Spatial_searching/test/Spatial_searching/Orthogonal_k_neighbor_search.cpp b/Spatial_searching/test/Spatial_searching/Orthogonal_k_neighbor_search.cpp index bbfed61ef41..0c51392cc44 100644 --- a/Spatial_searching/test/Spatial_searching/Orthogonal_k_neighbor_search.cpp +++ b/Spatial_searching/test/Spatial_searching/Orthogonal_k_neighbor_search.cpp @@ -22,7 +22,7 @@ typedef CGAL::Distance_adapter typedef CGAL::Orthogonal_k_neighbor_search Neighbor_search_with_info; template -void search(bool nearest) +bool search(bool nearest) { const unsigned int N = 1000; const double cube_side_length = 1.0; @@ -71,6 +71,7 @@ void search(bool nearest) } } } + bool res=true; // the other points must be further/closer than min_dist { for(std::vector::iterator it = diff.begin(); @@ -80,22 +81,26 @@ void search(bool nearest) if(nearest){ if(dist < sep_dist){ std::cout << "Error: Point " << *it << " at distance " << dist << " < " << sep_dist << std::endl; + res=false; } } else { if(dist > sep_dist){ std::cout << "Error: Point " << *it << " at distance " << dist << " > " << sep_dist << std::endl; + res=false; } } } } + return res; } int main() { - search(true); - search(false); - search(true); - search(false); + bool res=true; + res&=search(true); + res&=search(false); + res&=search(true); + res&=search(false); std::cout << "done" << std::endl; - return 0; + return res ? 0 : 1; }