cgal/Bounding_volumes/include/CGAL/Rectangular_p_center_traits...

344 lines
11 KiB
C++

// Copyright (c) 1998-2003 ETH Zurich (Switzerland).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Michael Hoffmann <hoffmann@inf.ethz.ch>
#ifndef CGAL_RECTANGULAR_P_CENTER_TRAITS_2_H
#define CGAL_RECTANGULAR_P_CENTER_TRAITS_2_H 1
#include <CGAL/license/Bounding_volumes.h>
#include <CGAL/Point_2.h>
#include <CGAL/Iso_rectangle_2.h>
#include <CGAL/basic_constructions_2.h>
#include <CGAL/pierce_rectangles_2.h>
#include <CGAL/assertions.h>
namespace CGAL {
template < class A, class S >
struct Select : public CGAL::cpp98::binary_function< A, A, A > {
Select() {}
Select(const S& s) : s_(s) {}
A operator()(const A& a, const A& b) const
{ return s_(a, b) ? a : b; }
A operator()(const A& a, const A& b)
{ return s_(a, b) ? a : b; }
protected:
S s_;
};
template < class R >
struct I_Signed_x_distance_2
: public CGAL::cpp98::binary_function<
Point_2< R >, Point_2< R >, typename R::FT >
{
typename R::FT
operator()(const Point_2< R >& q1, const Point_2< R >& q2) const
{ return q1.x() - q2.x(); }
};
template < class R >
struct I_Signed_y_distance_2
: public CGAL::cpp98::binary_function<
Point_2< R >, Point_2< R >, typename R::FT >
{
typename R::FT
operator()(const Point_2< R >& q1, const Point_2< R >& q2) const
{ return q1.y() - q2.y(); }
};
template < class R >
struct I_Infinity_distance_2
: public CGAL::cpp98::binary_function<
Point_2< R >, Point_2< R >, typename R::FT >
{
// Added as workaround for VC2017 with /arch:AVX to fix
// https://cgal.geometryfactory.com/CGAL/testsuite/CGAL-4.14-I-95/Rectangular_p_center_2_Examples/TestReport_afabri_x64_Cygwin-Windows10_MSVC2017-Release-64bits.gz
I_Infinity_distance_2()
{}
I_Infinity_distance_2(const I_Infinity_distance_2&)
{}
I_Infinity_distance_2& operator=(const I_Infinity_distance_2&)
{
return *this;
}
typename R::FT
operator()(const Point_2< R >& q1, const Point_2< R >& q2) const {
return (std::max)(CGAL_NTS abs(q1.x() - q2.x()),
CGAL_NTS abs(q1.y() - q2.y()));
}
};
template < class R >
struct I_Signed_infinity_distance_2
: public CGAL::cpp98::binary_function<
Point_2< R >, Point_2< R >, typename R::FT >
{
typename R::FT
operator()(const Point_2< R >& q1, const Point_2< R >& q2) const
{
return (std::max)(q1.x() - q2.x(), q1.y() - q2.y());
}
};
template < class R >
struct I_Construct_point_2_above_right_implicit_point_2 {
// (p, q, r) |--> (p.x() + r, q.y() + r)
typedef typename R::FT FT;
typedef typename R::Point_2 P;
inline P
operator()(const P& p, const P& q, FT r) const
{ return P(p.x() + r, q.y() + r); }
};
template < class R >
struct I_Construct_point_2_above_left_implicit_point_2 {
// (p, q, r) |--> (p.x() - r, q.y() + r)
typedef typename R::FT FT;
typedef typename R::Point_2 P;
inline P
operator()(const P& p, const P& q, FT r) const
{ return P(p.x() - r, q.y() + r); }
};
template < class R >
struct I_Construct_point_2_below_left_implicit_point_2 {
// (p, q, r) |--> (p.x() - r, q.y() - r)
typedef typename R::FT FT;
typedef typename R::Point_2 P;
inline P
operator()(const P& p, const P& q, FT r) const
{ return P(p.x() - r, q.y() - r); }
};
template < class R >
struct I_Construct_point_2_below_right_implicit_point_2 {
// (p, q, r) |--> (p.x() + r, q.y() - r)
typedef typename R::FT FT;
typedef typename R::Point_2 P;
inline P
operator()(const P& p, const P& q, FT r) const
{ return P(p.x() + r, q.y() - r); }
};
template < class R >
struct Rectangular_p_center_default_traits_2 : public R
{
// -----------------------------------------------------------------
// types:
//
typedef typename R::FT FT;
typedef typename R::Point_2 Point_2;
typedef typename R::Iso_rectangle_2 Iso_rectangle_2;
// -----------------------------------------------------------------
// predicates:
//
typedef typename R::Less_x_2 Less_x_2;
typedef typename R::Less_y_2 Less_y_2;
// -----------------------------------------------------------------
// constructions:
//
// from the kernel
typedef typename R::Construct_iso_rectangle_2 Construct_iso_rectangle_2;
typedef typename R::Construct_vertex_2 Construct_vertex_2;
// additions
typedef I_Signed_x_distance_2< R > Signed_x_distance_2;
typedef I_Signed_y_distance_2< R > Signed_y_distance_2;
typedef I_Infinity_distance_2< R > Infinity_distance_2;
typedef I_Signed_infinity_distance_2< R > Signed_infinity_distance_2;
typedef I_Construct_point_2_above_right_implicit_point_2< R >
Construct_point_2_above_right_implicit_point_2;
typedef I_Construct_point_2_above_left_implicit_point_2< R >
Construct_point_2_above_left_implicit_point_2;
typedef I_Construct_point_2_below_right_implicit_point_2< R >
Construct_point_2_below_right_implicit_point_2;
typedef I_Construct_point_2_below_left_implicit_point_2< R >
Construct_point_2_below_left_implicit_point_2;
// get object methods:
Signed_x_distance_2
signed_x_distance_2_object() const
{ return Signed_x_distance_2(); }
Signed_y_distance_2
signed_y_distance_2_object() const
{ return Signed_y_distance_2(); }
Infinity_distance_2
infinity_distance_2_object() const
{ return Infinity_distance_2(); }
Signed_infinity_distance_2
signed_infinity_distance_2_object() const
{ return Signed_infinity_distance_2(); }
Construct_point_2_above_right_implicit_point_2
construct_point_2_above_right_implicit_point_2_object() const
{ return Construct_point_2_above_right_implicit_point_2(); }
Construct_point_2_above_left_implicit_point_2
construct_point_2_above_left_implicit_point_2_object() const
{ return Construct_point_2_above_left_implicit_point_2(); }
Construct_point_2_below_left_implicit_point_2
construct_point_2_below_left_implicit_point_2_object() const
{ return Construct_point_2_below_left_implicit_point_2(); }
Construct_point_2_below_right_implicit_point_2
construct_point_2_below_right_implicit_point_2_object() const
{ return Construct_point_2_below_right_implicit_point_2(); }
}; // Rectangular_p_center_default_traits_2
template < class Traits_, class PiercingFunction_ >
struct Rectangular_p_center_matrix_search_traits_2 {
typedef Traits_ Traits;
typedef typename Traits::FT FT;
typedef typename Traits::Point_2 Point_2;
typedef PiercingFunction_ PiercingFunction;
typedef Staircases< Traits > LD;
typedef typename LD::size_type size_type;
template < class InputIC >
Rectangular_p_center_matrix_search_traits_2(
InputIC f, InputIC l, Traits t, const PiercingFunction& p)
: ld(f, l, t), pf(p)
#if (!defined(CGAL_OPTIMISATION_NO_ASSERTIONS) && \
!defined(CGAL_NO_ASSERTIONS) && !defined(NDEBUG))
, ld_size(ld.size())
#endif // optimisation_assertion_code
{}
size_type number_of_points() const { return ld.pts.size(); }
bool operator()(FT v)
{
CGAL_assertion(ld.size() == ld_size);
ld.r = v / FT(2);
bool ok;
pf(ld, Wastebasket< Point_2 >(), ok);
CGAL_assertion(ld.size() == ld_size);
return ok;
}
template < class OutputIterator >
OutputIterator operator()(FT v, OutputIterator o, bool& ok)
{
CGAL_assertion(ld.size() == ld_size);
ld.r = v / FT(2);
OutputIterator n = pf(ld, o, ok);
CGAL_assertion(ld.size() == ld_size);
return n; //pf(ld, o, ok);
}
protected:
// data members:
LD ld;
PiercingFunction pf;
CGAL_assertion_code(typename LD::size_type ld_size;)
// copying this would be too inefficient
Rectangular_p_center_matrix_search_traits_2(
const Rectangular_p_center_matrix_search_traits_2&)
{}
}; // Rectangular_p_center_matrix_search_traits_2< ... >
template < class ForwardIterator, class Traits >
typename Traits::Iso_rectangle_2
bounding_box_2(ForwardIterator f, ForwardIterator l, const Traits& t)
// PRE: f != l.
{
CGAL_precondition(f != l);
typedef typename Traits::Less_x_2 Less_x_2;
typedef typename Traits::Less_y_2 Less_y_2;
typedef typename Traits::Construct_iso_rectangle_2 Rect;
typedef typename Traits::Construct_vertex_2 CVertex;
Less_x_2 lessx = t.less_x_2_object();
Less_y_2 lessy = t.less_y_2_object();
Rect rect = t.construct_iso_rectangle_2_object();
CVertex v = t.construct_vertex_2_object();
ForwardIterator xmin = f;
ForwardIterator xmax = f;
ForwardIterator ymin = f;
ForwardIterator ymax = f;
while (++f != l) {
if (lessx(*f, *xmin)) xmin = f;
if (lessx(*xmax, *f)) xmax = f;
if (lessy(*f, *ymin)) ymin = f;
if (lessy(*ymax, *f)) ymax = f;
}
return rect(v(rect(*xmin, *ymin), 0), v(rect(*xmax, *ymax), 2));
} // bounding_box_2(f, l, t)
template < class ForwardIterator >
inline
auto
bounding_box_2(ForwardIterator f, ForwardIterator l)
// PRE: f != l.
{
CGAL_precondition(f != l);
// that is how it is supposed to be ...
//typedef typename std::iterator_traits< ForwardIterator >::value_type::R
// Traits;
typedef typename std::iterator_traits< ForwardIterator >::value_type::R R;
typedef Rectangular_p_center_default_traits_2< R > Traits;
Traits t;
return bounding_box_2(f, l, t);
} // bounding_box_2(f, l)
template < class Rectangle, class Traits >
inline Rectangle
construct_bounding_box_union_2(const Rectangle& r1,
const Rectangle& r2,
const Traits& t)
{
typedef typename Traits::Construct_iso_rectangle_2 Rect;
typedef typename Traits::Construct_vertex_2 CVertex;
typedef typename Traits::Less_x_2 Less_x_2;
typedef typename Traits::Less_y_2 Less_y_2;
Less_x_2 lessx = t.less_x_2_object();
Less_y_2 lessy = t.less_y_2_object();
Rect rect = t.construct_iso_rectangle_2_object();
CVertex v = t.construct_vertex_2_object();
return rect(
v(rect(lessx(v(r1, 0), v(r2, 0)) ? v(r1, 0) : v(r2, 0),
lessy(v(r1, 0), v(r2, 0)) ? v(r1, 0) : v(r2, 0)),
0),
v(rect(lessx(v(r2, 2), v(r1, 2)) ? v(r1, 2) : v(r2, 2),
lessy(v(r2, 2), v(r1, 2)) ? v(r1, 2) : v(r2, 2)),
2));
} // construct_bounding_box_union_2(r1, r2, t)
template < class Rectangle >
inline Rectangle
construct_bounding_box_union_2(const Rectangle& r1, const Rectangle& r2)
{
typename Rectangle::R t;
return construct_bounding_box_union_2(r1, r2, t);
} // construct_bounding_box_union_2(r1, r2)
} //namespace CGAL
#endif // ! (CGAL_RECTANGULAR_P_CENTER_TRAITS_2_H)