mirror of https://github.com/CGAL/cgal
495 lines
14 KiB
C++
495 lines
14 KiB
C++
// ============================================================================
|
|
//
|
|
// Copyright (c) 1998 The CGAL Consortium
|
|
//
|
|
// This software and related documentation is part of an INTERNAL release
|
|
// of the Computational Geometry Algorithms Library (CGAL). It is not
|
|
// intended for general use.
|
|
//
|
|
// ----------------------------------------------------------------------------
|
|
//
|
|
// release : $CGAL_Revision $
|
|
// release_date : $CGAL_Date $
|
|
//
|
|
// file : Extremal_polygon_traits_2.h
|
|
// chapter : $CGAL_Chapter: Geometric Optimisation $
|
|
// package : $CGAL_Package: Matrix_search $
|
|
// source : mon_search.aw
|
|
// revision : $Revision$
|
|
// revision_date : $Date$
|
|
// author(s) : Michael Hoffmann <hoffmann@inf.ethz.ch>
|
|
//
|
|
// coordinator : ETH Zurich (Bernd Gaertner <gaertner@inf.ethz.ch>)
|
|
//
|
|
// Predefined Traits classes for Extremal Polygon Computation
|
|
// ============================================================================
|
|
|
|
#if ! (CGAL_EXTREMAL_POLYGON_TRAITS_2_H)
|
|
#define CGAL_EXTREMAL_POLYGON_TRAITS_2_H 1
|
|
|
|
#include <CGAL/Optimisation/assertions.h>
|
|
#include <CGAL/squared_distance_2.h>
|
|
#include <CGAL/Polygon_2.h>
|
|
#include <CGAL/function_objects.h>
|
|
|
|
CGAL_BEGIN_NAMESPACE
|
|
template < class R > inline
|
|
#ifndef CGAL_CFG_RETURN_TYPE_BUG_1
|
|
typename R::FT
|
|
#else
|
|
R_FT_return(R)
|
|
#endif
|
|
Kgon_triangle_area( const Point_2< R >& p,
|
|
const Point_2< R >& q,
|
|
const Point_2< R >& r)
|
|
{
|
|
return abs( p.x() * ( q.y() - r.y()) +
|
|
q.x() * ( r.y() - p.y()) +
|
|
r.x() * ( p.y() - q.y()));
|
|
}
|
|
|
|
template < class _R >
|
|
class _Kgon_area_operator
|
|
: public CGAL_STD::binary_function< Point_2< _R >,
|
|
Point_2< _R >,
|
|
typename _R::FT >
|
|
{
|
|
public:
|
|
typedef _R R;
|
|
typedef Point_2< R > Point_2;
|
|
typedef typename R::FT FT;
|
|
|
|
_Kgon_area_operator( const Point_2& p)
|
|
: root( p)
|
|
{}
|
|
|
|
FT
|
|
operator()( const Point_2& p, const Point_2& q) const
|
|
{ return Kgon_triangle_area( p, q, root); }
|
|
|
|
private:
|
|
const Point_2& root;
|
|
};
|
|
|
|
|
|
|
|
template < class _R >
|
|
class Kgon_area_traits
|
|
{
|
|
public:
|
|
typedef _R R;
|
|
typedef Point_2< R > Point_2;
|
|
typedef typename _R::FT FT;
|
|
typedef _Kgon_area_operator< R > Operation;
|
|
|
|
int
|
|
min_k() const
|
|
{ return 3; }
|
|
|
|
FT
|
|
init( const Point_2&, const Point_2&) const
|
|
{ return FT( 0); }
|
|
|
|
Operation
|
|
operation( const Point_2& p) const
|
|
{ return Operation( p); }
|
|
|
|
#ifndef CGAL_CFG_NO_MEMBER_TEMPLATES
|
|
template < class RandomAccessIC, class OutputIterator >
|
|
#else
|
|
typedef typename std::vector< Point_2 >::iterator
|
|
RandomAccessIC;
|
|
typedef typename std::vector< int >::reverse_iterator
|
|
OutputIterator;
|
|
#endif
|
|
OutputIterator
|
|
compute_min_k_gon( RandomAccessIC points_begin,
|
|
RandomAccessIC points_end,
|
|
FT& max_area,
|
|
OutputIterator o) const
|
|
// RandomAccessIC is a random access iterator or
|
|
// circulator with value_type Point_2.
|
|
// OutputIterator accepts int as value_type.
|
|
//
|
|
// PRE: n := | [points_begin, points_end) | >= min_k() and
|
|
// the points described by the range [points_begin, points_end)
|
|
// form the boundary of a convex polygon oriented counterclockwise.
|
|
//
|
|
// POST: write the points of [points_begin, points_end)
|
|
// forming a min_k()-gon rooted at points_begin[0]
|
|
// of maximum area to o in counterclockwise order and return
|
|
// the past-the-end iterator for that range (== o + min_k()).
|
|
{
|
|
int number_of_points(
|
|
iterator_distance( points_begin, points_end));
|
|
CGAL_optimisation_precondition( number_of_points > min_k());
|
|
|
|
// this gives the area of the triangle of two points with
|
|
// the root:
|
|
Operation op( operation( points_begin[0]));
|
|
|
|
int p1( 1);
|
|
int p2( 2);
|
|
|
|
// maximal triangle so far (and the corresponding points):
|
|
max_area = op( points_begin[p1], points_begin[p2]);
|
|
int opt_p1( p1);
|
|
int opt_p2( p2);
|
|
|
|
// maximal triangle containing p1 so far:
|
|
FT tmp_area( max_area);
|
|
|
|
for (;;) {
|
|
while ( p2 + 1 < number_of_points &&
|
|
tmp_area < op( points_begin[p1], points_begin[p2+1])) {
|
|
tmp_area = op( points_begin[p1], points_begin[++p2]);
|
|
}
|
|
if ( tmp_area > max_area) {
|
|
max_area = tmp_area;
|
|
opt_p1 = p1;
|
|
opt_p2 = p2;
|
|
}
|
|
if ( ++p1 == number_of_points - 1)
|
|
break;
|
|
if ( p2 == p1)
|
|
++p2;
|
|
tmp_area = op( points_begin[p1], points_begin[p2]);
|
|
} // for (;;)
|
|
|
|
// give result:
|
|
*o++ = opt_p2;
|
|
*o++ = opt_p1;
|
|
*o++ = 0;
|
|
return o;
|
|
} // compute_min_k_gon( ... )
|
|
|
|
#ifndef CGAL_CFG_NO_MEMBER_TEMPLATES
|
|
template < class RandomAccessIC >
|
|
#endif
|
|
bool
|
|
is_convex( RandomAccessIC points_begin,
|
|
RandomAccessIC points_end) const
|
|
// PRE: value_type of RandomAccessIC is Point_2
|
|
// POST: return true, iff the points [ points_begin, points_end)
|
|
// form a convex chain.
|
|
{
|
|
typedef Polygon_traits_2< R > P_traits;
|
|
typedef std::vector< Point_2 > Cont;
|
|
typedef Polygon_2< P_traits, Cont > Polygon_2;
|
|
|
|
Polygon_2 p( points_begin, points_end);
|
|
return p.is_convex();
|
|
} // is_convex( points_begin, points_end)
|
|
|
|
};
|
|
|
|
CGAL_END_NAMESPACE
|
|
#include <CGAL/Optimisation/assertions.h>
|
|
#include <cmath>
|
|
#ifdef CGAL_USE_LEDA
|
|
#include <CGAL/leda_real.h>
|
|
#endif // CGAL_USE_LEDA
|
|
CGAL_BEGIN_NAMESPACE
|
|
|
|
template < class _FT >
|
|
struct Sqrt
|
|
: public CGAL_STD::binary_function< _FT, _FT, _FT >
|
|
{
|
|
typedef _FT FT;
|
|
|
|
FT
|
|
operator()( const FT& x) const
|
|
{ return CGAL::sqrt( x); }
|
|
|
|
};
|
|
template < class _R >
|
|
class _Kgon_perimeter_operator
|
|
: public CGAL_STD::binary_function< Point_2< _R >,
|
|
Point_2< _R >,
|
|
typename _R::FT >
|
|
{
|
|
public:
|
|
typedef _R R;
|
|
typedef Point_2< R > Point_2;
|
|
typedef typename R::FT FT;
|
|
|
|
_Kgon_perimeter_operator( const Point_2& p)
|
|
: root( p)
|
|
{}
|
|
|
|
FT
|
|
operator()( const Point_2& p, const Point_2& q) const
|
|
{ return dist( p, root) + dist( p, q) - dist( q, root); }
|
|
|
|
private:
|
|
static
|
|
FT
|
|
dist( const Point_2& p, const Point_2& q)
|
|
{ return CGAL::sqrt( squared_distance( p, q)); }
|
|
|
|
const Point_2& root;
|
|
};
|
|
|
|
|
|
template < class _R >
|
|
class Kgon_perimeter_traits
|
|
{
|
|
public:
|
|
typedef _R R;
|
|
typedef Point_2< R > Point_2;
|
|
typedef typename _R::FT FT;
|
|
typedef _Kgon_perimeter_operator< R > Operation;
|
|
|
|
int
|
|
min_k() const
|
|
{ return 2; }
|
|
|
|
FT
|
|
init( const Point_2& p, const Point_2& r) const
|
|
{ return operation( r)( p, r); }
|
|
|
|
Operation
|
|
operation( const Point_2& p) const
|
|
{ return Operation( p); }
|
|
|
|
#ifndef CGAL_CFG_NO_MEMBER_TEMPLATES
|
|
template < class RandomAccessIC, class OutputIterator >
|
|
#else
|
|
typedef typename std::vector< Point_2 >::iterator
|
|
RandomAccessIC;
|
|
typedef typename std::vector< int >::reverse_iterator
|
|
OutputIterator;
|
|
#endif
|
|
OutputIterator
|
|
compute_min_k_gon( RandomAccessIC points_begin,
|
|
RandomAccessIC points_end,
|
|
FT& max_perimeter,
|
|
OutputIterator o) const
|
|
// RandomAccessIC is a random access iterator or
|
|
// circulator with value_type Point_2.
|
|
// OutputIterator has value_type Point_2.
|
|
//
|
|
// PRE: n := | [points_begin, points_end) | >= min_k() and
|
|
// the points described by the range [points_begin, points_end)
|
|
// form the boundary of a convex polygon oriented counterclockwise.
|
|
//
|
|
// POST: write the points of [points_begin, points_end)
|
|
// forming a min_k()-gon rooted at points_begin[0] of maximum
|
|
// perimeter to o in counterclockwise order and return the
|
|
// past-the-end iterator for that range (== o + min_k()).
|
|
{
|
|
#ifndef CGAL_CFG_NO_NAMESPACE
|
|
using std::bind2nd;
|
|
using std::less;
|
|
using std::max_element;
|
|
#endif
|
|
|
|
CGAL_optimisation_precondition_code(
|
|
int number_of_points(
|
|
iterator_distance( points_begin, points_end));)
|
|
CGAL_optimisation_precondition( number_of_points > min_k());
|
|
|
|
// kind of messy, but first we have to have something
|
|
// like Distance (function object) ...
|
|
RandomAccessIC maxi(
|
|
max_element(
|
|
points_begin + 1,
|
|
points_end,
|
|
compose2_2(
|
|
less< FT >(),
|
|
bind2nd( operation( points_begin[0]), points_begin[0]),
|
|
bind2nd( operation( points_begin[0]), points_begin[0]))));
|
|
|
|
// give result:
|
|
*o++ = iterator_distance( points_begin, maxi);
|
|
*o++ = 0;
|
|
|
|
return o;
|
|
} // compute_min_k_gon( ... )
|
|
|
|
#ifndef CGAL_CFG_NO_MEMBER_TEMPLATES
|
|
template < class RandomAccessIC >
|
|
#endif
|
|
bool
|
|
is_convex( RandomAccessIC points_begin,
|
|
RandomAccessIC points_end) const
|
|
// PRE: value_type of RandomAccessIC is Point_2
|
|
// POST: return true, iff the points [ points_begin, points_end)
|
|
// form a convex chain.
|
|
{
|
|
typedef Polygon_traits_2< R > P_traits;
|
|
typedef std::vector< Point_2 > Cont;
|
|
typedef Polygon_2< P_traits, Cont > Polygon_2;
|
|
|
|
Polygon_2 p( points_begin, points_end);
|
|
return p.is_convex();
|
|
} // is_convex( points_begin, points_end)
|
|
|
|
};
|
|
|
|
|
|
template < class RandomAccessIC,
|
|
class OutputIterator >
|
|
inline
|
|
OutputIterator
|
|
maximum_area_inscribed_k_gon(
|
|
RandomAccessIC points_begin,
|
|
RandomAccessIC points_end,
|
|
int k,
|
|
OutputIterator o)
|
|
//
|
|
// preconditions:
|
|
// --------------
|
|
// * Traits fulfills the requirements for an extremal polygon
|
|
// traits class
|
|
// * the range [points_begin, points_end) of size n > 0
|
|
// describes the vertices of a convex polygon $P$
|
|
// enumerated clock- or counterclockwise
|
|
// * value_type of RandomAccessIC (=: Point_2)
|
|
// is Point_2<R> for some representation class R
|
|
// * OutputIterator accepts Point_2 as value_type
|
|
// * k >= 3
|
|
//
|
|
// functionality:
|
|
// --------------
|
|
// computes maximum area inscribed k-gon $P_k$
|
|
// of the polygon $P$,
|
|
// writes the indices (relative to points_begin)
|
|
// of $P_k$'s vertices to o and
|
|
// returns the past-the-end iterator of that sequence.
|
|
{
|
|
return CGAL_maximum_area_inscribed_k_gon(
|
|
points_begin,
|
|
points_end,
|
|
k,
|
|
o,
|
|
std::value_type( points_begin));
|
|
} // maximum_area_inscribed_k_gon( ... )
|
|
|
|
template < class RandomAccessIC,
|
|
class OutputIterator,
|
|
class R >
|
|
inline
|
|
OutputIterator
|
|
CGAL_maximum_area_inscribed_k_gon(
|
|
RandomAccessIC points_begin,
|
|
RandomAccessIC points_end,
|
|
int k,
|
|
OutputIterator o,
|
|
Point_2< R >*)
|
|
//
|
|
// preconditions:
|
|
// --------------
|
|
// * Traits fulfills the requirements for an extremal polygon
|
|
// traits class
|
|
// * the range [points_begin, points_end) of size n > 0
|
|
// describes the vertices of a convex polygon $P$
|
|
// enumerated clock- or counterclockwise
|
|
// * R is a CGAL representation class
|
|
// * value_type of RandomAccessIC is Point_2<R>
|
|
// * OutputIterator accepts Point_2<R> as value_type
|
|
// * k >= 3
|
|
//
|
|
// functionality:
|
|
// --------------
|
|
// computes maximum area inscribed k-gon $P_k$
|
|
// of the polygon $P$,
|
|
// writes the indices (relative to points_begin)
|
|
// of $P_k$'s vertices to o and
|
|
// returns the past-the-end iterator of that sequence.
|
|
{
|
|
return extremal_polygon(
|
|
points_begin,
|
|
points_end,
|
|
k,
|
|
o,
|
|
Kgon_area_traits< R >());
|
|
} // CGAL_maximum_area_inscribed_k_gon( ... )
|
|
|
|
template < class RandomAccessIC,
|
|
class OutputIterator >
|
|
inline
|
|
OutputIterator
|
|
maximum_perimeter_inscribed_k_gon(
|
|
RandomAccessIC points_begin,
|
|
RandomAccessIC points_end,
|
|
int k,
|
|
OutputIterator o)
|
|
//
|
|
// preconditions:
|
|
// --------------
|
|
// * Traits fulfills the requirements for an extremal polygon
|
|
// traits class
|
|
// * the range [points_begin, points_end) of size n > 0
|
|
// describes the vertices of a convex polygon $P$
|
|
// enumerated clock- or counterclockwise
|
|
// * value_type of RandomAccessIC (=: Point_2)
|
|
// is Point_2<R> for some representation class R
|
|
// * OutputIterator accepts Point_2 as value_type
|
|
// * k >= 2
|
|
//
|
|
// functionality:
|
|
// --------------
|
|
// computes maximum perimeter inscribed k-gon $P_k$
|
|
// of the polygon $P$,
|
|
// writes the indices (relative to points_begin)
|
|
// of $P_k$'s vertices to o and
|
|
// returns the past-the-end iterator of that sequence.
|
|
{
|
|
return CGAL_maximum_perimeter_inscribed_k_gon(
|
|
points_begin,
|
|
points_end,
|
|
k,
|
|
o,
|
|
std::value_type( points_begin));
|
|
} // maximum_perimeter_inscribed_k_gon( ... )
|
|
|
|
template < class RandomAccessIC,
|
|
class OutputIterator,
|
|
class R >
|
|
inline
|
|
OutputIterator
|
|
CGAL_maximum_perimeter_inscribed_k_gon(
|
|
RandomAccessIC points_begin,
|
|
RandomAccessIC points_end,
|
|
int k,
|
|
OutputIterator o,
|
|
Point_2< R >*)
|
|
//
|
|
// preconditions:
|
|
// --------------
|
|
// * Traits fulfills the requirements for an extremal polygon
|
|
// traits class
|
|
// * the range [points_begin, points_end) of size n > 0
|
|
// describes the vertices of a convex polygon $P$
|
|
// enumerated clock- or counterclockwise
|
|
// * R is a CGAL representation class
|
|
// * value_type of RandomAccessIC is Point_2<R>
|
|
// * OutputIterator accepts Point_2<R> as value_type
|
|
// * k >= 2
|
|
//
|
|
// functionality:
|
|
// --------------
|
|
// computes maximum perimeter inscribed k-gon $P_k$
|
|
// of the polygon $P$,
|
|
// writes the indices (relative to points_begin)
|
|
// of $P_k$'s vertices to o and
|
|
// returns the past-the-end iterator of that sequence.
|
|
{
|
|
return extremal_polygon(
|
|
points_begin,
|
|
points_end,
|
|
k,
|
|
o,
|
|
Kgon_perimeter_traits< R >());
|
|
} // CGAL_maximum_perimeter_inscribed_k_gon( ... )
|
|
|
|
CGAL_END_NAMESPACE
|
|
|
|
#endif // ! (CGAL_EXTREMAL_POLYGON_TRAITS_2_H)
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// ** EOF
|
|
// ----------------------------------------------------------------------------
|
|
|