mirror of https://github.com/CGAL/cgal
344 lines
11 KiB
C++
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)
|