mirror of https://github.com/CGAL/cgal
353 lines
9.5 KiB
C++
353 lines
9.5 KiB
C++
|
|
namespace CGAL {
|
|
|
|
/*!
|
|
\ingroup PkgBoundingVolumes
|
|
|
|
An object of the class `Min_sphere_d` is the unique sphere of
|
|
smallest volume enclosing a finite (multi)set of points in \f$ d\f$-dimensional
|
|
Euclidean space \f$ \E^d\f$. For a set \f$ P\f$ we denote by \f$ ms(P)\f$ the
|
|
smallest sphere that contains all points of \f$ P\f$. \f$ ms(P)\f$ can
|
|
be degenerate, i.e.\ \f$ ms(P)=\emptyset\f$
|
|
if \f$ P=\emptyset\f$ and \f$ ms(P)=\{p\}\f$ if
|
|
\f$ P=\{p\}\f$.
|
|
|
|
An inclusion-minimal subset \f$ S\f$ of \f$ P\f$ with \f$ ms(S)=ms(P)\f$ is called a
|
|
<I>support set</I>, the points in \f$ S\f$ are the <I>support points</I>.
|
|
A support set has size at most \f$ d+1\f$, and all its points lie on the
|
|
boundary of \f$ ms(P)\f$. In general, neither the support set nor its size
|
|
are unique.
|
|
|
|
The algorithm
|
|
computes a support set \f$ S\f$ which remains fixed until the next insert
|
|
or clear operation.
|
|
|
|
<B>Please note:</B> This class is (almost) obsolete. The class
|
|
`CGAL::Min_sphere_of_spheres_d<Traits>` solves a more general problem
|
|
and is faster then `Min_sphere_d` even if used only for points
|
|
as input. Most importantly, `CGAL::Min_sphere_of_spheres_d<Traits>` has
|
|
a specialized implementation for floating-point arithmetic which
|
|
ensures correct results in a large number of cases (including
|
|
highly degenerate ones). In contrast, `Min_sphere_d` is not reliable
|
|
under floating-point computations. The only advantage of
|
|
`Min_sphere_d` over `CGAL::Min_sphere_of_spheres_d<Traits>` is that the
|
|
former can deal with points in homogeneous coordinates, in which
|
|
case the algorithm is division-free. Thus, `Min_sphere_d` might still
|
|
be an option in case your input number type cannot (efficiently)
|
|
divide.
|
|
|
|
|
|
\tparam Traits must be a model of the concept
|
|
`OptimisationDTraits` as its template argument.
|
|
|
|
We provide the models `CGAL::Optimisation_d_traits_2`,
|
|
`CGAL::Optimisation_d_traits_3` and
|
|
`CGAL::Optimisation_d_traits_d`
|
|
for two-, three-, and \f$ d\f$-dimensional points respectively.
|
|
|
|
\sa `CGAL::Optimisation_d_traits_2<K,ET,NT>`
|
|
\sa `CGAL::Optimisation_d_traits_3<K,ET,NT>`
|
|
\sa `CGAL::Optimisation_d_traits_d<K,ET,NT>`
|
|
\sa `OptimisationDTraits`
|
|
\sa `CGAL::Min_circle_2<Traits>`
|
|
\sa `CGAL::Min_sphere_of_spheres_d<Traits>`
|
|
\sa `CGAL::Min_annulus_d<Traits>`
|
|
|
|
\cgalHeading{Implementation}
|
|
|
|
We implement the algorithm of Welzl with move-to-front
|
|
heuristic \cgalCite{w-sedbe-91a} for small point sets, combined with a new
|
|
efficient method for large sets, which is particularly tuned for
|
|
moderately large dimension (\f$ d \leq 20\f$) \cgalCite{cgal:g-frseb-99}.
|
|
The creation time is almost
|
|
always linear in the number of points. Access functions and predicates
|
|
take constant time, inserting a point might take up to linear time,
|
|
but substantially less than computing the new smallest enclosing
|
|
sphere from scratch. The clear operation and the check for validity
|
|
each take linear time.
|
|
|
|
\cgalHeading{Example}
|
|
|
|
\cgalExample{Min_sphere_d/min_sphere_d.cpp}
|
|
|
|
*/
|
|
template< typename Traits >
|
|
class Min_sphere_d {
|
|
public:
|
|
|
|
/// \name Types
|
|
/// @{
|
|
|
|
/*!
|
|
|
|
*/
|
|
typedef unspecified_type Traits;
|
|
|
|
/*!
|
|
typedef to `Traits::FT`.
|
|
*/
|
|
typedef unspecified_type FT;
|
|
|
|
/*!
|
|
typedef to `Traits::Point`.
|
|
*/
|
|
typedef unspecified_type Point;
|
|
|
|
/*!
|
|
non-mutable model of the STL
|
|
concept `BidirectionalIterator` with value type `Point`. Used
|
|
to access the points used to build the smallest enclosing sphere.
|
|
*/
|
|
typedef unspecified_type Point_iterator;
|
|
|
|
/*!
|
|
non-mutable model of the STL
|
|
concept `BidirectionalIterator` with value type `Point`. Used
|
|
to access the support points defining the smallest enclosing sphere.
|
|
*/
|
|
typedef unspecified_type Support_point_iterator;
|
|
|
|
/// @}
|
|
|
|
/// \name Creation
|
|
/// @{
|
|
|
|
/*!
|
|
|
|
creates a variable of type `Min_sphere_d` and
|
|
initializes it to \f$ ms(\emptyset)\f$.
|
|
If the traits parameter is not supplied, the class `Traits`
|
|
must provide a default constructor.
|
|
*/
|
|
Min_sphere_d (const Traits& traits = Traits());
|
|
|
|
/*!
|
|
|
|
creates a variable `min_sphere` of type `Min_sphere_d`.
|
|
It is initialized to \f$ ms(P)\f$ with \f$ P\f$ being the set of points
|
|
in the range [`first`,`last`).
|
|
\tparam InputIterator is a model of `InputIterator` with `Point` as value type.
|
|
If the traits parameter is not supplied, the class `Traits` must provide a default constructor.
|
|
\pre All points have the same dimension.
|
|
*/
|
|
template < class InputIterator >
|
|
Min_sphere_d( InputIterator first,
|
|
InputIterator last,
|
|
const Traits& traits = Traits());
|
|
|
|
/*!
|
|
|
|
returns the number of points of `min_sphere`, i.e.\ \f$ |P|\f$.
|
|
*/
|
|
int number_of_points( ) const;
|
|
|
|
/*!
|
|
|
|
returns the number of support points of `min_sphere`, i.e.\ \f$ |S|\f$.
|
|
*/
|
|
int number_of_support_points( ) const;
|
|
|
|
/*!
|
|
|
|
returns an iterator referring to the first point of `min_sphere`.
|
|
*/
|
|
Point_iterator points_begin() const;
|
|
|
|
/*!
|
|
|
|
returns the corresponding past-the-end iterator.
|
|
*/
|
|
Point_iterator points_end() const;
|
|
|
|
/*!
|
|
|
|
returns an iterator referring to the first support point of `min_sphere`.
|
|
*/
|
|
Support_point_iterator support_points_begin() const;
|
|
|
|
/*!
|
|
|
|
returns the corresponding past-the-end iterator.
|
|
*/
|
|
Support_point_iterator support_points_end() const;
|
|
|
|
/*!
|
|
|
|
returns the dimension of the points in \f$ P\f$. If `min_sphere` is empty, the ambient dimension is \f$ -1\f$.
|
|
*/
|
|
int ambient_dimension() const;
|
|
|
|
/*!
|
|
|
|
returns the center of `min_sphere`.
|
|
\pre `min_sphere` is not empty.
|
|
*/
|
|
const Point& center( ) const;
|
|
|
|
/*!
|
|
|
|
returns the squared radius of `min_sphere`.
|
|
\pre `min_sphere` is not empty.
|
|
*/
|
|
FT squared_radius( ) const;
|
|
|
|
/// @}
|
|
|
|
/// \name Predicates
|
|
/// By definition, an empty `Min_sphere_d` has no boundary and no
|
|
/// bounded side, i.e.\ its unbounded side equals the whole space \f$
|
|
/// \E^d\f$.
|
|
/// @{
|
|
|
|
/*!
|
|
|
|
returns `CGAL::ON_BOUNDED_SIDE`, `CGAL::ON_BOUNDARY`, or
|
|
`CGAL::ON_UNBOUNDED_SIDE` iff `p` lies properly inside,
|
|
on the boundary, or properly outside of `min_sphere`, resp.
|
|
\pre If `min_sphere` is not empty, the dimension of \f$ p\f$ equals `ambient_dimension()`.
|
|
*/
|
|
Bounded_side
|
|
bounded_side( const Point& p) const;
|
|
|
|
/*!
|
|
|
|
returns `true`, iff `p` lies properly inside `min_sphere`.
|
|
\pre If `min_sphere` is not empty, the dimension of \f$ p\f$ equals `ambient_dimension()`.
|
|
*/
|
|
bool has_on_bounded_side( const Point& p) const;
|
|
|
|
/*!
|
|
|
|
returns `true`, iff `p` lies on the boundary
|
|
of `min_sphere`.
|
|
\pre if `min_sphere` is not empty, the dimension of \f$ p\f$ equals `ambient_dimension()`.
|
|
*/
|
|
bool has_on_boundary( const Point& p) const;
|
|
|
|
/*!
|
|
|
|
returns `true`, iff `p` lies properly outside of `min_sphere`.
|
|
\pre If `min_sphere` is not empty, the dimension of \f$ p\f$ equals `ambient_dimension()`.
|
|
*/
|
|
bool has_on_unbounded_side( const Point& p) const;
|
|
|
|
/*!
|
|
|
|
returns `true`, iff `min_sphere` is empty (this implies
|
|
degeneracy).
|
|
*/
|
|
bool is_empty( ) const;
|
|
|
|
/*!
|
|
|
|
returns `true`, iff `min_sphere` is degenerate, i.e.\ if
|
|
`min_sphere` is empty or equal to a single point, equivalently if
|
|
the number of support points is less than 2.
|
|
*/
|
|
bool is_degenerate( ) const;
|
|
|
|
/// @}
|
|
|
|
/// \name Modifiers
|
|
/// @{
|
|
|
|
/*!
|
|
|
|
resets `min_sphere` to \f$ ms(\emptyset)\f$.
|
|
*/
|
|
void clear ();
|
|
|
|
/*!
|
|
|
|
sets `min_sphere` to the \f$ ms(P)\f$, where \f$ P\f$ is the set of points
|
|
in the range [`first`,`last`).
|
|
\tparam InputIterator is a model of `InputIterator` with `Point` as value type.
|
|
\pre All points have the same dimension.
|
|
*/
|
|
template < class InputIterator >
|
|
void set( InputIterator first,
|
|
InputIterator last );
|
|
|
|
/*!
|
|
|
|
inserts `p` into `min_sphere`. If `p` lies inside the
|
|
current sphere, this is a constant-time operation, otherwise
|
|
it might take longer, but usually substantially less than
|
|
recomputing the smallest enclosing sphere from scratch.
|
|
\pre The dimension of `p` equals `ambient_dimension()` if `min_sphere` is not empty.
|
|
*/
|
|
void insert( const Point& p);
|
|
|
|
/*!
|
|
|
|
inserts the points in the range [`first`,`last`)
|
|
into `min_sphere` and recomputes the smallest enclosing sphere, by
|
|
calling `insert` for all points in the range.
|
|
\tparam InputIterator is a model of `InputIterator` with `Point` as value type.
|
|
\pre All points have the same dimension. If `min_sphere` is not empty, this dimension must be equal to `ambient_dimension()`.
|
|
*/
|
|
template < class InputIterator >
|
|
void insert( InputIterator first,
|
|
InputIterator last );
|
|
|
|
/// @}
|
|
|
|
/// \name Validity Check
|
|
/// An object `min_sphere` is valid, iff <UL> <LI>`min_sphere`
|
|
/// contains all points of its defining set \f$ P\f$, <LI>`min_sphere`
|
|
/// is the smallest sphere containing its support set \f$ S\f$, and
|
|
/// <LI>\f$ S\f$ is minimal, i.e.\ no support point is redundant. </UL>
|
|
///
|
|
/// \note Under inexact arithmetic, the result of the
|
|
/// validation is not realiable, because the checker itself can suffer
|
|
/// from numerical problems.
|
|
/// @{
|
|
|
|
/*!
|
|
|
|
returns `true`, iff `min_sphere` is valid. If `verbose`
|
|
is `true`, some messages concerning the performed checks
|
|
are written to standard error stream. The second parameter
|
|
`level` is not used, we provide it only for consistency
|
|
with interfaces of other classes.
|
|
*/
|
|
bool is_valid( bool verbose = false,
|
|
int level = 0 ) const;
|
|
|
|
/// @}
|
|
|
|
/// \name Miscellaneous
|
|
/// @{
|
|
|
|
/*!
|
|
|
|
returns a const reference to the traits class object.
|
|
*/
|
|
const Traits& traits( ) const;
|
|
|
|
/// @}
|
|
|
|
}; /* end Min_sphere_d */
|
|
|
|
|
|
/*!
|
|
|
|
writes `min_sphere` to output stream `os`.
|
|
An overload of `operator<<` must be defined for `Point`.
|
|
\relates Min_sphere_d
|
|
*/
|
|
std::ostream& operator << ( std::ostream& os,
|
|
const Min_sphere_d<Traits>&
|
|
min_sphere);
|
|
|
|
/*!
|
|
|
|
reads `min_sphere` from input stream `is`.
|
|
An overload of `operator>>` must be defined for `Point`
|
|
\relates Min_sphere_d
|
|
*/
|
|
std::istream& operator >> ( std::istream& is,
|
|
Min_sphere_d<Traits> min_sphere&);
|
|
|
|
} /* end namespace CGAL */
|