mirror of https://github.com/CGAL/cgal
146 lines
4.1 KiB
C
146 lines
4.1 KiB
C
// Copyright (c) 1999 Max-Planck-Institute Saarbruecken (Germany).
|
|
// All rights reserved.
|
|
//
|
|
// This file is part of CGAL (www.cgal.org); you may redistribute it under
|
|
// the terms of the Q Public License version 1.0.
|
|
// See the file LICENSE.QPL distributed with CGAL.
|
|
//
|
|
// 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$
|
|
//
|
|
//
|
|
// Author(s) : Stefan Schirra
|
|
|
|
|
|
#ifndef CGAL_CH_EDDY_C
|
|
#define CGAL_CH_EDDY_C
|
|
|
|
#ifndef CGAL_CH_EDDY_H
|
|
#include <CGAL/ch_eddy.h>
|
|
#endif // CGAL_CH_EDDY_H
|
|
|
|
#ifndef CGAL_CH_NO_POSTCONDITIONS
|
|
#include <CGAL/convexity_check_2.h>
|
|
#endif // CGAL_CH_NO_POSTCONDITIONS
|
|
|
|
#include <CGAL/ch_assertions.h>
|
|
#include <CGAL/ch_selected_extreme_points_2.h>
|
|
#include <CGAL/algorithm.h>
|
|
#include <CGAL/functional.h>
|
|
#include <list>
|
|
#include <algorithm>
|
|
|
|
CGAL_BEGIN_NAMESPACE
|
|
template <class List, class ListIterator, class Traits>
|
|
void
|
|
ch__recursive_eddy(List& L,
|
|
ListIterator a_it, ListIterator b_it,
|
|
const Traits& ch_traits)
|
|
{
|
|
typedef typename Traits::Point_2 Point_2;
|
|
typedef typename Traits::Left_turn_2 Left_turn_2;
|
|
typedef typename Traits::Less_signed_distance_to_line_2 Less_dist;
|
|
|
|
Left_turn_2 left_turn = ch_traits.left_turn_2_object();
|
|
|
|
CGAL_ch_precondition( \
|
|
std::find_if(a_it, b_it, \
|
|
bind_1(bind_1(left_turn, *b_it), *a_it)) \
|
|
!= b_it );
|
|
|
|
|
|
ListIterator f_it = successor(a_it);
|
|
Less_dist less_dist = ch_traits.less_signed_distance_to_line_2_object();
|
|
ListIterator
|
|
c_it = std::min_element( f_it, b_it, // max before
|
|
bind_1(bind_1(less_dist, *a_it), *b_it));
|
|
Point_2 c = *c_it;
|
|
|
|
c_it = std::partition(f_it, b_it, bind_1(bind_1(left_turn, c), *a_it));
|
|
f_it = std::partition(c_it, b_it, bind_1(bind_1(left_turn, *b_it), c));
|
|
c_it = L.insert(c_it, c);
|
|
L.erase( f_it, b_it );
|
|
|
|
if ( successor(a_it) != c_it )
|
|
{
|
|
ch__recursive_eddy( L, a_it, c_it, ch_traits);
|
|
}
|
|
if ( successor(c_it) != b_it )
|
|
{
|
|
ch__recursive_eddy( L, c_it, b_it, ch_traits);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
template <class InputIterator, class OutputIterator, class Traits>
|
|
OutputIterator
|
|
ch_eddy(InputIterator first, InputIterator last,
|
|
OutputIterator result,
|
|
const Traits& ch_traits)
|
|
{
|
|
typedef typename Traits::Point_2 Point_2;
|
|
typedef typename Traits::Left_turn_2 Left_turn_2;
|
|
typedef typename Traits::Equal_2 Equal_2;
|
|
|
|
Left_turn_2 left_turn = ch_traits.left_turn_2_object();
|
|
Equal_2 equal_points = ch_traits.equal_2_object();
|
|
|
|
if (first == last) return result;
|
|
std::list< Point_2 > L;
|
|
std::copy( first, last, std::back_inserter(L) );
|
|
|
|
typedef typename std::list< Point_2 >::iterator list_iterator;
|
|
list_iterator w, e;
|
|
ch_we_point(L.begin(), L.end(), w, e, ch_traits);
|
|
Point_2 wp = *w;
|
|
Point_2 ep = *e;
|
|
if (equal_points(wp,ep) )
|
|
{
|
|
*result = wp; ++result;
|
|
return result;
|
|
}
|
|
|
|
L.erase(w);
|
|
L.erase(e);
|
|
|
|
e = std::partition(L.begin(), L.end(),
|
|
bind_1(bind_1(left_turn, ep), wp) );
|
|
L.push_front(wp);
|
|
e = L.insert(e, ep);
|
|
|
|
if ( successor(L.begin()) != e )
|
|
{
|
|
ch__recursive_eddy( L, L.begin(), e, ch_traits);
|
|
}
|
|
w = std::find_if( e, L.end(), bind_1(bind_1(left_turn, wp), ep) );
|
|
if ( w == L.end() )
|
|
{
|
|
L.erase( ++e, L.end() );
|
|
return std::copy( L.begin(), L.end(), result );
|
|
}
|
|
w = L.insert(L.end(), wp);
|
|
ch__recursive_eddy( L, e, w, ch_traits);
|
|
|
|
|
|
CGAL_ch_postcondition( \
|
|
is_ccw_strongly_convex_2( L.begin(), w, ch_traits) );
|
|
CGAL_ch_expensive_postcondition( \
|
|
ch_brute_force_check_2( first, last, \
|
|
L.begin(), w, ch_traits ) );
|
|
|
|
return std::copy( L.begin(), w, result );
|
|
|
|
}
|
|
|
|
CGAL_END_NAMESPACE
|
|
|
|
#endif // CGAL_CH_EDDY_C
|
|
|