dust3d/thirdparty/cgal/CGAL-4.13/include/CGAL/rectangular_p_center_2.h

444 lines
12 KiB
C++
Executable File

// Copyright (c) 1998-2003 ETH Zurich (Switzerland).
// 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
// 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$
// SPDX-License-Identifier: GPL-3.0+
//
//
// Author(s) : Michael Hoffmann <hoffmann@inf.ethz.ch>
#ifndef CGAL_RECTANGULAR_P_CENTER_2_H
#define CGAL_RECTANGULAR_P_CENTER_2_H 1
#include <CGAL/license/Bounding_volumes.h>
#include <CGAL/pierce_rectangles_2.h>
#include <CGAL/sorted_matrix_search.h>
#include <CGAL/rectangular_3_center_2.h>
#include <algorithm>
#include <CGAL/number_utils_classes.h>
#include <CGAL/Rectangular_p_center_traits_2.h>
#include <CGAL/Cartesian_matrix.h>
namespace CGAL {
template < class Operation,
class RandomAccessIC_row,
class RandomAccessIC_column >
class Cartesian_matrix_horizontally_flipped
: public Cartesian_matrix< Operation,
RandomAccessIC_row,
RandomAccessIC_column >
{
public:
typedef
Cartesian_matrix< Operation,
RandomAccessIC_row,
RandomAccessIC_column > Base;
typedef typename Base::Value Value;
using Base::number_of_rows;
using Base::number_of_columns;
/*
Cartesian_matrix_horizontally_flipped(
Operation o = Operation())
: Base( o)
{}
*/
Cartesian_matrix_horizontally_flipped(
RandomAccessIC_row r_f,
RandomAccessIC_row r_l,
RandomAccessIC_column c_f,
RandomAccessIC_column c_l)
: Base( r_f, r_l, c_f, c_l)
{}
Cartesian_matrix_horizontally_flipped(
RandomAccessIC_row r_f,
RandomAccessIC_row r_l,
RandomAccessIC_column c_f,
RandomAccessIC_column c_l,
const Operation& o)
: Base( r_f, r_l, c_f, c_l, o)
{}
Value
operator()( int r, int c) const
{
CGAL_optimisation_precondition( r >= 0 && r < number_of_rows());
CGAL_optimisation_precondition( c >= 0 && c < number_of_columns());
return Base::operator()( r, number_of_columns() - 1 - c);
}
};
template < class Operation,
class RandomAccessIC_row,
class RandomAccessIC_column >
inline
Cartesian_matrix_horizontally_flipped<
Operation,
RandomAccessIC_row,
RandomAccessIC_column >
cartesian_matrix_horizontally_flipped(
RandomAccessIC_row r_f,
RandomAccessIC_row r_l,
RandomAccessIC_column c_f,
RandomAccessIC_column c_l,
const Operation& o)
{
return
Cartesian_matrix_horizontally_flipped<
Operation,
RandomAccessIC_row,
RandomAccessIC_column >
( r_f, r_l, c_f, c_l, o);
}
/*
template < class ForwardIterator,
class OutputIterator,
class FT,
class PiercingFunction >
inline
OutputIterator
rectangular_p_center_2_binary_search(
ForwardIterator f,
ForwardIterator l,
OutputIterator o,
FT& r,
const PiercingFunction& pf)
{
return rectangular_p_center_2_binary_search(
f,
l,
o,
r,
pf,
CGAL_reinterpret_cast(
Rectangular_p_center_matrix_search_traits_2< PiercingFunction >, 0));
} // rectangular_p_center_2_binary_search( ... )
template < class ForwardIterator, class OutputIterator, class Traits >
OutputIterator
rectangular_p_center_2_binary_search(
ForwardIterator f,
ForwardIterator l,
OutputIterator o,
typename Traits::FT& r,
const typename Traits::PiercingFunction& pf,
Traits*)
//
// preconditions:
// --------------
// * Traits fulfills the requirements for PCenter traits classes
// * value type of ForwardIterator is Traits::Point_2
// * OutputIterator accepts Traits::Point_2 as value type
// * the range [f,l) is not empty
//
// functionality:
// --------------
//
{
CGAL_optimisation_precondition( f != l);
// typedefs:
typedef typename Traits::FT FT;
typedef typename Traits::X X;
typedef typename Traits::Y Y;
// create Traits object:
Traits pierce_it( f, l, pf);
// check, if input data is trivial
bool ok;
OutputIterator oi = pierce_it(FT(0), o, ok);
if (ok) {
r = 0;
return oi;
}
// create vector with absolute coordinate differences:
std::vector< FT > c_diffs;
c_diffs.reserve( pierce_it.number_of_points() *
(pierce_it.number_of_points() - 1));
for ( ForwardIterator i( f); i != l; ++i)
for ( ForwardIterator j( i + 1); j != l; ++j) {
c_diffs.push_back( CGAL_NTS abs( i->x() - j->x()));
c_diffs.push_back( CGAL_NTS abs( i->y() - j->y()));
}
CGAL_optimisation_assertion(
c_diffs.size() == pierce_it.number_of_points() *
(pierce_it.number_of_points() - 1));
// sort it:
sort( c_diffs.begin(), c_diffs.end());
// search it:
int b( 0);
int e( c_diffs.size());
// invariant of the following loop:
// forall 0 <= a < b: c_diffs[a] is infeasible AND
// forall e <= a < c_diffs.size(): c_diffs[a] is feasible
while ( e > b) {
int c = ( e + b) >> 1;
if ( pierce_it( c_diffs[c])) {
// c_diffs[c] is feasible
e = c;
}
else {
// c_diffs[c] is infeasible
b = c + 1;
}
} // while ( e > b)
CGAL_optimisation_assertion( e == b);
// return the result:
r = c_diffs[e];
OutputIterator o_return( pierce_it( r, o, ok));
CGAL_optimisation_assertion( ok);
return o_return;
} // rectangular_p_center_2_binary_search( ... )
*/
template < class RandomAccessIC,
class OutputIterator,
class PiercingFunction,
class Traits,
class MatrixOperator >
OutputIterator
rectangular_p_center_2_matrix_search(
RandomAccessIC f,
RandomAccessIC l,
OutputIterator o,
typename Traits::FT& r,
PiercingFunction pf,
const Traits& t,
const MatrixOperator& mop)
{
std::size_t number_of_points( iterator_distance( f, l));
CGAL_optimisation_precondition( number_of_points > 0);
using std::minus;
using std::sort;
// typedefs:
typedef typename Traits::FT FT;
typedef std::vector< FT > FT_cont;
typedef typename FT_cont::iterator FT_iterator;
typedef Cartesian_matrix_horizontally_flipped<
MatrixOperator,
FT_iterator,
FT_iterator >
Matrix;
typedef std::vector< Matrix > MatrixContainer;
typedef
Rectangular_p_center_matrix_search_traits_2< Traits, PiercingFunction >
MSTraits;
typedef Sorted_matrix_search_traits_adaptor< MSTraits&, Matrix >
Matrix_search_traits;
// create Traits object:
MSTraits pierce_it(f, l, t, pf);
// check, if input data is trivial
bool ok;
OutputIterator oi = pierce_it(FT(0), o, ok);
if (ok) {
r = 0;
return oi;
}
// create matrix search traits:
Matrix_search_traits search_it(pierce_it);
// copy x and y coordinates from [f,l):
std::vector< FT > x_coords;
std::vector< FT > y_coords;
x_coords.reserve( number_of_points);
y_coords.reserve( number_of_points);
for ( RandomAccessIC p( f); p != l; ++p) {
x_coords.push_back(p->x());
y_coords.push_back(p->y());
}
// sort coordinates:
sort( x_coords.begin(), x_coords.end());
sort( y_coords.begin(), y_coords.end());
// create matrices:
MatrixContainer matrices;
// create matrix of x-differences:
matrices.push_back(
Matrix( x_coords.begin(),
x_coords.end(),
x_coords.begin(),
x_coords.end(),
mop));
// create matrix of y-differences:
matrices.push_back(
Matrix( y_coords.begin(),
y_coords.end(),
y_coords.begin(),
y_coords.end(),
mop));
// do the actual search:
r = sorted_matrix_search(matrices.begin(),
matrices.end(),
search_it);
// return result:
OutputIterator o_return(pierce_it(r, o, ok));
CGAL_optimisation_assertion(ok);
return o_return;
} // P_center_matrix_search
template < class RandomAccessIC,
class OutputIterator,
class PiercingFunction,
class Traits >
inline
OutputIterator
rectangular_p_center_2_matrix_search(
RandomAccessIC f,
RandomAccessIC l,
OutputIterator o,
typename Traits::FT& r,
const PiercingFunction& pf,
const Traits& t)
{
typedef typename Traits::FT FT;
using std::minus;
return rectangular_p_center_2_matrix_search(
f,
l,
o,
r,
pf,
t,
boost::bind(Max<FT>(), 0, boost::bind(minus<FT>(), _1, _2)));
} // Pcenter_matrix_search( ... )
template < class ForwardIterator, class OutputIterator, class FT >
inline OutputIterator
rectangular_p_center_matrix_search_2(
ForwardIterator f,
ForwardIterator l,
OutputIterator o,
FT& r,
int p)
{
CGAL_optimisation_precondition(p >= 2 && p < 5);
typename std::iterator_traits<ForwardIterator>::value_type::R t;
if (p == 2)
return rectangular_p_center_2_matrix_search(
f, l, o, r, Two_covering_algorithm(), t);
else if (p == 3)
return rectangular_p_center_2_matrix_search(
f, l, o, r, Three_covering_algorithm(), t);
return rectangular_p_center_2_matrix_search(
f, l, o, r, Four_covering_algorithm(), t);
} // rectangular_p_center_matrix_search_2(f, l, o, r, p)
namespace internal{
template <class Iterator>
bool is_distance_greater_than_p
( Iterator begin,Iterator end,
typename std::iterator_traits<Iterator>::difference_type p,
std::random_access_iterator_tag)
{
return std::distance(begin,end) > p;
}
template <class Iterator>
bool is_distance_greater_than_p
( Iterator begin,Iterator end,
typename std::iterator_traits<Iterator>::difference_type p,
std::forward_iterator_tag)
{
Iterator it=begin;
while(p!=0){
if (it==end) return false;
++it;
--p;
}
if (it!=end) return true;
return false;
}
template <class Iterator>
bool is_distance_greater_than_p
(Iterator begin,Iterator end,
typename std::iterator_traits<Iterator>::difference_type p)
{
return
is_distance_greater_than_p(begin,end,p,
typename std::iterator_traits<Iterator>::iterator_category());
}
} //namespace internal
template < class ForwardIterator, class OutputIterator, class Traits >
inline OutputIterator
rectangular_p_center_2(ForwardIterator f,
ForwardIterator l,
OutputIterator o,
typename Traits::FT& r,
int p,
Traits& t)
{
CGAL_optimisation_precondition(p >= 2 && p < 5);
r=0;
if ( !internal::is_distance_greater_than_p(f,l,p) ) return std::copy(f,l,o);
if (p == 2)
return rectangular_2_center_2(f, l, o, r, t);
else if (p == 3)
return rectangular_3_center_2(f, l, o, r, t);
return rectangular_p_center_2_matrix_search(
f, l, o, r, Four_covering_algorithm(), t);
} // rectangular_p_center_2( ... )
template < class ForwardIterator, class OutputIterator, class FT >
inline OutputIterator
rectangular_p_center_2(ForwardIterator f,
ForwardIterator l,
OutputIterator o,
FT& r,
int p)
{
CGAL_optimisation_precondition(p >= 2 && p < 5);
typedef typename
std::iterator_traits< ForwardIterator >::value_type::R R;
Rectangular_p_center_default_traits_2< R > t;
return rectangular_p_center_2(f, l, o, r, p, t);
} // rectangular_p_center_2( ... )
} //namespace CGAL
#endif // ! (CGAL_RECTANGULAR_P_CENTER_2_H)