31#if defined(QuickHullKernels_RECURSES)
32#error Recursive header files inclusion detected in QuickHullKernels.h
35#define QuickHullKernels_RECURSES
37#if !defined QuickHullKernels_h
39#define QuickHullKernels_h
47#include "DGtal/base/Common.h"
48#include "DGtal/kernel/CInteger.h"
49#include "DGtal/kernel/NumberTraits.h"
50#include "DGtal/kernel/PointVector.h"
51#include "DGtal/kernel/IntegerConverter.h"
52#include "DGtal/math/linalg/SimpleMatrix.h"
53#include "DGtal/geometry/tools/AffineGeometry.h"
66 template <
typename Po
int >
69 if ( points.empty() )
return Point::zero;
70 Point l = points[ 0 ];
72 for (
const auto& p : points ) {
76 return Point( ( l + u ) / 2 );
107 template <
typename OutputValue,
108 typename ForwardIterator,
109 typename ConversionFct >
110 void transform( std::vector< OutputValue >& output_values,
111 std::vector< std::size_t >& input2output,
112 std::vector< std::size_t >& output2input,
113 ForwardIterator itb, ForwardIterator ite,
114 const ConversionFct& F,
115 bool remove_duplicates )
117 typedef std::size_t
Size;
120 for (
auto it = itb; it != ite; ++it ) ++n;
121 std::vector< OutputValue > input( n );
122 for (
Size i = 0; i < n; i++ )
123 input[ i ] = F( *itb++ );
124 if ( ! remove_duplicates ) {
125 output_values.swap( input );
126 input2output.resize( input.size() );
127 output2input.resize( input.size() );
128 for (
Size i = 0; i < input.size(); ++i )
129 input2output[ i ] = output2input[ i ] = i;
132 output_values.clear();
133 std::vector< std::size_t > i2c_sort( input.size() );
134 input2output.resize( input.size() );
135 for (
Size i = 0; i < input.size(); i++ ) i2c_sort[ i ] = i;
137 std::sort( i2c_sort.begin(), i2c_sort.end(),
138 [&input] (
Size i,
Size j ) { return input[ i ] < input[ j ]; } );
139 output_values.resize( input.size() );
140 output_values[ 0 ] = input[ i2c_sort[ 0 ] ];
141 input2output[ i2c_sort[ 0 ] ] = 0;
143 for (
Size i = 1; i < input.size(); i++ ) {
144 if ( input[ i2c_sort[ i-1 ] ] != input[ i2c_sort[ i ] ] )
145 output_values[ ++j ] = input[ i2c_sort[ i ] ];
146 input2output[ i2c_sort[ i ] ] = j;
148 output_values.resize( j+1 );
149 output2input.resize( output_values.size() );
150 for (
Size i = 0; i < input2output.size(); i++ )
151 output2input[ input2output[ i ] ] = i;
212 :
N( aN ),
c( aC ) {}
234 compute(
const std::vector< CoordinatePoint >& vpoints,
244 if ( nu > hs.
c ) { hs.
N = -hs.
N; hs.
c = -hs.
c; }
261 compute(
const std::vector< CoordinatePoint >& vpoints,
295 return H1.
N.
dot( H2.
N );
308 return H1.
c == H2.
c && H1.
N == H2.
N;
336 {
return height(
H, p ) >= 0; }
342 {
return height(
H, p ) == 0; }
388 using typename Base::HalfSpace;
447 template <
typename InputPo
int>
448 void makeInput( std::vector< CoordinatePoint >& processed_points,
450 const std::vector< InputPoint >& input_points,
451 bool remove_duplicates )
461 input_points.cbegin(), input_points.cend(),
462 F, remove_duplicates );
467 template <
typename OutputPo
int>
471 out_p[ k ] =
static_cast<typename OutputPoint::Component
>(p[ k ]);
584 template <
typename InputPo
int>
585 void makeInput( std::vector< CoordinatePoint >& processed_points,
587 const std::vector< InputPoint >& input_points,
588 bool remove_duplicates )
603 input_points.cbegin(), input_points.cend(),
604 F, remove_duplicates );
609 template <
typename OutputPo
int>
745 template <
typename InputPo
int>
746 void makeInput( std::vector< CoordinatePoint >& processed_points,
748 const std::vector< InputPoint >& input_points,
749 bool remove_duplicates )
759 input_points.cbegin(), input_points.cend(),
760 F, remove_duplicates );
779 template <
typename OutputPo
int>
783 out_p[ k ] = ( (
double) p[ k ] ) /
precision;
923 template <
typename InputPo
int>
924 void makeInput( std::vector< CoordinatePoint >& processed_points,
926 const std::vector< InputPoint >& input_points,
927 bool remove_duplicates )
943 input_points.cbegin(), input_points.cend(),
944 F, remove_duplicates );
966 template <
typename OutputPo
int>
970 out_p[ k ] = ( (
double) p[ k ] ) /
precision;
981#undef QuickHullKernels_RECURSES
InternalScalar c
the intercept
HalfSpace(const InternalVector &aN, const InternalScalar aC)
InternalVector N
the normal vector
InternalScalar internalIntercept() const
const InternalVector & internalNormal() const
Aim: Implements basic operations that will be used in Point and Vector classes.
auto dot(const PointVector< dim, OtherComponent, OtherStorage > &v) const -> decltype(DGtal::dotProduct(*this, v))
Dot product with a PointVector.
static Self zero
Static const for zero PointVector.
void transform(std::vector< OutputValue > &output_values, std::vector< std::size_t > &input2output, std::vector< std::size_t > &output2input, ForwardIterator itb, ForwardIterator ite, const ConversionFct &F, bool remove_duplicates)
Point center(const std::vector< Point > &points)
static void getOrthogonalVector(TPoint &w, const std::vector< TInputPoint > &X, const TIndexRange &I, const double tolerance=1e-12)
DGtal is the top-level namespace which contains all DGtal functions and types.
std::int64_t int64_t
signed 94-bit integer.
DGtal::uint32_t Dimension
Aim: the common part of all geometric kernels for computing the convex hull or Delaunay triangulation...
DGtal::PointVector< dim, InternalInteger > InternalVector
BOOST_CONCEPT_ASSERT((concepts::CInteger< TCoordinateInteger >))
InternalInteger InternalScalar
std::array< Index, dim > CombinatorialPlaneSimplex
bool above(const HalfSpace &H, const CoordinatePoint &p) const
InternalScalar height(const HalfSpace &H, const CoordinatePoint &p) const
CoordinateInteger CoordinateScalar
HalfSpace compute(const std::vector< CoordinatePoint > &vpoints, const CombinatorialPlaneSimplex &simplex)
TCoordinateInteger CoordinateInteger
CoordinateVector normal(const HalfSpace &H) const
InternalScalar volume(const HalfSpace &H, const CoordinatePoint &p) const
InternalScalar dot(const HalfSpace &H1, const HalfSpace &H2) const
HalfSpace compute(const std::vector< CoordinatePoint > &vpoints, const CombinatorialPlaneSimplex &simplex, Index idx_below)
DGtal::PointVector< dim, CoordinateInteger > CoordinatePoint
std::vector< Index > IndexRange
bool equal(const HalfSpace &H1, const HalfSpace &H2) const
BOOST_CONCEPT_ASSERT((concepts::CInteger< TInternalInteger >))
DGtal::PointVector< dim, InternalInteger > InternalPoint
IntegerConverter< dim, InternalInteger > Inner
Converter to inner internal integers or lattice points / vector.
bool on(const HalfSpace &H, const CoordinatePoint &p) const
TInternalInteger InternalInteger
static const Dimension dimension
ConvexHullCommonKernel< dim-1, TCoordinateInteger, TInternalInteger > LowerSelf
bool aboveOrOn(const HalfSpace &H, const CoordinatePoint &p) const
IntegerConverter< dim, CoordinateInteger > Outer
Converter to outer coordinate integers or lattice points / vector.
ConvexHullCommonKernel< dim, TCoordinateInteger, TInternalInteger > Self
ConvexHullCommonKernel()=default
Default constructor.
CoordinateScalar intercept(const HalfSpace &H) const
DGtal::PointVector< dim, CoordinateInteger > CoordinateVector
Aim: a geometric kernel to compute the convex hull of digital points with integer-only arithmetic.
CoordinateInteger CoordinateScalar
ConvexHullCommonKernel< dim, TCoordinateInteger, TInternalInteger > Base
void convertPointTo(const CoordinatePoint &p, OutputPoint &out_p) const
std::vector< Index > IndexRange
ConvexHullIntegralKernel< dim-1, TCoordinateInteger, TInternalInteger > LowerSelf
bool hasInfiniteFacets() const
void makeInput(std::vector< CoordinatePoint > &processed_points, IndexRange &input2comp, IndexRange &comp2input, const std::vector< InputPoint > &input_points, bool remove_duplicates)
bool isHalfSpaceFacetInfinite(const HalfSpace &hs) const
static const Dimension dimension
ConvexHullIntegralKernel()=default
Default constructor.
ConvexHullIntegralKernel< dim, TCoordinateInteger, TInternalInteger > Self
Aim: a geometric kernel to compute the convex hull of floating points with integer-only arithmetic....
void convertPointTo(const CoordinatePoint &p, OutputPoint &out_p) const
CoordinateInteger CoordinateScalar
void makeInput(std::vector< CoordinatePoint > &processed_points, IndexRange &input2comp, IndexRange &comp2input, const std::vector< InputPoint > &input_points, bool remove_duplicates)
std::vector< Index > IndexRange
double precision
The precision as the common denominator for all rational points.
bool hasInfiniteFacets() const
bool isHalfSpaceFacetInfinite(const HalfSpace &hs) const
ConvexHullRationalKernel(double aPrecision=1024.)
static const Dimension dimension
ConvexHullCommonKernel< dim, TCoordinateInteger, TInternalInteger > Base
ConvexHullRationalKernel< dim, TCoordinateInteger, TInternalInteger > Self
ConvexHullRationalKernel< dim-1, TCoordinateInteger, TInternalInteger > LowerSelf
Aim: a geometric kernel to compute the Delaunay triangulation of digital points with integer-only ari...
InternalInteger InternalScalar
CoordinateInteger CoordinateScalar
std::vector< Index > IndexRange
ConvexHullCommonKernel< dim+1, TCoordinateInteger, TInternalInteger > Base
void convertPointTo(const CoordinatePoint &p, OutputPoint &out_p) const
DelaunayIntegralKernel< dim, TCoordinateInteger, TInternalInteger > Self
DelaunayIntegralKernel()=default
Default constructor.
void makeInput(std::vector< CoordinatePoint > &processed_points, IndexRange &input2comp, IndexRange &comp2input, const std::vector< InputPoint > &input_points, bool remove_duplicates)
static const Dimension dimension
bool isHalfSpaceFacetInfinite(const HalfSpace &hs) const
bool hasInfiniteFacets() const
DelaunayIntegralKernel< dim-1, TCoordinateInteger, TInternalInteger > LowerSelf
Aim: a geometric kernel to compute the Delaunay triangulation of a range of floating points with inte...
InternalInteger InternalScalar
CoordinateInteger CoordinateScalar
DelaunayRationalKernel< dim, TCoordinateInteger, TInternalInteger > Self
std::vector< Index > IndexRange
bool hasInfiniteFacets() const
double precision
The precision as the common denominator for all rational points.
ConvexHullCommonKernel< dim+1, TCoordinateInteger, TInternalInteger > Base
DelaunayRationalKernel(double aPrecision=1024.)
static const Dimension dimension
void makeInput(std::vector< CoordinatePoint > &processed_points, IndexRange &input2comp, IndexRange &comp2input, const std::vector< InputPoint > &input_points, bool remove_duplicates)
void convertPointTo(const CoordinatePoint &p, OutputPoint &out_p) const
DelaunayRationalKernel< dim-1, TCoordinateInteger, TInternalInteger > LowerSelf
bool isHalfSpaceFacetInfinite(const HalfSpace &hs) const
----------— INTEGER/POINT CONVERSION SERVICES -----------------—
static Integer cast(Integer i)
Aim: Concept checking for Integer Numbers. More precisely, this concept is a refinement of both CEucl...
HalfEdgeDataStructure::Size Size