diff --git a/Spatial_searching/doc/Spatial_searching/CGAL/Fuzzy_iso_box.h b/Spatial_searching/doc/Spatial_searching/CGAL/Fuzzy_iso_box.h index 618b06a3fdc..2366cfa35ba 100644 --- a/Spatial_searching/doc/Spatial_searching/CGAL/Fuzzy_iso_box.h +++ b/Spatial_searching/doc/Spatial_searching/CGAL/Fuzzy_iso_box.h @@ -1,7 +1,7 @@ namespace CGAL { /*! -\ingroup RangeQueryItemClasses +\ingroup RangeQueryItemClasses The class `Fuzzy_iso_box` implements fuzzy `d`-dimensional iso boxes. A fuzzy iso box with fuzziness value \f$ \epsilon\f$ has as inner and outer approximations @@ -13,19 +13,19 @@ points may or may not be reported. Subsequently, points on the boundary of the inner and outer approximations may or may not be reported. Specifically when \f$ \epsilon = 0\f$, points on the boundary of the box may or may not be reported. -\tparam Traits must be a model of the concept -`SearchTraits`, for example `CGAL::Search_traits_2 >`. +\tparam Traits must be a model of the concept +`SearchTraits`, for example `CGAL::Search_traits_2 >`. \cgalModels `FuzzyQueryItem` -\sa `FuzzyQueryItem` +\sa `FuzzyQueryItem` */ template< typename Traits > class Fuzzy_iso_box { public: -/// \name Types +/// \name Types /// @{ /*! @@ -34,18 +34,18 @@ Dimension Tag. typedef unspecified_type D; /*! -Point type. -*/ -typedef Traits::Point_d Point_d; +Point type. +*/ +typedef Traits::Point_d Point_d; /*! -Number type. -*/ -typedef Traits::FT FT; +Number type. +*/ +typedef Traits::FT FT; -/// @} +/// @} -/// \name Creation +/// \name Creation /// @{ /*! @@ -62,13 +62,13 @@ Construct a fuzzy iso box specified by the minimal iso box containing `p` and `q \attention Only available in case `Traits` is `Search_traits_adapter`. -\pre `p` must be lexicographically smaller than `q`. -*/ -Fuzzy_iso_box(Traits::Base::Point_d p, Traits::Base::Point_d q, FT epsilon=FT(0), Traits t=Traits()); +\pre `p` must be lexicographically smaller than `q`. +*/ +Fuzzy_iso_box(Traits::Base::Point_d p, Traits::Base::Point_d q, FT epsilon=FT(0), Traits t=Traits()); -/// @} +/// @} -/// \name Operations +/// \name Operations /// @{ /*! diff --git a/Spatial_searching/doc/Spatial_searching/CGAL/Fuzzy_sphere.h b/Spatial_searching/doc/Spatial_searching/CGAL/Fuzzy_sphere.h index 79da75f1306..181ea1d312e 100644 --- a/Spatial_searching/doc/Spatial_searching/CGAL/Fuzzy_sphere.h +++ b/Spatial_searching/doc/Spatial_searching/CGAL/Fuzzy_sphere.h @@ -22,14 +22,14 @@ of radius \f$ r\f$ may or may not be reported. \cgalModels `FuzzyQueryItem` -\sa `FuzzyQueryItem` +\sa `FuzzyQueryItem` */ template< typename Traits > class Fuzzy_sphere { public: -/// \name Types +/// \name Types /// @{ /*! @@ -38,19 +38,19 @@ Dimension Tag. typedef unspecified_type D; /*! -Point type. -*/ -typedef Traits::Point_d Point_d; +Point type. +*/ +typedef Traits::Point_d Point_d; /*! -Number type. -*/ -typedef Traits::FT FT; +Number type. +*/ +typedef Traits::FT FT; -/// @} +/// @} -/// \name Creation -/// +/// \name Creation +/// /// @{ /*! @@ -62,12 +62,12 @@ Fuzzy_sphere(Point_d center, FT radius, FT epsilon=FT(0),Traits t=Traits()); /*! Construct a fuzzy sphere centered at `center` with radius `radius` and fuzziness value `epsilon`. \attention Only available in case `Traits` is `Search_traits_adapter`. -*/ -Fuzzy_sphere(Traits::Base::Point_d center, FT radius, FT epsilon=FT(0), Traits t=Traits()); +*/ +Fuzzy_sphere(Traits::Base::Point_d center, FT radius, FT epsilon=FT(0), Traits t=Traits()); -/// @} +/// @} -/// \name Operations +/// \name Operations /// @{ /*! diff --git a/Spatial_searching/doc/Spatial_searching/Spatial_searching.txt b/Spatial_searching/doc/Spatial_searching/Spatial_searching.txt index c7768822ca7..40ca743f96f 100644 --- a/Spatial_searching/doc/Spatial_searching/Spatial_searching.txt +++ b/Spatial_searching/doc/Spatial_searching/Spatial_searching.txt @@ -2,7 +2,7 @@ namespace CGAL { /*! -\mainpage User Manual +\mainpage User Manual \anchor Chapter_dD_Spatial_Searching \anchor ChapterUserSpatialSearching \cgalAutoToc @@ -92,14 +92,14 @@ neighbor must not be smaller than \f$ r/(1+\epsilon)\f$. Obviously, for the less exact the result. While searching the nearest neighbor the algorithm descends the kd-tree -and has to decide two things for each node : Which child node should be visited -first and could there be possible nearest neighbors in the other child. This +and has to decide two things for each node : Which child node should be visited +first and could there be possible nearest neighbors in the other child. This basically comes down to computing the distance to the further child, because the -distance to the closer child is the same as the one to the parent. There are +distance to the closer child is the same as the one to the parent. There are two options now:
-# In general, we compute the distance with the given metric. This is the k-neighbor search with a general distance class. --# For point queries we can "update" the distance, because it is only +-# For point queries we can "update" the distance, because it is only changed in one dimension at a time. This is the orthogonal k-neighbor search with an orthogonal distance class. The following example shows the orthogonal distance computation in detail: @@ -110,15 +110,15 @@ Orthogonal distance computation technique Assume we are searching the nearest neighbor, descending the kd-tree, with \f$ R_{p} \f$ as the parent rectangle and \f$ R_{lo} \f$ and \f$ R_{hi}\f$ as its childs in the current step. -Further assume \f$ R_{lo} \f$ is closer to query point \f$q\f$. Let \f$cd\f$ denote the cutting dimension and let +Further assume \f$ R_{lo} \f$ is closer to query point \f$q\f$. Let \f$cd\f$ denote the cutting dimension and let \f$cv\f$ denote the cutting value. At this point we already know the distance \f$rd_{p}\f$ -to the parent rectangle and need to check if \f$R_{hi}\f$ could contain +to the parent rectangle and need to check if \f$R_{hi}\f$ could contain nearest neighbors. Because \f$R_{lo}\f$ is the closer rectangle, its distance -to \f$q\f$, \f$rd_{lo}\f$, is the same as \f$rd_{p}\f$. -Notice that for each dimension \f$i \neq cd \f$, \f$ \mathrm{dists}_{lo}[i] = \mathrm{dists}_{hi}[i]\f$, -since these coordinates are not affected by the current cut. So the new distance along the +to \f$q\f$, \f$rd_{lo}\f$, is the same as \f$rd_{p}\f$. +Notice that for each dimension \f$i \neq cd \f$, \f$ \mathrm{dists}_{lo}[i] = \mathrm{dists}_{hi}[i]\f$, +since these coordinates are not affected by the current cut. So the new distance along the cutting dimension is \f$ \mathrm{dists}_{hi}[cd] = cv - q[cd]\f$. Now we can compute \f$rd_{hi}\f$ -in constant time (independent of dimension) with +in constant time (independent of dimension) with \f$rd_{hi} = rd_{p} - \mathrm{dists}_{lo}[cd]^2 + (cv - q[cd])^2\f$.
This strategy can be used if and only if the distance changes only in one dimension at a time, which is the case for point queries. @@ -126,25 +126,25 @@ which is the case for point queries. The following two classes implement the standard search strategy for orthogonal distances like the weighted Minkowski -distance. The second one is a specialization for incremental neighbor +distance. The second one is a specialization for incremental neighbor searching and distance browsing. Both require extendes nodes. `Orthogonal_k_neighbor_search` +OrthogonalDistance, Splitter, SpatialTree>` `Orthogonal_incremental_neighbor_search` +OrthogonalDistance, Splitter, SpatialTree>` The other two classes implement the standard search strategy for general distances like the Manhattan distance for iso-rectangle queries. -Again, the second one is a specialization for incremental neighbor +Again, the second one is a specialization for incremental neighbor searching and distance browsing . `K_neighbor_search` +Splitter, SpatialTree>` `Incremental_neighbor_search` +GeneralDistance, Splitter, SpatialTree>` \subsection Spatial_searchingRangeSearching Range Searching @@ -165,13 +165,13 @@ For range searching of large data sets, the user may set the parameter `bucket_s used in building the `kd` tree to a large value (e.g. 100), because in general the query time will be less than using the default value. -\section Spatial_SearchingSplitting_rule_section Splitting Rules +\section Spatial_SearchingSplitting_rule_section Splitting Rules Instead of using the default splitting rule `Sliding_midpoint` described below, -a user may, depending upon the data, select +a user may, depending upon the data, select one from the following splitting rules, -which determine how a separating hyperplane is computed. Every splitter has -degenerated worst cases, which may lead to a linear tree and a stack overflow. +which determine how a separating hyperplane is computed. Every splitter has +degenerated worst cases, which may lead to a linear tree and a stack overflow. Switching the splitting rule to one of a different kind will solve the problem.
@@ -219,7 +219,7 @@ along this dimension.
-The tree can become linear for the median rules, if many points are collinear in a dimension +The tree can become linear for the median rules, if many points are collinear in a dimension which is not the cutting dimension. \cgalFigureBegin{Spatial_searchingmedianworstcase, Median_worst_case.jpg} Median worst case point set in 2d.\n @@ -266,7 +266,7 @@ generate empty cells. \section Spatial_searchingExample Example Programs We give seven examples. The first example illustrates k nearest neighbor -searching, and the second example incremental neighbor searching. +searching, and the second example incremental neighbor searching. The third is an example of approximate furthest neighbor searching using a `d`-dimensional iso-rectangle as an query object. Approximate range searching is illustrated by the fourth example. The fifth @@ -280,10 +280,10 @@ scenarios for different splitter types. The first example illustrates k neighbor searching with an Euclidean distance and 2-dimensional points. The generated random data points are inserted in a search tree. We then initialize -the k neighbor search object with the origin as query. Finally, we +the k neighbor search object with the origin as query. Finally, we obtain the result of the computation in the form of an iterator range. The value of the iterator is a pair of a point and its square -distance to the query point. We use square distances, or transformed distances for other distance classes, as they are +distance to the query point. We use square distances, or transformed distances for other distance classes, as they are computationally cheaper. \cgalExample{Spatial_searching/nearest_neighbor_searching.cpp} @@ -308,7 +308,7 @@ This example program illustrates approximate nearest and furthest neighbor searching using 4-dimensional %Cartesian coordinates. Five approximate furthest neighbors of the query rectangle \f$ [0.1,0.2]^4\f$ are computed. Because the query object is a rectangle -we cannot use the orthogonal neighbor search. As in the previous +we cannot use the orthogonal neighbor search. As in the previous examples we first initialize a search tree, create the search object with the query, and obtain the result of the search as iterator range. @@ -327,18 +327,18 @@ The range queries are member functions of the `kd` tree class. The neighbor searching works with all \cgal kernels, as well as with user defined points and distance classes. -In this example we assume that the user provides the following 3-dimensional +In this example we assume that the user provides the following 3-dimensional points class. \cgalExample{Spatial_searching/Point.h} -We have put the glue layer in this file as well, that is a class that allows to +We have put the glue layer in this file as well, that is a class that allows to iterate over the %Cartesian coordinates of the point, and a class to construct such an iterator for a point. We next need a distance class \cgalExample{Spatial_searching/Distance.h} We are ready to put the pieces together. -The class `Search_traits<..>` ,which you see in the next file, is a mere +The class `Search_traits<..>` ,which you see in the next file, is a mere wrapper for all our defined types. The searching itself works exactly as for \cgal kernels. \cgalExample{Spatial_searching/user_defined_point_and_distance.cpp} @@ -373,7 +373,7 @@ Points are read from a `std::map`. The search tree stores integers of type `std: \subsubsection Spatial_searchingUsingSurfaceMesh Using a Point Property Map of a Polygonal Mesh -This example programs shows how to search the closest vertices of a `Surface_mesh` or, quite similar, of a +This example programs shows how to search the closest vertices of a `Surface_mesh` or, quite similar, of a `Polyhedron_3`. Points are stored in the polygonal mesh. The search tree stores vertex descriptors. The value type of the iterator of the neighbor searching algorithm is \link BGLSMGT `boost::graph_traits::vertex_descriptor` \endlink. @@ -386,19 +386,19 @@ The value type of the iterator of the neighbor searching algorithm is \link BGL This example program illustrates selecting a splitting rule and setting the maximal allowed bucket size. The only differences with -the first example are the declaration of the Fair +the first example are the declaration of the Fair splitting rule, needed to set the maximal allowed bucket size. \cgalExample{Spatial_searching/using_fair_splitting_rule.cpp} \subsection Spatial_searchingExampleforWorstCaseScenarios Example for Worst-Case Scenarios for Different Splitters -This example program has two 2-dimensional data sets: The first one containing +This example program has two 2-dimensional data sets: The first one containing collinear points with exponential increasing distances and the second one with collinear points in the firstdimension and one point with a distance -exceeding the spread of the other points in the second dimension. These are -the worst cases for the midpoint/median rules and can also occur in -higher dimensions. +exceeding the spread of the other points in the second dimension. These are +the worst cases for the midpoint/median rules and can also occur in +higher dimensions. \cgalExample{Spatial_searching/splitter_worst_cases.cpp} @@ -406,11 +406,11 @@ higher dimensions. \subsection OrthogonalPerfomance Performance of the Orthogonal Search -We took the gargoyle data set (Surface) from aim\@shape, and generated the same number of random points in the bbox of the gargoyle (Random). +We took the gargoyle data set (Surface) from aim\@shape, and generated the same number of random points in the bbox of the gargoyle (Random). We then consider three scenarios as data/queries. -The data set contains 800K points. For each query point we compute the K=10,20,30 closest points, with the default splitter and for the bucket size 10 (default) and 20. +The data set contains 800K points. For each query point we compute the K=10,20,30 closest points, with the default splitter and for the bucket size 10 (default) and 20. -The results were produced with the release 4.6 of \cgal, on an Intel i7 2.7 Ghz +The results were produced with the release 4.6 of \cgal, on an Intel i7 2.7 Ghz laptop with 16 GB RAM, compiled with Visual C++ 2012 with the /O2 option. The values are the average of ten tests each. @@ -419,12 +419,12 @@ The values are the average of ten tests each.
k | bucket size | Surface/Surface | Surface/Random | Random/Random --|------------:|-----------------:|---------------:|----------------: -10| 10 | 0.89 | 11.48 | 2.63 -10| 20 | 0.89 | 9.80 | 2.25 -20| 10 | 1.60 | 13.41 | 4.06 -20| 20 | 1.59 | 11.62 | 3.46 -30| 10 | 2.35 | 15.52 | 5.42 -30| 20 | 2.33 | 13.50 | 4.61 +10| 10 | 0.89 | 11.48 | 2.63 +10| 20 | 0.89 | 9.80 | 2.25 +20| 10 | 1.60 | 13.41 | 4.06 +20| 20 | 1.59 | 11.62 | 3.46 +30| 10 | 2.35 | 15.52 | 5.42 +30| 20 | 2.33 | 13.50 | 4.61
\cgalFigureBegin{Spatial_searchingfigbenchmark,gargoyle.png} @@ -434,7 +434,7 @@ Blue: Gargoyle surface. Green: Gargoyle bbox random. \section Spatial_searchingSoftware Software Design -\subsection Kd_tree_subsection The kd Tree +\subsection Kd_tree_subsection The kd Tree Bentley \cgalCite{b-mbstu-75} introduced the `kd` tree as a generalization of the binary search tree in higher dimensions. `kd` @@ -504,6 +504,6 @@ The initial implementation of this package was done by Hans Tangelder and Andreas Fabri. It was optimized in speed and memory consumption by Markus Overtheil during an internship at GeometryFactory in 2014. -*/ +*/ } /* namespace CGAL */ diff --git a/Spatial_searching/include/CGAL/Fuzzy_iso_box.h b/Spatial_searching/include/CGAL/Fuzzy_iso_box.h index 4266d263d5c..ce229908e1b 100644 --- a/Spatial_searching/include/CGAL/Fuzzy_iso_box.h +++ b/Spatial_searching/include/CGAL/Fuzzy_iso_box.h @@ -14,7 +14,7 @@ // // $URL$ // $Id$ -// +// // // Author(s) : Hans Tangelder () diff --git a/Spatial_searching/include/CGAL/Fuzzy_sphere.h b/Spatial_searching/include/CGAL/Fuzzy_sphere.h index b4edbec7679..7d2c01badbf 100644 --- a/Spatial_searching/include/CGAL/Fuzzy_sphere.h +++ b/Spatial_searching/include/CGAL/Fuzzy_sphere.h @@ -14,7 +14,7 @@ // // $URL$ // $Id$ -// +// // // Author(s) : Hans Tangelder () diff --git a/Spatial_searching/test/Spatial_searching/Circular_query.cpp b/Spatial_searching/test/Spatial_searching/Circular_query.cpp index 0475c07f256..4b6ca65a341 100644 --- a/Spatial_searching/test/Spatial_searching/Circular_query.cpp +++ b/Spatial_searching/test/Spatial_searching/Circular_query.cpp @@ -1,7 +1,7 @@ // 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 +// +// 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 @@ -26,12 +26,11 @@ typedef Point_with_info_helper::type 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; - + 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()), @@ -41,7 +40,7 @@ void run(std::list all_points){ // 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); @@ -80,7 +79,7 @@ void run(std::list all_points){ assert(CGAL::squared_distance(center,get_point(*pt))<=0.140625); // (0.25 + 0.125)² 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)² @@ -88,23 +87,22 @@ void run(std::list all_points){ } assert(CGAL::squared_distance(center,*pt) >= 0.015625); } - std::cout << "done" << std::endl; + std::cout << "done" << std::endl; } int main() { const int N=1000; - // generator for random data points in the square ( (-1,-1), (1,1) ) - Random_points_iterator rpit( 1.0); + // generator for random data points in the square ( (-1,-1), (1,1) ) + 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)); + run(all_points); run(all_points); return 0; } - 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 562e249ba57..15abb583eb1 100644 --- a/Spatial_searching/test/Spatial_searching/Iso_rectangle_2_query.cpp +++ b/Spatial_searching/test/Spatial_searching/Iso_rectangle_2_query.cpp @@ -28,13 +28,13 @@ template void run(std::list all_points) { 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()) ); - + Point p(0.1, 0.2); Point q(0.3, 0.5); typename SearchTraits::Point_d pp(p); @@ -57,7 +57,7 @@ void run(std::list all_points) 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)); } @@ -76,27 +76,27 @@ void run(std::list all_points) assert(! outer_ic.has_on_unbounded_side(get_point(*pt)) || outer_ic.has_on_boundary(get_point(*pt))); 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)); } - std::cout << "done" << std::endl; + std::cout << "done" << std::endl; } int main() { const int N=10000; - - // generator for random data points in the square ( (-1,-1), (1,1) ) + + // generator for random data points in the square ( (-1,-1), (1,1) ) 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)); + run(all_points); run(all_points); - + return 0; } diff --git a/Spatial_searching/test/Spatial_searching/Range_searching.cpp b/Spatial_searching/test/Spatial_searching/Range_searching.cpp index 3afb2c02ee0..09889a6caea 100644 --- a/Spatial_searching/test/Spatial_searching/Range_searching.cpp +++ b/Spatial_searching/test/Spatial_searching/Range_searching.cpp @@ -28,16 +28,16 @@ template void run(std::list all_points) { 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()) ); - + Point p(0.1, 0.2, 0.3); Point q(0.3, 0.5, 0.4); - + typename SearchTraits::Point_d pp(p); typename SearchTraits::Point_d qq(q); @@ -75,24 +75,24 @@ void run(std::list all_points) assert(! outer_ic.has_on_unbounded_side(get_point(*pt))); 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)); } - std::cout << "done" << std::endl; + std::cout << "done" << std::endl; } int main() { - // generator for random data points in the square ( (-1,-1), (1,1) ) + // generator for random data points in the square ( (-1,-1), (1,1) ) 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)); + run(all_points); run(all_points); - + return 0; } diff --git a/Spatial_searching/test/Spatial_searching/iso_rectangle_2_query_2.cpp b/Spatial_searching/test/Spatial_searching/iso_rectangle_2_query_2.cpp index 4a1acbec9a0..fc3ae4312fc 100644 --- a/Spatial_searching/test/Spatial_searching/iso_rectangle_2_query_2.cpp +++ b/Spatial_searching/test/Spatial_searching/iso_rectangle_2_query_2.cpp @@ -63,7 +63,7 @@ main() { Fuzzy_iso_box approximate_range(p, q, 0.1); tree.search(std::back_inserter( result ), approximate_range); std::cout << "The points in the fuzzy box [<0.1-0.3>,<0.6-0.9>]x[<0.1-0.3>,<0.6-0.9>] are: " - << std::endl; + << std::endl; std::copy (result.begin(), result.end(), std::ostream_iterator(std::cout,"\n") ); std::cout << std::endl; return 0;