mirror of https://github.com/CGAL/cgal
Merge branch 'Spatial_sorting-spatial_sorting_on_sphere-pmachado' of git://github.com/sloriot/cgal into sloriot-Spatial_sorting-spatial_sorting_on_sphere-pmachado
This commit is contained in:
commit
a0fcac7d94
|
|
@ -131,6 +131,13 @@ and <code>src/</code> directories).
|
|||
<!-- Mesh Generation -->
|
||||
<!-- Geometry Processing -->
|
||||
<!-- Spatial Searching and Sorting -->
|
||||
<h3>Spatial Sorting</h3>
|
||||
<ul>
|
||||
<li>Add the possibility to sort points on a sphere along
|
||||
a space-filling curve using the functions
|
||||
<code>CGAL::hilbert_sort_on_sphere</code> and
|
||||
<code>CGAL::spatial_sort_on_sphere</code>.</li>
|
||||
</ul>
|
||||
<!-- Geometric Optimization -->
|
||||
<!-- Interpolation -->
|
||||
<!-- Support Library -->
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ Hilbert_sort_2(const Traits &traits = Traits());
|
|||
/// @{
|
||||
|
||||
/*!
|
||||
sorts the range `[begin, end)`.
|
||||
It sorts the range `[begin, end)`.
|
||||
\tparam RandomAccessIterator must be an iterator with value type `Traits::Point_2`.
|
||||
*/
|
||||
template <class RandomAccessIterator> void operator() (RandomAccessIterator begin, RandomAccessIterator end) const;
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ Hilbert_sort_3(const Traits &traits = Traits());
|
|||
/// @{
|
||||
|
||||
/*!
|
||||
sorts the range `[begin, end)`.
|
||||
It sorts the range `[begin, end)`.
|
||||
\tparam RandomAccessIterator must be an iterator with value type `Traits::Point_3`.
|
||||
*/
|
||||
template <class RandomAccessIterator> void operator() (RandomAccessIterator begin, RandomAccessIterator end) const;
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ Hilbert_sort_d(const Traits &traits = Traits());
|
|||
/// @{
|
||||
|
||||
/*!
|
||||
sorts the range `[begin, end)`.
|
||||
It sorts the range `[begin, end)`.
|
||||
\tparam RandomAccessIterator must be an iteratoe with value type `Traits::Point_d`.
|
||||
*/
|
||||
template <class RandomAccessIterator> void operator() (RandomAccessIterator begin, RandomAccessIterator end) const;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
namespace CGAL {
|
||||
|
||||
/*!
|
||||
\ingroup PkgSpatialSortingFunctionObjects
|
||||
|
||||
The function object `Hilbert_sort_on_sphere_3` sorts iterator ranges of
|
||||
`Traits::Point_3` along a Hilbert curve on a given sphere. Actually, it approximates a Hilbert curve on
|
||||
that sphere by a Hilbert curve on a certain cube. For each face of that cube, it calls an appropriate
|
||||
version of `Hilbert_sort_2` which sorts a subset of the iterator range.
|
||||
`Hilbert_sort_2` in each face is called with the median or the middle policy depending on the `PolicyTag`. The input points are supposed to be close to the input sphere.
|
||||
If input points are not close to the input sphere, this function still works, but it might not be a good sorting function.
|
||||
|
||||
\tparam Traits must be a model for `SpatialSortingTraits_3`.
|
||||
|
||||
*/
|
||||
template< typename Traits, typename PolicyTag >
|
||||
class Hilbert_sort_on_sphere_3 {
|
||||
public:
|
||||
|
||||
/// \name Creation
|
||||
/// @{
|
||||
|
||||
/*!
|
||||
constructs an instance with `traits` as traits class instance, `sq_r` as the squared_radius of the given sphere,
|
||||
and `p` as the center of the given sphere.
|
||||
\pre The value of \f$sq\_r\f$ should be greater than 0.
|
||||
*/
|
||||
Hilbert_sort_on_sphere_3(const Traits &traits = Traits(),
|
||||
double sq_r = 1.0,
|
||||
const Traits::Point_3 &p = Traits::Point_3(0,0,0));
|
||||
|
||||
/// @}
|
||||
|
||||
/// \name Operations
|
||||
/// @{
|
||||
|
||||
/*!
|
||||
It sorts the range `[begin, end)` along a hilbert curve on the sphere centered at `p` with squared radius `sq_r`;
|
||||
these arguments are passed in the construction of the object `Hilbert_sort_on_sphere_3`.
|
||||
\tparam RandomAccessIterator must be an iterator with value type `Traits::Point_3`.
|
||||
*/
|
||||
template <class RandomAccessIterator> void operator() (RandomAccessIterator begin, RandomAccessIterator end) const;
|
||||
|
||||
/// @}
|
||||
|
||||
}; /* end Hilbert_sort_on_sphere_3 */
|
||||
} /* end namespace CGAL */
|
||||
|
|
@ -30,7 +30,7 @@ Multiscale_sort (const Sort &sort = Sort(), std::ptrdiff_t threshold = 1, double
|
|||
/// @{
|
||||
|
||||
/*!
|
||||
sorts the range `[begin, end)`.
|
||||
It sorts the range `[begin, end)`.
|
||||
\cgalRequires `Sort::operator()(RandomAccessIterator begin, RandomAccessIterator end)` is defined.
|
||||
*/
|
||||
template <class RandomAccessIterator> void operator() (RandomAccessIterator begin, RandomAccessIterator end) const;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ namespace CGAL {
|
|||
The function `hilbert_sort()` sorts an iterator range of points
|
||||
along a Hilbert curve.
|
||||
|
||||
sorts the range `[begin, end)` in place.
|
||||
It sorts the range `[begin, end)` in place.
|
||||
|
||||
The default traits class `Default_traits` is the kernel in which the type
|
||||
`std::iterator_traits<RandomAccessIterator>::%value_type` is defined.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
namespace CGAL {
|
||||
|
||||
/*!
|
||||
\ingroup PkgSpatialSortingFunctions
|
||||
|
||||
The function `hilbert_sort_on_sphere()` sorts an iterator range of points that are supposed to be close to a given sphere
|
||||
along a Hilbert curve on that same sphere.
|
||||
If input points are not close to the input sphere, this function still works, but it might not be a good sorting function.
|
||||
|
||||
It sorts the range `[begin, end)` in place.
|
||||
|
||||
The default traits class `Default_traits` is the kernel in which the type
|
||||
`std::iterator_traits<RandomAccessIterator>::%value_type` is defined.
|
||||
The default policy is `Hilbert_sort_median_policy()` and the
|
||||
other option is `Hilbert_sort_middle_policy()`.
|
||||
|
||||
The input sphere is given by a squared radius and a center, parameter `sqr_radius` and parameter `center` respectively.
|
||||
The default squared radius of the sphere is 1.0.
|
||||
The default center of the sphere is the origin (0,0,0).
|
||||
|
||||
\cgalHeading{Requirements}
|
||||
|
||||
<OL>
|
||||
<LI>`std::iterator_traits<RandomAccessIterator>::%value_type` is convertible to
|
||||
`Traits::Point_3`.
|
||||
<LI>`Traits` is a model for concept `SpatialSortingTraits_3`.
|
||||
</OL>
|
||||
|
||||
\cgalHeading{Precondition}
|
||||
|
||||
<OL>
|
||||
<LI>`sqr_radius` greater than 0.
|
||||
</OL>
|
||||
|
||||
\cgalHeading{Implementation}
|
||||
|
||||
Creates an instance of `Hilbert_sort_on_sphere<Traits, PolicyTag>`,
|
||||
and calls its `operator()`.
|
||||
|
||||
*/
|
||||
template <class RandomAccessIterator, class Traits, class PolicyTag>
|
||||
void
|
||||
hilbert_sort_on_sphere( RandomAccessIterator begin,
|
||||
RandomAccessIterator end,
|
||||
const Traits& traits = Default_traits,
|
||||
PolicyTag policy = Default_policy,
|
||||
double sqr_radius = 1.0,
|
||||
const Traits::Point_3 ¢er = Default_center);
|
||||
|
||||
} /* namespace CGAL */
|
||||
|
||||
|
|
@ -8,7 +8,7 @@ improves space locality. Two points close in the order will be close
|
|||
geometrically, and two points close geometrically will have a high probability
|
||||
of being close in the order.
|
||||
|
||||
sorts the range `[begin, end)` in place.
|
||||
It sorts the range `[begin, end)` in place.
|
||||
|
||||
The default traits class `Default_traits` is the kernel in which the type
|
||||
`std::iterator_traits<RandomAccessIterator>::%value_type` is defined.
|
||||
|
|
@ -16,7 +16,7 @@ The default traits class `Default_traits` is the kernel in which the type
|
|||
The default policy is `Hilbert_sort_median_policy()` and the
|
||||
other option is `Hilbert_sort_middle_policy()`.
|
||||
|
||||
The default values for the thresholds and the ratio depends on the dimension.
|
||||
The default values for the thresholds and the ratio depend on the dimension.
|
||||
|
||||
\cgalHeading{Requirements}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,70 @@
|
|||
namespace CGAL {
|
||||
|
||||
/*!
|
||||
\ingroup PkgSpatialSortingFunctions
|
||||
|
||||
The function `spatial_sort_on_sphere()` sorts an iterator range of points in a way that
|
||||
improves space locality with respect to the intrinsic metric on the sphere given as input.
|
||||
Two points close in the order will be close
|
||||
on the sphere, and two points close on the sphere will have a high probability
|
||||
of being close in the order. The input points are supposed to be close to the input sphere.
|
||||
If input points are not close to the input sphere, this function still works, but it might not be a good sorting function.
|
||||
|
||||
It sorts the range `[begin, end)` in place.
|
||||
|
||||
The default traits class `Default_traits` is the kernel in which the type
|
||||
`std::iterator_traits<RandomAccessIterator>::%value_type` is defined.
|
||||
|
||||
The default policy is `Hilbert_sort_median_policy()` and the
|
||||
other option is `Hilbert_sort_middle_policy()`.
|
||||
|
||||
The input sphere is given by a squared radius and a center, parameter `sqr_radius` and parameter `center` respectively.
|
||||
The default squared radius of the sphere is 1.0.
|
||||
The default center of the sphere is the origin (0,0,0).
|
||||
|
||||
\cgalHeading{Requirements}
|
||||
|
||||
<OL>
|
||||
<LI>`std::iterator_traits<RandomAccessIterator>::%value_type` is convertible to
|
||||
`Traits::Point_3`.
|
||||
<LI>`Traits` is a model for concept `SpatialSortingTraits_3`.
|
||||
</OL>
|
||||
|
||||
\cgalHeading{Precondition}
|
||||
|
||||
<OL>
|
||||
<LI>`sqr_radius` greater than 0.
|
||||
</OL>
|
||||
|
||||
|
||||
\cgalHeading{Implementation}
|
||||
|
||||
Creates an instance of `Multiscale_sort<Hilbert_sort_on_sphere_3>`
|
||||
where `Hilbert_sort_on_sphere_3` is an Hilbert sorting on the sphere object,
|
||||
and calls its `operator()`.
|
||||
|
||||
The `threshold_hilbert` is the minimal size of a point set to be
|
||||
subdivided recursively during Hilbert sorting, otherwise random order is used.
|
||||
The `threshold_multiscale` value is the minimal size for a sample to
|
||||
call the `Hilbert_sort_on_sphere_3` functor, otherwise random order is used.
|
||||
The `ratio` value is used to split the original set in two subsets,
|
||||
spatial sort is applied on the first subset of size
|
||||
`ratio`
|
||||
times the original size of the set, `Hilbert_sort_on_sphere_3` functor is applied on the
|
||||
second subset.
|
||||
|
||||
*/
|
||||
template <class RandomAccessIterator, class Traits, class PolicyTag>
|
||||
void
|
||||
spatial_sort_on_sphere( RandomAccessIterator begin,
|
||||
RandomAccessIterator end,
|
||||
const Traits& traits = Default_traits,
|
||||
PolicyTag policy = Default_policy,
|
||||
double sqr_radius = 1.0,
|
||||
const Traits::Point_3 ¢er = Default_center,
|
||||
std::ptrdiff_t threshold_hilbert=default,
|
||||
std::ptrdiff_t threshold_multiscale=default,
|
||||
double ratio=default);
|
||||
|
||||
} /* namespace CGAL */
|
||||
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
\ingroup PkgSpatialSortingConcepts
|
||||
\cgalConcept
|
||||
|
||||
All 3D spatial sorting algorithms provided in \cgal are parameterized
|
||||
All 3D spatial sorting algorithms, including sorting on the sphere, provided in \cgal are parameterized
|
||||
by a traits class `Traits`, which defines the
|
||||
primitives (objects and predicates) that the sorting algorithms use.
|
||||
`SpatialSortingTraits_3` defines the complete set of primitives required in these
|
||||
|
|
|
|||
|
|
@ -18,12 +18,11 @@
|
|||
|
||||
/*!
|
||||
\addtogroup PkgSpatialSorting
|
||||
\todo check generated documentation
|
||||
\cgalPkgDescriptionBegin{Spatial Sorting,PkgSpatialSortingSummary}
|
||||
\cgalPkgPicture{hilbert.png}
|
||||
\cgalPkgSummaryBegin
|
||||
\cgalPkgAuthors{Christophe Delage and Olivier Devillers}
|
||||
\cgalPkgDesc{This package provides functions for sorting geometric objects in two, three and higher dimensions, in order to improve efficiency of incremental geometric algorithms.}
|
||||
\cgalPkgDesc{This package provides functions for sorting geometric objects in two, three and higher dimensions, including on a sphere, in order to improve efficiency of incremental geometric algorithms.}
|
||||
\cgalPkgManuals{Chapter_Spatial_Sorting,PkgSpatialSorting}
|
||||
\cgalPkgSummaryEnd
|
||||
\cgalPkgShortInfoBegin
|
||||
|
|
@ -37,12 +36,15 @@
|
|||
|
||||
## Functions ##
|
||||
- `CGAL::spatial_sort()`
|
||||
- `CGAL::spatial_sort_on_sphere()`
|
||||
- `CGAL::hilbert_sort()`
|
||||
- `CGAL::hilbert_sort_on_sphere()`
|
||||
|
||||
## Function Objects ##
|
||||
- `CGAL::Multiscale_sort<Sort>`
|
||||
- `CGAL::Hilbert_sort_2<Traits, PolicyTag>`
|
||||
- `CGAL::Hilbert_sort_3<Traits, PolicyTag>`
|
||||
- `CGAL::Hilbert_sort_on_sphere_3<Traits, PolicyTag>`
|
||||
- `CGAL::Hilbert_sort_d<Traits, PolicyTag>`
|
||||
|
||||
## Traits classes ##
|
||||
|
|
|
|||
|
|
@ -63,43 +63,69 @@ Hilbert mapping
|
|||
\cgalFigureEnd
|
||||
|
||||
Now given a set of 2D points, they can be sorted in the order they have on such
|
||||
a space filling curve as illustrated in \cgalFigureRef{Spatial_sorting_fig_Hilbert_middle} :
|
||||
a space filling curve. Note that at each step, we split a square exactly at its center; we call this
|
||||
subdivision policy: \f$middle\f$ policy (see \cgalFigureRef{Spatial_sorting_fig_Hilbert_median}).
|
||||
|
||||
\cgalFigureBegin{Spatial_sorting_fig_Hilbert_middle,Hilbert-middle.png}
|
||||
Hilbert sort with middle policy
|
||||
\cgalFigureEnd
|
||||
|
||||
If instead of subdividing the square in a fixed way at its center,
|
||||
as above, we subdivide it
|
||||
by splitting at the median point (in \f$ x\f$ or \f$ y\f$ directions alternating),
|
||||
we construct a 2-d tree adapted to the point set. This tree can be visited in a
|
||||
similar manner and we get also a suitable ordering of the points; we call this
|
||||
subdivision policy: \f$median\f$ policy (see \cgalFigureRef{Spatial_sorting_fig_Hilbert_median}).
|
||||
|
||||
\cgalFigureBegin{Spatial_sorting_fig_Hilbert_median,Hilbert-median.png}
|
||||
Hilbert sort with median policy
|
||||
\cgalFigureEnd
|
||||
|
||||
The middle policy is easier to analyze, and is interesting in practice
|
||||
for well distributed set of points in small dimension (if the number
|
||||
of points is really smaller than \f$ 2^d\f$).
|
||||
The median policy should be preferred for high dimension or if
|
||||
the point set distribution is not regular (or unknown).
|
||||
Since the median policy cannot be much worse than the middle
|
||||
policy, while the converse can happen, the median policy is the
|
||||
default behavior.
|
||||
Most theoretical results are using the middle policy
|
||||
\cgalCite{acr-icb-03}, \cgalCite{bg-sfche-89}, \cgalCite{b-aahsf-71}, \cgalCite{pb-scpts-89}.
|
||||
|
||||
\cgal provides Hilbert sorting for points in 2D, 3D and higher dimensions,
|
||||
in the middle and the median policies.
|
||||
|
||||
We also consider space filling curves on a given sphere. The method is described for the unit sphere below; it works on any sphere by an affine transformation.
|
||||
The points to be sorted are supposed to be close to the sphere.
|
||||
|
||||
Actually, we approximate a space filling curve on
|
||||
the unit sphere by a space filling curve on a cube (with facets at \f$x, y, z = \pm 1/\sqrt{3}\f$).
|
||||
Roughly speaking, we split the original set of points in six subsets corresponding to the six facets of the cube. The subset corresponding to a facet \f$f\f$ is the set of points that lie in the half-space defined by the supporting plane of \f$f\f$ that does not contain the origin. And then we basically use the 2D Hilbert sort with its corresponding policy, as explained above for the projection of the points in each subset on its corresponding facet of the cube. The axes orientation on each facet is chosen so that the space filling curve covers the whole cube without any jump; see \cgalFigureRef{Spatial_sorting_fig_Faces_orientations}.
|
||||
A point can lie in more than one such half-plane, so, we give a priority for each facet of the cube. The priority order is:
|
||||
first, the facet of the cube at \f$x = 1/\sqrt{3}\f$; second, the facet of the cube at \f$y = 1/\sqrt{3}\f$; third, the facet of the cube at \f$ x = -1/\sqrt{3}\f$; fourth, the facet of the cube at \f$ z = 1/\sqrt{3}\f$; fifth, the facet of the cube at \f$ y = -1/\sqrt{3}\f$; and, sixth, the facet of the cube at \f$ z = -1/\sqrt{3}\f$.
|
||||
|
||||
If points are not close to the sphere, they are still sorted the same way, however there is no guarantee that such an order is good anymore.
|
||||
|
||||
\cgalFigureBegin{Spatial_sorting_fig_Faces_orientations,HilbertOnSphere.png}
|
||||
A 2D Hilbert sort for each facet of the cube
|
||||
\cgalFigureEnd
|
||||
|
||||
Points sorted on the sphere according to the description above are depicted in \cgalFigureRef{Spatial_sorting_fig_Hilbert_on_sphere}.
|
||||
|
||||
\cgalFigureBegin{Spatial_sorting_fig_Hilbert_on_sphere,HilbertOnSphereIllustration.png}
|
||||
Hilbert sort on the sphere
|
||||
\cgalFigureEnd
|
||||
|
||||
|
||||
\subsection Spatial_sortingExamples Examples
|
||||
|
||||
The code to use Hilbert sort is as simple as the following example:
|
||||
|
||||
\cgalExample{Spatial_sorting/hilbert.cpp}
|
||||
|
||||
If instead of subdividing the square in a fixed way at its middle point,
|
||||
as above, we subdivide it
|
||||
by splitting at the median point (in \f$ x\f$ or \f$ y\f$ directions alternating),
|
||||
we construct a 2-d tree adapted to the point set. This tree can be visited in a
|
||||
similar manner and we get also a suitable ordering of the points
|
||||
(see \cgalFigureRef{Spatial_sorting_fig_Hilbert_median}).
|
||||
The following example shows how to perform a Hilbert sort on a sphere.
|
||||
|
||||
\cgalFigureBegin{Spatial_sorting_fig_Hilbert_median,Hilbert-median.png}
|
||||
Hilbert sort with median policy
|
||||
\cgalFigureEnd
|
||||
|
||||
|
||||
\cgal provides Hilbert sorting for points in 2D, 3D and higher dimensions,
|
||||
in the middle and the median policies.
|
||||
|
||||
The middle policy is easier to analyze, and is interesting in practice
|
||||
for well distributed set of points in small dimension (if the number
|
||||
of points is really smaller than \f$ 2^d\f$).
|
||||
The median policy should be prefered for high dimension or if
|
||||
the point set distribution is not regular (or unknown).
|
||||
Since the median policy cannot be much worse than the middle
|
||||
policy, while the converse can happen, the median policy is the
|
||||
default behavior.
|
||||
Most theoretical results are using the middle policy
|
||||
\cgalCite{acr-icb-03}, \cgalCite{b-aahsf-71}, \cgalCite{bg-sfche-89},pb-scpts-89.
|
||||
\cgalExample{Spatial_sorting/hilbert_sort_on_sphere.cpp}
|
||||
|
||||
This other example illustrates the use of the two different policies
|
||||
|
||||
|
|
@ -133,6 +159,10 @@ Delaunay with median spatial sort... done in 0.022415 seconds.
|
|||
|
||||
\cgalExample{Spatial_sorting/small_example_delaunay_2.cpp}
|
||||
|
||||
Spatial sort can be performed on the sphere as well, as shown in the following example.
|
||||
|
||||
\cgalExample{Spatial_sorting/spatial_sort_on_sphere.cpp}
|
||||
|
||||
\subsection Spatial_sortingUsingYourOwnPointType Using Your Own Point Type
|
||||
|
||||
If you want to sort points of your own point type,
|
||||
|
|
@ -178,6 +208,13 @@ In this example program, the sorted sequence of points is retrieved
|
|||
using the indices of the points in a vector of pairs of points and integers.
|
||||
\cgalExample{Spatial_sorting/sp_sort_using_property_map_d.cpp}
|
||||
|
||||
\section Spatial_sortingDesign Design and Implementation History
|
||||
|
||||
The first implementation of Hilbert and spatial sorting (2D and 3D) in CGAL was done by Cristophe Delage. Then, Olivier Devillers improved its design,
|
||||
and implemented its multidimensional version. Finally, Pedro Machado Manhaes de Castro and Olivier Devillers added Hilbert sorting
|
||||
on the sphere as well.
|
||||
|
||||
|
||||
*/
|
||||
} /* namespace CGAL */
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@
|
|||
\example Spatial_sorting/hilbert.cpp
|
||||
\example Spatial_sorting/hilbert_policies.cpp
|
||||
\example Spatial_sorting/small_example_delaunay_2.cpp
|
||||
\example Spatial_sorting/hilbert_sort_on_sphere.cpp
|
||||
\example Spatial_sorting/myPoint.cpp
|
||||
\example Spatial_sorting/sp_sort_using_property_map_2.cpp
|
||||
\example Spatial_sorting/sp_sort_using_property_map_3.cpp
|
||||
\example Spatial_sorting/sp_sort_using_property_map_d.cpp
|
||||
\example Spatial_sorting/spatial_sort_on_sphere.cpp
|
||||
*/
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 56 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 95 KiB |
Binary file not shown.
|
|
@ -0,0 +1,49 @@
|
|||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/point_generators_3.h>
|
||||
#include <CGAL/hilbert_sort_on_sphere.h>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
||||
typedef K::Point_3 Point;
|
||||
typedef K::Vector_3 Vector;
|
||||
typedef K::Sphere_3 Sphere;
|
||||
typedef CGAL::Creator_uniform_3<double,Point> Creator_3;
|
||||
|
||||
int main ()
|
||||
{
|
||||
std::size_t size = 32;
|
||||
CGAL::Random random (42);
|
||||
std::vector<Point> v;
|
||||
|
||||
// unit sphere
|
||||
std::cout << "UNIT SPHERE: " << std::endl;
|
||||
|
||||
v.reserve(size);
|
||||
|
||||
CGAL::Random_points_on_sphere_3<Point> unit_sphere(1.0, random); // generate points
|
||||
for (std::size_t i = 0; i < size; ++i) v.push_back(*unit_sphere++);
|
||||
|
||||
CGAL::hilbert_sort_on_sphere(v.begin(), v.end()); // sort
|
||||
|
||||
for(std::size_t i=0; i<size; ++i) std::cout << v[i] << std::endl; //output
|
||||
|
||||
v.clear();
|
||||
|
||||
// given sphere
|
||||
std::cout << "GIVEN SPHERE: " << std::endl;
|
||||
|
||||
v.reserve(size);
|
||||
|
||||
Vector trans = Vector(3,4,5);
|
||||
Sphere sphere = Sphere(CGAL::ORIGIN + trans, 4);
|
||||
CGAL::Random_points_on_sphere_3<Point> given_sphere(2.0, random); // generate points
|
||||
for (std::size_t i = 0; i < size; ++i) v.push_back(*given_sphere++ + trans);
|
||||
|
||||
CGAL::hilbert_sort_on_sphere(v.begin(), v.end(), // sort
|
||||
sphere.squared_radius(), sphere.center());
|
||||
|
||||
for(std::size_t i=0; i<size; ++i) std::cout << v[i] << std::endl; //output
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/point_generators_3.h>
|
||||
#include <CGAL/spatial_sort_on_sphere.h>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
||||
typedef K::Point_3 Point;
|
||||
typedef K::Vector_3 Vector;
|
||||
typedef K::Sphere_3 Sphere;
|
||||
typedef CGAL::Creator_uniform_3<double,Point> Creator_3;
|
||||
|
||||
int main ()
|
||||
{
|
||||
std::size_t size = 32;
|
||||
CGAL::Random random (42);
|
||||
std::vector<Point> v;
|
||||
|
||||
// unit sphere
|
||||
std::cout << "UNIT SPHERE: " << std::endl;
|
||||
|
||||
v.reserve(size);
|
||||
|
||||
CGAL::Random_points_on_sphere_3<Point> unit_sphere(1.0, random); // generate points
|
||||
for (std::size_t i = 0; i < size; ++i) v.push_back(*unit_sphere++);
|
||||
|
||||
CGAL::spatial_sort_on_sphere(v.begin(), v.end()); // sort
|
||||
|
||||
for(std::size_t i=0; i<size; ++i) std::cout << v[i] << std::endl; //output
|
||||
|
||||
v.clear();
|
||||
|
||||
// given sphere
|
||||
std::cout << "GIVEN SPHERE: " << std::endl;
|
||||
|
||||
v.reserve(size);
|
||||
|
||||
Vector trans = Vector(3,4,5);
|
||||
Sphere sphere = Sphere(CGAL::ORIGIN + trans, 4);
|
||||
CGAL::Random_points_on_sphere_3<Point> given_sphere(2.0, random); // generate points
|
||||
for (std::size_t i = 0; i < size; ++i) v.push_back(*given_sphere++ + trans);
|
||||
|
||||
CGAL::spatial_sort_on_sphere(v.begin(), v.end(), // sort
|
||||
sphere.squared_radius(), sphere.center());
|
||||
|
||||
for(std::size_t i=0; i<size; ++i) std::cout << v[i] << std::endl; //output
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -125,9 +125,26 @@ public:
|
|||
template <class RandomAccessIterator>
|
||||
void operator() (RandomAccessIterator begin, RandomAccessIterator end) const
|
||||
{
|
||||
Bbox_2 box=bbox_2(begin, end);
|
||||
sort <0, false, false> (begin, end,
|
||||
box.xmin(), box.ymin(), box.xmax(), box.ymax());
|
||||
//Bbox_2 box=bbox_2(begin, end); BUG: WE NEED TO FIX THIS
|
||||
|
||||
K k;
|
||||
double xmin=to_double(k.compute_x_2_object()(*begin)),
|
||||
ymin=to_double(k.compute_y_2_object()(*begin)),
|
||||
xmax=xmin,
|
||||
ymax=ymin;
|
||||
|
||||
for(RandomAccessIterator it=begin+1; it<end; ++it){
|
||||
if ( to_double(k.compute_x_2_object()(*it)) < xmin)
|
||||
xmin = to_double(k.compute_x_2_object()(*it));
|
||||
if ( to_double(k.compute_y_2_object()(*it)) < ymin)
|
||||
ymin = to_double(k.compute_y_2_object()(*it));
|
||||
if ( to_double(k.compute_x_2_object()(*it)) > xmax)
|
||||
xmax = to_double(k.compute_x_2_object()(*it));
|
||||
if ( to_double(k.compute_y_2_object()(*it)) > ymax)
|
||||
ymax = to_double(k.compute_y_2_object()(*it));
|
||||
}
|
||||
|
||||
sort <0, false, false> (begin, end, xmin, ymin, xmax, ymax);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,119 @@
|
|||
// Copyright (c) 2013 INRIA Sophia-Antipolis (France).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// Licensees holding a valid commercial license may use this file in
|
||||
// accordance with the commercial license agreement provided with the software.
|
||||
//
|
||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
//
|
||||
// Author(s) : Olivier Devillers
|
||||
// Pedro Machado Manhaes de Castro
|
||||
|
||||
#ifndef CGAL_HILBERT_SORT_ON_SPHERE_3_H
|
||||
#define CGAL_HILBERT_SORT_ON_SPHERE_3_H
|
||||
|
||||
#include <CGAL/Hilbert_sort_2.h>
|
||||
#include <CGAL/internal/Transform_coordinates_traits_3.h>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template <class K, class Hilbert_policy >
|
||||
class Hilbert_sort_on_sphere_3 {
|
||||
typedef typename K::Point_3 Point_3;
|
||||
|
||||
static const double _sqrt_of_one_over_three;
|
||||
|
||||
// Face 1, x > sqrt(1/3)
|
||||
// Face 2, y > sqrt(1/3)
|
||||
// Face 3, x < -sqrt(1/3)
|
||||
// Face 4, z > sqrt(1/3)
|
||||
// Face 5, y < -sqrt(1/3)
|
||||
// Face 6, z < -sqrt(1/3)
|
||||
|
||||
typedef internal::Transform_coordinates_traits_3<K,0,1,1,0> Face_1_traits_3; // +y +z
|
||||
typedef internal::Transform_coordinates_traits_3<K,-1,0,1,0> Face_2_traits_3; // -x +z
|
||||
typedef internal::Transform_coordinates_traits_3<K,0,1,-1,1> Face_3_traits_3; // +z -y
|
||||
typedef internal::Transform_coordinates_traits_3<K,-1,1,0,1> Face_4_traits_3; // -y +x
|
||||
typedef internal::Transform_coordinates_traits_3<K,-1,0,1,1> Face_5_traits_3; // -z +x
|
||||
typedef internal::Transform_coordinates_traits_3<K,1,1,0,0> Face_6_traits_3; // +x +y
|
||||
|
||||
Hilbert_sort_2<Face_1_traits_3, Hilbert_policy > _hs_1_object;
|
||||
Hilbert_sort_2<Face_2_traits_3, Hilbert_policy > _hs_2_object;
|
||||
Hilbert_sort_2<Face_3_traits_3, Hilbert_policy > _hs_3_object;
|
||||
Hilbert_sort_2<Face_4_traits_3, Hilbert_policy > _hs_4_object;
|
||||
Hilbert_sort_2<Face_5_traits_3, Hilbert_policy > _hs_5_object;
|
||||
Hilbert_sort_2<Face_6_traits_3, Hilbert_policy > _hs_6_object;
|
||||
K _k;
|
||||
Point_3 _p;
|
||||
double _sq_r;
|
||||
|
||||
public:
|
||||
Hilbert_sort_on_sphere_3 (const K &k=K(),
|
||||
double sq_r = 1.0,
|
||||
const Point_3 &p = Point_3(0,0,0),
|
||||
std::ptrdiff_t limit=1)
|
||||
: _hs_1_object(Face_1_traits_3(),limit),
|
||||
_hs_2_object(Face_2_traits_3(),limit),
|
||||
_hs_3_object(Face_3_traits_3(),limit),
|
||||
_hs_4_object(Face_4_traits_3(),limit),
|
||||
_hs_5_object(Face_5_traits_3(),limit),
|
||||
_hs_6_object(Face_6_traits_3(),limit),
|
||||
_k(k), _p(p), _sq_r(sq_r)
|
||||
{
|
||||
CGAL_precondition( sq_r > 0 );
|
||||
}
|
||||
|
||||
|
||||
template <class RandomAccessIterator>
|
||||
void operator()(RandomAccessIterator begin, RandomAccessIterator end) const {
|
||||
typedef typename std::iterator_traits<RandomAccessIterator>::value_type Point;
|
||||
std::vector< Point > vec[6];
|
||||
|
||||
const double mulcte = _sqrt_of_one_over_three * CGAL_NTS sqrt(_sq_r);
|
||||
const double lxi = _p.x() - mulcte, lxs = _p.x() + mulcte;
|
||||
const double lyi = _p.y() - mulcte, lys = _p.y() + mulcte;
|
||||
const double lzs = _p.z() + mulcte;
|
||||
|
||||
for(RandomAccessIterator i = begin; i != end; ++i) {
|
||||
const Point &p = *i;
|
||||
const typename K::FT x = _k.compute_x_3_object()(p);
|
||||
const typename K::FT y = _k.compute_y_3_object()(p);
|
||||
const typename K::FT z = _k.compute_z_3_object()(p); // for unit sphere
|
||||
if(x > lxs) vec[0].push_back(p); // Face 1, x > sqrt(1/3)
|
||||
else if(y > lys) vec[1].push_back(p); // Face 2, y > sqrt(1/3)
|
||||
else if(x < lxi) vec[2].push_back(p); // Face 3, x < -sqrt(1/3)
|
||||
else if(z > lzs) vec[3].push_back(p); // Face 4, z > sqrt(1/3)
|
||||
else if(y < lyi) vec[4].push_back(p); // Face 5, y < -sqrt(1/3)
|
||||
else vec[5].push_back(p); // Face 6, z < -sqrt(1/3)
|
||||
}
|
||||
if(vec[0].size()) _hs_1_object(vec[0].begin(), vec[0].end());
|
||||
if(vec[1].size()) _hs_2_object(vec[1].begin(), vec[1].end());
|
||||
if(vec[2].size()) _hs_3_object(vec[2].begin(), vec[2].end());
|
||||
if(vec[3].size()) _hs_4_object(vec[3].begin(), vec[3].end());
|
||||
if(vec[4].size()) _hs_5_object(vec[4].begin(), vec[4].end());
|
||||
if(vec[5].size()) _hs_6_object(vec[5].begin(), vec[5].end());
|
||||
|
||||
// this is the order that set of points in a face should appear
|
||||
// after sorting points wrt each face
|
||||
for(int i=0; i<6; i++)
|
||||
for(std::size_t j=0; j<vec[i].size(); j++)
|
||||
*begin++ = vec[i][j];
|
||||
}
|
||||
};
|
||||
template <class K, class Hilbert_policy >
|
||||
const double Hilbert_sort_on_sphere_3<K,Hilbert_policy>::_sqrt_of_one_over_three = 0.57735026919;
|
||||
|
||||
} // namespace CGAL
|
||||
|
||||
#endif//CGAL_HILBERT_SORT_ON_SPHERE_3_H
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
// $Id$
|
||||
//
|
||||
// Author(s) : Christophe Delage
|
||||
// : Olivier Devillers
|
||||
//
|
||||
|
||||
#ifndef CGAL_HILBERT_SORT_H
|
||||
#define CGAL_HILBERT_SORT_H
|
||||
|
|
@ -89,9 +89,6 @@ namespace internal {
|
|||
#endif
|
||||
(Hilbert_sort_d<Kernel, Policy> (k))(begin, end);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
template <class RandomAccessIterator>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,110 @@
|
|||
// Copyright (c) 2015 INRIA Sophia-Antipolis (France).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// Licensees holding a valid commercial license may use this file in
|
||||
// accordance with the commercial license agreement provided with the software.
|
||||
//
|
||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
//
|
||||
// Author(s) : Olivier Devillers
|
||||
// : Pedro Machado Manhaes de Castro
|
||||
|
||||
#ifndef CGAL_HILBERT_SORT_ON_SPHERE_H
|
||||
#define CGAL_HILBERT_SORT_ON_SPHERE_H
|
||||
|
||||
#include <CGAL/hilbert_sort.h>
|
||||
#include <CGAL/Hilbert_sort_on_sphere_3.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
namespace internal {
|
||||
|
||||
template <class RandomAccessIterator, class Kernel, class Policy>
|
||||
void hilbert_sort_on_sphere (RandomAccessIterator begin,
|
||||
RandomAccessIterator end,
|
||||
const Kernel &k,
|
||||
Policy,
|
||||
typename Kernel::Point_3 *,
|
||||
double sq_r,
|
||||
const typename Kernel::Point_3 &p)
|
||||
{
|
||||
boost::rand48 random;
|
||||
boost::random_number_generator<boost::rand48> rng(random);
|
||||
std::random_shuffle(begin,end, rng);
|
||||
(Hilbert_sort_on_sphere_3<Kernel, Policy> (k,sq_r,p))(begin, end);
|
||||
}
|
||||
|
||||
} //end of namespace internal
|
||||
|
||||
template <class RandomAccessIterator>
|
||||
void hilbert_sort_on_sphere (RandomAccessIterator begin, RandomAccessIterator end,
|
||||
double sq_r = 1.0,
|
||||
const typename CGAL::Kernel_traits<typename std::iterator_traits<RandomAccessIterator>::value_type>::Kernel::Point_3 &p =
|
||||
typename CGAL::Kernel_traits<typename std::iterator_traits<RandomAccessIterator>::value_type>::Kernel::Point_3(0,0,0))
|
||||
{
|
||||
|
||||
typedef std::iterator_traits<RandomAccessIterator> ITraits;
|
||||
typedef typename ITraits::value_type value_type;
|
||||
typedef CGAL::Kernel_traits<value_type> KTraits;
|
||||
typedef typename KTraits::Kernel Kernel;
|
||||
|
||||
internal::hilbert_sort_on_sphere(begin, end, Kernel(), Hilbert_sort_median_policy(),
|
||||
static_cast<value_type *> (0), sq_r, p);
|
||||
|
||||
}
|
||||
|
||||
template <class RandomAccessIterator>
|
||||
void hilbert_sort_on_sphere (RandomAccessIterator begin, RandomAccessIterator end, Hilbert_sort_median_policy policy,
|
||||
double sq_r = 1.0,
|
||||
const typename CGAL::Kernel_traits<typename std::iterator_traits<RandomAccessIterator>::value_type>::Kernel::Point_3 &p =
|
||||
typename CGAL::Kernel_traits<typename std::iterator_traits<RandomAccessIterator>::value_type>::Kernel::Point_3(0,0,0))
|
||||
{
|
||||
typedef std::iterator_traits<RandomAccessIterator> ITraits;
|
||||
typedef typename ITraits::value_type value_type;
|
||||
typedef CGAL::Kernel_traits<value_type> KTraits;
|
||||
typedef typename KTraits::Kernel Kernel;
|
||||
|
||||
internal::hilbert_sort_on_sphere(begin, end, Kernel(), policy,
|
||||
static_cast<value_type *> (0), sq_r, p);
|
||||
}
|
||||
|
||||
|
||||
template <class RandomAccessIterator>
|
||||
void hilbert_sort_on_sphere (RandomAccessIterator begin, RandomAccessIterator end, Hilbert_sort_middle_policy policy,
|
||||
double sq_r = 1.0,
|
||||
const typename CGAL::Kernel_traits<typename std::iterator_traits<RandomAccessIterator>::value_type>::Kernel::Point_3 &p =
|
||||
typename CGAL::Kernel_traits<typename std::iterator_traits<RandomAccessIterator>::value_type>::Kernel::Point_3(0,0,0))
|
||||
{
|
||||
typedef std::iterator_traits<RandomAccessIterator> ITraits;
|
||||
typedef typename ITraits::value_type value_type;
|
||||
typedef CGAL::Kernel_traits<value_type> KTraits;
|
||||
typedef typename KTraits::Kernel Kernel;
|
||||
|
||||
internal::hilbert_sort_on_sphere(begin, end, Kernel(), policy,
|
||||
static_cast<value_type *> (0), sq_r, p);
|
||||
}
|
||||
|
||||
|
||||
template <class RandomAccessIterator, class Kernel, class Policy>
|
||||
void hilbert_sort_on_sphere (RandomAccessIterator begin, RandomAccessIterator end, const Kernel &k, Policy policy,
|
||||
double sq_r = 1.0, const typename Kernel::Point_3 &p = typename Kernel::Point_3(0,0,0))
|
||||
{
|
||||
typedef std::iterator_traits<RandomAccessIterator> ITraits;
|
||||
typedef typename ITraits::value_type value_type;
|
||||
|
||||
internal::hilbert_sort_on_sphere(begin, end,
|
||||
k, policy, static_cast<value_type *> (0), sq_r, p);
|
||||
}
|
||||
|
||||
} // end of namespace CGAL
|
||||
|
||||
#endif // CGAL_HILBERT_SORT_ON_SPHERE_H
|
||||
|
|
@ -0,0 +1,267 @@
|
|||
// Copyright (c) 2013 INRIA Sophia-Antipolis (France).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// Licensees holding a valid commercial license may use this file in
|
||||
// accordance with the commercial license agreement provided with the software.
|
||||
//
|
||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
//
|
||||
// Author(s) : Olivier Devillers
|
||||
// Pedro Machado Manhaes de Castro
|
||||
|
||||
#ifndef CGAL_INTERNAL_SCALE_COORDINATES_ADAPTOR_TRAITS_3_H
|
||||
#define CGAL_INTERNAL_SCALE_COORDINATES_ADAPTOR_TRAITS_3_H
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
namespace internal {
|
||||
|
||||
template <int x, int y, int z, int ord>
|
||||
struct Transform_constant_struct;
|
||||
|
||||
template <> struct Transform_constant_struct<1,1,0,0> { enum {value = 0}; };
|
||||
template <> struct Transform_constant_struct<-1,1,0,0> { enum {value = 1}; };
|
||||
template <> struct Transform_constant_struct<1,-1,0,0> { enum {value = 2}; };
|
||||
template <> struct Transform_constant_struct<-1,-1,0,0> { enum {value = 3}; };
|
||||
template <> struct Transform_constant_struct<1,1,0,1> { enum {value = 4}; };
|
||||
template <> struct Transform_constant_struct<-1,1,0,1> { enum {value = 5}; };
|
||||
template <> struct Transform_constant_struct<1,-1,0,1> { enum {value = 6}; };
|
||||
template <> struct Transform_constant_struct<-1,-1,0,1> { enum {value = 7}; };
|
||||
|
||||
template <> struct Transform_constant_struct<1,0,1,0> { enum {value = 8}; };
|
||||
template <> struct Transform_constant_struct<-1,0,1,0> { enum {value = 9}; };
|
||||
template <> struct Transform_constant_struct<1,0,-1,0> { enum {value = 10}; };
|
||||
template <> struct Transform_constant_struct<-1,0,-1,0> { enum {value = 11}; };
|
||||
template <> struct Transform_constant_struct<1,0,1,1> { enum {value = 12}; };
|
||||
template <> struct Transform_constant_struct<-1,0,1,1> { enum {value = 13}; };
|
||||
template <> struct Transform_constant_struct<1,0,-1,1> { enum {value = 14}; };
|
||||
template <> struct Transform_constant_struct<-1,0,-1,1> { enum {value = 15}; };
|
||||
|
||||
template <> struct Transform_constant_struct<0,1,1,0> { enum {value = 16}; };
|
||||
template <> struct Transform_constant_struct<0,-1,1,0> { enum {value = 17}; };
|
||||
template <> struct Transform_constant_struct<0,1,-1,0> { enum {value = 18}; };
|
||||
template <> struct Transform_constant_struct<0,-1,-1,0> { enum {value = 19}; };
|
||||
template <> struct Transform_constant_struct<0,1,1,1> { enum {value = 20}; };
|
||||
template <> struct Transform_constant_struct<0,-1,1,1> { enum {value = 21}; };
|
||||
template <> struct Transform_constant_struct<0,1,-1,1> { enum {value = 22}; };
|
||||
template <> struct Transform_constant_struct<0,-1,-1,1> { enum {value = 23}; };
|
||||
|
||||
template <class R, int opt>
|
||||
struct Coordinate_value_adaptor;
|
||||
|
||||
template <class R>
|
||||
struct Coordinate_value_adaptor<R,0> {
|
||||
static typename R::FT x(const typename R::Point_3& p) {return p.x();}
|
||||
static typename R::FT y(const typename R::Point_3& p) {return p.y();}
|
||||
};
|
||||
|
||||
template <class R>
|
||||
struct Coordinate_value_adaptor<R,1> {
|
||||
static typename R::FT x(const typename R::Point_3& p) {return -p.x();}
|
||||
static typename R::FT y(const typename R::Point_3& p) {return p.y();}
|
||||
};
|
||||
|
||||
template <class R>
|
||||
struct Coordinate_value_adaptor<R,2> {
|
||||
static typename R::FT x(const typename R::Point_3& p) {return p.x();}
|
||||
static typename R::FT y(const typename R::Point_3& p) {return -p.y();}
|
||||
};
|
||||
|
||||
template <class R>
|
||||
struct Coordinate_value_adaptor<R,3> {
|
||||
static typename R::FT x(const typename R::Point_3& p) {return -p.x();}
|
||||
static typename R::FT y(const typename R::Point_3& p) {return -p.y();}
|
||||
};
|
||||
|
||||
template <class R>
|
||||
struct Coordinate_value_adaptor<R,4> {
|
||||
static typename R::FT x(const typename R::Point_3& p) {return p.y();}
|
||||
static typename R::FT y(const typename R::Point_3& p) {return p.x();}
|
||||
};
|
||||
|
||||
template <class R>
|
||||
struct Coordinate_value_adaptor<R,5> {
|
||||
static typename R::FT x(const typename R::Point_3& p) {return -p.y();}
|
||||
static typename R::FT y(const typename R::Point_3& p) {return p.x();}
|
||||
};
|
||||
|
||||
template <class R>
|
||||
struct Coordinate_value_adaptor<R,6> {
|
||||
static typename R::FT x(const typename R::Point_3& p) {return p.y();}
|
||||
static typename R::FT y(const typename R::Point_3& p) {return -p.x();}
|
||||
};
|
||||
|
||||
template <class R>
|
||||
struct Coordinate_value_adaptor<R,7> {
|
||||
static typename R::FT x(const typename R::Point_3& p) {return -p.y();}
|
||||
static typename R::FT y(const typename R::Point_3& p) {return -p.x();}
|
||||
};
|
||||
|
||||
template <class R>
|
||||
struct Coordinate_value_adaptor<R,8> {
|
||||
static typename R::FT x(const typename R::Point_3& p) {return p.x();}
|
||||
static typename R::FT y(const typename R::Point_3& p) {return p.z();}
|
||||
};
|
||||
|
||||
template <class R>
|
||||
struct Coordinate_value_adaptor<R,9> {
|
||||
static typename R::FT x(const typename R::Point_3& p) {return -p.x();}
|
||||
static typename R::FT y(const typename R::Point_3& p) {return p.z();}
|
||||
};
|
||||
|
||||
template <class R>
|
||||
struct Coordinate_value_adaptor<R,10> {
|
||||
static typename R::FT x(const typename R::Point_3& p) {return p.x();}
|
||||
static typename R::FT y(const typename R::Point_3& p) {return -p.z();}
|
||||
};
|
||||
|
||||
template <class R>
|
||||
struct Coordinate_value_adaptor<R,11> {
|
||||
static typename R::FT x(const typename R::Point_3& p) {return -p.x();}
|
||||
static typename R::FT y(const typename R::Point_3& p) {return -p.z();}
|
||||
};
|
||||
|
||||
template <class R>
|
||||
struct Coordinate_value_adaptor<R,12> {
|
||||
static typename R::FT x(const typename R::Point_3& p) {return p.z();}
|
||||
static typename R::FT y(const typename R::Point_3& p) {return p.x();}
|
||||
};
|
||||
|
||||
template <class R>
|
||||
struct Coordinate_value_adaptor<R,13> {
|
||||
static typename R::FT x(const typename R::Point_3& p) {return -p.z();}
|
||||
static typename R::FT y(const typename R::Point_3& p) {return p.x();}
|
||||
};
|
||||
|
||||
template <class R>
|
||||
struct Coordinate_value_adaptor<R,14> {
|
||||
static typename R::FT x(const typename R::Point_3& p) {return p.z();}
|
||||
static typename R::FT y(const typename R::Point_3& p) {return -p.x();}
|
||||
};
|
||||
|
||||
template <class R>
|
||||
struct Coordinate_value_adaptor<R,15> {
|
||||
static typename R::FT x(const typename R::Point_3& p) {return -p.z();}
|
||||
static typename R::FT y(const typename R::Point_3& p) {return -p.x();}
|
||||
};
|
||||
|
||||
template <class R>
|
||||
struct Coordinate_value_adaptor<R,16> {
|
||||
static typename R::FT x(const typename R::Point_3& p) {return p.y();}
|
||||
static typename R::FT y(const typename R::Point_3& p) {return p.z();}
|
||||
};
|
||||
|
||||
template <class R>
|
||||
struct Coordinate_value_adaptor<R,17> {
|
||||
static typename R::FT x(const typename R::Point_3& p) {return -p.y();}
|
||||
static typename R::FT y(const typename R::Point_3& p) {return p.z();}
|
||||
};
|
||||
|
||||
template <class R>
|
||||
struct Coordinate_value_adaptor<R,18> {
|
||||
static typename R::FT x(const typename R::Point_3& p) {return p.y();}
|
||||
static typename R::FT y(const typename R::Point_3& p) {return -p.z();}
|
||||
};
|
||||
|
||||
template <class R>
|
||||
struct Coordinate_value_adaptor<R,19> {
|
||||
static typename R::FT x(const typename R::Point_3& p) {return -p.y();}
|
||||
static typename R::FT y(const typename R::Point_3& p) {return -p.z();}
|
||||
};
|
||||
|
||||
template <class R>
|
||||
struct Coordinate_value_adaptor<R,20> {
|
||||
static typename R::FT x(const typename R::Point_3& p) {return p.z();}
|
||||
static typename R::FT y(const typename R::Point_3& p) {return p.y();}
|
||||
};
|
||||
|
||||
template <class R>
|
||||
struct Coordinate_value_adaptor<R,21> {
|
||||
static typename R::FT x(const typename R::Point_3& p) {return -p.z();}
|
||||
static typename R::FT y(const typename R::Point_3& p) {return p.y();}
|
||||
};
|
||||
|
||||
template <class R>
|
||||
struct Coordinate_value_adaptor<R,22> {
|
||||
static typename R::FT x(const typename R::Point_3& p) {return p.z();}
|
||||
static typename R::FT y(const typename R::Point_3& p) {return -p.y();}
|
||||
};
|
||||
|
||||
template <class R>
|
||||
struct Coordinate_value_adaptor<R,23> {
|
||||
static typename R::FT x(const typename R::Point_3& p) {return -p.z();}
|
||||
static typename R::FT y(const typename R::Point_3& p) {return -p.y();}
|
||||
};
|
||||
|
||||
template <class R, int opt>
|
||||
class Compute_x_2
|
||||
{
|
||||
public:
|
||||
typedef typename R::Point_3 Point;
|
||||
typename R::FT x(const Point &p) const { return Coordinate_value_adaptor<R,opt>::x(p); }
|
||||
typename R::FT operator()(const Point& p) const { return x(p); }
|
||||
};
|
||||
|
||||
template <class R, int opt>
|
||||
class Compute_y_2
|
||||
{
|
||||
public:
|
||||
typedef typename R::Point_3 Point;
|
||||
typename R::FT y(const Point &p) const { return Coordinate_value_adaptor<R,opt>::y(p); }
|
||||
typename R::FT operator()(const Point& p) const { return y(p); }
|
||||
};
|
||||
|
||||
template <class R, int opt>
|
||||
class Less_x_2
|
||||
{
|
||||
public:
|
||||
typedef typename R::Point_3 Point;
|
||||
typename R::FT x(const Point &p) const { return Coordinate_value_adaptor<R,opt>::x(p); }
|
||||
bool operator()(const Point& p, const Point& q) const { return x(p) < x(q); }
|
||||
};
|
||||
|
||||
template <class R, int opt>
|
||||
class Less_y_2
|
||||
{
|
||||
public:
|
||||
typedef typename R::Point_3 Point;
|
||||
typename R::FT y(const Point &p) const { return Coordinate_value_adaptor<R,opt>::y(p); }
|
||||
bool operator()(const Point& p, const Point& q) const { return y(p) < y(q); }
|
||||
};
|
||||
|
||||
template <class R, int x, int y, int z, int ord>
|
||||
struct Transform_coordinates_traits_3 {
|
||||
private:
|
||||
enum {opt = Transform_constant_struct<x,y,z,ord>::value};
|
||||
|
||||
public:
|
||||
typedef Transform_coordinates_traits_3<R,x,y,z,ord> Traits;
|
||||
typedef R Rp;
|
||||
typedef typename Rp::Point_3 Point_2;
|
||||
typedef Less_x_2<R,opt> Less_x;
|
||||
typedef Less_y_2<R,opt> Less_y;
|
||||
typedef Compute_x_2<R,opt> Compute_x;
|
||||
typedef Compute_y_2<R,opt> Compute_y;
|
||||
|
||||
Transform_coordinates_traits_3(){}
|
||||
Transform_coordinates_traits_3(const Transform_coordinates_traits_3&){}
|
||||
|
||||
Less_x less_x_2_object() const { return Less_x(); }
|
||||
Less_y less_y_2_object() const { return Less_y(); }
|
||||
Compute_x compute_x_2_object() const { return Compute_x(); }
|
||||
Compute_y compute_y_2_object() const { return Compute_y(); }
|
||||
};
|
||||
|
||||
|
||||
} } //namespace CGAL::internal
|
||||
|
||||
#endif // CGAL_INTERNAL_SCALE_COORDINATES_ADAPTOR_TRAITS_3_H
|
||||
|
|
@ -16,7 +16,6 @@
|
|||
// $Id$
|
||||
//
|
||||
// Author(s) : Christophe Delage
|
||||
// : Olivier Devillers
|
||||
|
||||
#ifndef CGAL_SPATIAL_SORT_H
|
||||
#define CGAL_SPATIAL_SORT_H
|
||||
|
|
|
|||
|
|
@ -0,0 +1,144 @@
|
|||
// Copyright (c) 2015 INRIA Sophia-Antipolis (France).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// Licensees holding a valid commercial license may use this file in
|
||||
// accordance with the commercial license agreement provided with the software.
|
||||
//
|
||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
//
|
||||
// Author(s) : Olivier Devillers
|
||||
// : Pedro Machado Manhaes de Castro
|
||||
|
||||
|
||||
#ifndef CGAL_SPATIAL_SORT_ON_SPHERE_H
|
||||
#define CGAL_SPATIAL_SORT_ON_SPHERE_H
|
||||
|
||||
#include <CGAL/spatial_sort.h>
|
||||
#include <CGAL/hilbert_sort_on_sphere.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
namespace internal {
|
||||
|
||||
template <class RandomAccessIterator, class Policy, class Kernel>
|
||||
void spatial_sort_on_sphere (
|
||||
RandomAccessIterator begin, RandomAccessIterator end,
|
||||
const Kernel &k,
|
||||
Policy /*policy*/,
|
||||
typename Kernel::Point_3 *,
|
||||
double sq_r,
|
||||
const typename Kernel::Point_3 &p,
|
||||
std::ptrdiff_t threshold_hilbert,
|
||||
std::ptrdiff_t threshold_multiscale,
|
||||
double ratio)
|
||||
{
|
||||
typedef Hilbert_sort_on_sphere_3<Kernel, Policy> Sort;
|
||||
boost::rand48 random;
|
||||
boost::random_number_generator<boost::rand48> rng(random);
|
||||
std::random_shuffle(begin,end, rng);
|
||||
|
||||
if (threshold_hilbert==0) threshold_hilbert=4;
|
||||
if (threshold_multiscale==0) threshold_multiscale=16;
|
||||
if (ratio==0.0) ratio=0.25;
|
||||
|
||||
(Multiscale_sort<Sort> (Sort (k, sq_r, p, threshold_hilbert),
|
||||
threshold_multiscale, ratio)) (begin, end);
|
||||
}
|
||||
|
||||
} // end of namespace internal
|
||||
|
||||
template <class RandomAccessIterator, class Policy, class Kernel>
|
||||
void spatial_sort_on_sphere (RandomAccessIterator begin, RandomAccessIterator end,
|
||||
const Kernel &k,
|
||||
Policy policy,
|
||||
double sq_r=1.0,
|
||||
const typename Kernel::Point_3 &p = typename Kernel::Point_3(0,0,0),
|
||||
std::ptrdiff_t threshold_hilbert=0,
|
||||
std::ptrdiff_t threshold_multiscale=0,
|
||||
double ratio=0.0)
|
||||
{
|
||||
typedef std::iterator_traits<RandomAccessIterator> ITraits;
|
||||
typedef typename ITraits::value_type value_type;
|
||||
|
||||
internal::spatial_sort_on_sphere(begin, end, k, policy, static_cast<value_type *> (0),
|
||||
sq_r,p, threshold_hilbert,threshold_multiscale,ratio);
|
||||
}
|
||||
|
||||
template <class RandomAccessIterator>
|
||||
void spatial_sort_on_sphere (RandomAccessIterator begin, RandomAccessIterator end,
|
||||
Hilbert_sort_median_policy policy,
|
||||
double sq_r=1.0,
|
||||
const typename CGAL::Kernel_traits<typename std::iterator_traits<RandomAccessIterator>::value_type>::Kernel::Point_3 &p =
|
||||
typename CGAL::Kernel_traits<typename std::iterator_traits<RandomAccessIterator>::value_type>::Kernel::Point_3(0,0,0),
|
||||
std::ptrdiff_t threshold_hilbert=0,
|
||||
std::ptrdiff_t threshold_multiscale=0,
|
||||
double ratio=0.0)
|
||||
{
|
||||
typedef std::iterator_traits<RandomAccessIterator> ITraits;
|
||||
typedef typename ITraits::value_type value_type;
|
||||
typedef CGAL::Kernel_traits<value_type> KTraits;
|
||||
typedef typename KTraits::Kernel Kernel;
|
||||
|
||||
spatial_sort_on_sphere (begin, end, Kernel(), policy, sq_r, p,
|
||||
threshold_hilbert,threshold_multiscale,ratio);
|
||||
}
|
||||
template <class RandomAccessIterator>
|
||||
void spatial_sort_on_sphere (RandomAccessIterator begin, RandomAccessIterator end,
|
||||
Hilbert_sort_middle_policy policy,
|
||||
double sq_r=1.0,
|
||||
const typename CGAL::Kernel_traits<typename std::iterator_traits<RandomAccessIterator>::value_type>::Kernel::Point_3 &p =
|
||||
typename CGAL::Kernel_traits<typename std::iterator_traits<RandomAccessIterator>::value_type>::Kernel::Point_3(0,0,0),
|
||||
std::ptrdiff_t threshold_hilbert=0,
|
||||
std::ptrdiff_t threshold_multiscale=0,
|
||||
double ratio=0.0)
|
||||
{
|
||||
typedef std::iterator_traits<RandomAccessIterator> ITraits;
|
||||
typedef typename ITraits::value_type value_type;
|
||||
typedef CGAL::Kernel_traits<value_type> KTraits;
|
||||
typedef typename KTraits::Kernel Kernel;
|
||||
|
||||
spatial_sort_on_sphere (begin, end, Kernel(), policy, sq_r,p,
|
||||
threshold_hilbert,threshold_multiscale,ratio);
|
||||
}
|
||||
|
||||
|
||||
template <class RandomAccessIterator, class Kernel>
|
||||
void spatial_sort_on_sphere (RandomAccessIterator begin, RandomAccessIterator end,
|
||||
const Kernel &k,
|
||||
double sq_r = 1.0,
|
||||
const typename Kernel::Point_3 &p = typename Kernel::Point_3(0,0,0),
|
||||
std::ptrdiff_t threshold_hilbert=0,
|
||||
std::ptrdiff_t threshold_multiscale=0,
|
||||
double ratio=0.0)
|
||||
{
|
||||
spatial_sort_on_sphere (begin, end, k,
|
||||
Hilbert_sort_median_policy(), sq_r, p,
|
||||
threshold_hilbert,threshold_multiscale,ratio);
|
||||
}
|
||||
|
||||
template <class RandomAccessIterator>
|
||||
void spatial_sort_on_sphere (RandomAccessIterator begin, RandomAccessIterator end,
|
||||
double sq_r = 1.0,
|
||||
const typename CGAL::Kernel_traits<typename std::iterator_traits<RandomAccessIterator>::value_type>::Kernel::Point_3 &p =
|
||||
typename CGAL::Kernel_traits<typename std::iterator_traits<RandomAccessIterator>::value_type>::Kernel::Point_3(0,0,0),
|
||||
std::ptrdiff_t threshold_hilbert=0,
|
||||
std::ptrdiff_t threshold_multiscale=0,
|
||||
double ratio=0.0)
|
||||
{
|
||||
spatial_sort_on_sphere (begin, end,
|
||||
Hilbert_sort_median_policy(), sq_r,p,
|
||||
threshold_hilbert,threshold_multiscale,ratio);
|
||||
}
|
||||
|
||||
} // end of namespace CGAL
|
||||
|
||||
#endif // CGAL_SPATIAL_SORT_ON_SPHERE_H
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
#include <cassert>
|
||||
|
||||
#include <CGAL/hilbert_sort.h>
|
||||
#include <CGAL/hilbert_sort_on_sphere.h>
|
||||
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Cartesian_d.h>
|
||||
|
|
@ -22,6 +23,7 @@
|
|||
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
||||
typedef K::Point_2 Point_2;
|
||||
typedef K::Point_3 Point_3;
|
||||
typedef K::Vector_3 Vector_3;
|
||||
typedef CGAL::Creator_uniform_2<double,Point_2> Creator_2;
|
||||
typedef CGAL::Creator_uniform_3<double,Point_3> Creator_3;
|
||||
|
||||
|
|
@ -277,6 +279,130 @@ int main ()
|
|||
assert(CGAL::squared_distance( v[i], v[i+1]) - 4.0 < 0.1 );
|
||||
}
|
||||
std::cout << "OK." << std::endl;
|
||||
}
|
||||
{
|
||||
std::cout << "Testing Spherical (median policy): Generating "<<nb_points_3<<" random points... " << std::flush;
|
||||
|
||||
std::vector<Point_3> v;
|
||||
v.reserve (nb_points_3);
|
||||
|
||||
CGAL::Random_points_on_sphere_3<Point_3> gen (1.0, random);
|
||||
|
||||
for (int i = 0; i < nb_points_3; ++i)
|
||||
v.push_back (*gen++);
|
||||
|
||||
std::cout << "done." << std::endl;
|
||||
|
||||
std::vector<Point_3> v2 (v);
|
||||
|
||||
std::cout << " Sorting points... " << std::flush;
|
||||
|
||||
cost.reset();cost.start();
|
||||
CGAL::hilbert_sort(v.begin(),v.end());
|
||||
cost.stop();
|
||||
|
||||
std::cout << "done in "<<cost.time()<<"seconds." << std::endl;
|
||||
|
||||
std::cout << " Checking... " << std::flush;
|
||||
|
||||
std::sort (v.begin(), v.end(), K().less_xyz_3_object());
|
||||
std::sort (v2.begin(), v2.end(), K().less_xyz_3_object());
|
||||
assert(v == v2);
|
||||
|
||||
std::cout << "no points lost." << std::endl;
|
||||
}
|
||||
{
|
||||
std::cout << "Testing Spherical (median policy) + given sphere: Generating "<<nb_points_3<<" random points... " << std::flush;
|
||||
|
||||
std::vector<Point_3> v;
|
||||
v.reserve (nb_points_3);
|
||||
|
||||
CGAL::Random_points_on_sphere_3<Point_3> gen (2.0, random);
|
||||
|
||||
for (int i = 0; i < nb_points_3; ++i)
|
||||
v.push_back (*gen++ + Vector_3(3,5,5));
|
||||
|
||||
std::cout << "done." << std::endl;
|
||||
|
||||
std::vector<Point_3> v2 (v);
|
||||
|
||||
std::cout << " Sorting points... " << std::flush;
|
||||
|
||||
cost.reset();cost.start();
|
||||
CGAL::hilbert_sort_on_sphere(v.begin(),v.end(), 4, CGAL::ORIGIN + Vector_3(3,5,5));
|
||||
cost.stop();
|
||||
|
||||
std::cout << "done in "<<cost.time()<<"seconds." << std::endl;
|
||||
|
||||
std::cout << " Checking... " << std::flush;
|
||||
|
||||
std::sort (v.begin(), v.end(), K().less_xyz_3_object());
|
||||
std::sort (v2.begin(), v2.end(), K().less_xyz_3_object());
|
||||
assert(v == v2);
|
||||
|
||||
std::cout << "no points lost." << std::endl;
|
||||
}
|
||||
{
|
||||
std::cout << "Testing Spherical (middle policy): Generating "<<nb_points_3<<" random points... " << std::flush;
|
||||
|
||||
std::vector<Point_3> v;
|
||||
v.reserve (nb_points_3);
|
||||
|
||||
CGAL::Random_points_on_sphere_3<Point_3> gen (1.0, random);
|
||||
|
||||
for (int i = 0; i < nb_points_3; ++i)
|
||||
v.push_back (*gen++);
|
||||
|
||||
std::cout << "done." << std::endl;
|
||||
|
||||
std::vector<Point_3> v2 (v);
|
||||
|
||||
std::cout << " Sorting points... " << std::flush;
|
||||
|
||||
cost.reset();cost.start();
|
||||
CGAL::hilbert_sort_on_sphere(v.begin(),v.end(),CGAL::Hilbert_sort_middle_policy());
|
||||
cost.stop();
|
||||
|
||||
std::cout << "done in "<<cost.time()<<"seconds." << std::endl;
|
||||
|
||||
std::cout << " Checking... " << std::flush;
|
||||
|
||||
std::sort (v.begin(), v.end(), K().less_xyz_3_object());
|
||||
std::sort (v2.begin(), v2.end(), K().less_xyz_3_object());
|
||||
assert(v == v2);
|
||||
|
||||
std::cout << "no points lost." << std::endl;
|
||||
}
|
||||
{
|
||||
std::cout << "Testing Spherical (middle policy) + given sphere: Generating "<<nb_points_3<<" random points... " << std::flush;
|
||||
|
||||
std::vector<Point_3> v;
|
||||
v.reserve (nb_points_3);
|
||||
|
||||
CGAL::Random_points_on_sphere_3<Point_3> gen (2.0, random);
|
||||
|
||||
for (int i = 0; i < nb_points_3; ++i)
|
||||
v.push_back (*gen++ + Vector_3(3,5,5));
|
||||
|
||||
std::cout << "done." << std::endl;
|
||||
|
||||
std::vector<Point_3> v2 (v);
|
||||
|
||||
std::cout << " Sorting points... " << std::flush;
|
||||
|
||||
cost.reset();cost.start();
|
||||
CGAL::hilbert_sort_on_sphere(v.begin(),v.end(),CGAL::Hilbert_sort_middle_policy(), 4, CGAL::ORIGIN + Vector_3(3,5,5));
|
||||
cost.stop();
|
||||
|
||||
std::cout << "done in "<<cost.time()<<"seconds." << std::endl;
|
||||
|
||||
std::cout << " Checking... " << std::flush;
|
||||
|
||||
std::sort (v.begin(), v.end(), K().less_xyz_3_object());
|
||||
std::sort (v2.begin(), v2.end(), K().less_xyz_3_object());
|
||||
assert(v == v2);
|
||||
|
||||
std::cout << "no points lost." << std::endl;
|
||||
}
|
||||
{
|
||||
int dim =5;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include <cassert>
|
||||
|
||||
#include <CGAL/spatial_sort.h>
|
||||
#include <CGAL/spatial_sort_on_sphere.h>
|
||||
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Cartesian_d.h>
|
||||
|
|
@ -20,6 +21,7 @@
|
|||
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
||||
typedef K::Point_2 Point_2;
|
||||
typedef K::Point_3 Point_3;
|
||||
typedef K::Vector_3 Vector_3;
|
||||
|
||||
typedef CGAL::Creator_uniform_2<double,Point_2> Creator_2;
|
||||
typedef CGAL::Creator_uniform_3<double,Point_3> Creator_3;
|
||||
|
|
@ -94,6 +96,66 @@ int main ()
|
|||
std::cout << "no points lost." << std::endl;
|
||||
}
|
||||
|
||||
{
|
||||
std::cout << "Testing Spherical: Generating points... " << std::flush;
|
||||
|
||||
std::vector<Point_3> v;
|
||||
v.reserve (nb_points_3);
|
||||
|
||||
CGAL::Random_points_on_sphere_3<Point_3,Creator_3> gen (1.0, random);
|
||||
|
||||
for (int i = 0; i < nb_points_3; ++i)
|
||||
v.push_back (*gen++);
|
||||
|
||||
std::cout << "done." << std::endl;
|
||||
|
||||
std::vector<Point_3> v2 (v);
|
||||
|
||||
std::cout << " Sorting points... " << std::flush;
|
||||
|
||||
CGAL::spatial_sort_on_sphere (v.begin(), v.end());
|
||||
|
||||
std::cout << "done." << std::endl;
|
||||
|
||||
std::cout << " Checking... " << std::flush;
|
||||
|
||||
std::sort (v.begin(), v.end(), K().less_xyz_3_object());
|
||||
std::sort (v2.begin(), v2.end(), K().less_xyz_3_object());
|
||||
assert(v == v2);
|
||||
|
||||
std::cout << "no points lost." << std::endl;
|
||||
}
|
||||
|
||||
{
|
||||
std::cout << "Testing Spherical + given sphere: Generating points... " << std::flush;
|
||||
|
||||
std::vector<Point_3> v;
|
||||
v.reserve (nb_points_3);
|
||||
|
||||
CGAL::Random_points_on_sphere_3<Point_3,Creator_3> gen (3.0, random);
|
||||
|
||||
for (int i = 0; i < nb_points_3; ++i)
|
||||
v.push_back (*gen++ + Vector_3(10,10,3));
|
||||
|
||||
std::cout << "done." << std::endl;
|
||||
|
||||
std::vector<Point_3> v2 (v);
|
||||
|
||||
std::cout << " Sorting points... " << std::flush;
|
||||
|
||||
CGAL::spatial_sort_on_sphere (v.begin(), v.end(), 9, Point_3(10,10,3));
|
||||
|
||||
std::cout << "done." << std::endl;
|
||||
|
||||
std::cout << " Checking... " << std::flush;
|
||||
|
||||
std::sort (v.begin(), v.end(), K().less_xyz_3_object());
|
||||
std::sort (v2.begin(), v2.end(), K().less_xyz_3_object());
|
||||
assert(v == v2);
|
||||
|
||||
std::cout << "no points lost." << std::endl;
|
||||
}
|
||||
|
||||
{
|
||||
int dim=5;
|
||||
std::cout << "Testing "<<dim<<"D: Generating points... " << std::flush;
|
||||
|
|
|
|||
Loading…
Reference in New Issue