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

468 lines
15 KiB
C
Raw Normal View History

// Copyright (c) 1997
// Utrecht University (The Netherlands),
// ETH Zurich (Switzerland),
// INRIA Sophia-Antipolis (France),
// Max-Planck-Institute Saarbruecken (Germany),
// and Tel-Aviv University (Israel). 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 Lesser 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: LGPL-3.0+
//
//
// Author(s) : Wieger Wesselink <wieger@cs.ruu.nl>
/*!
\file Polygon_2_algorithms.h
*/
#ifndef CGAL_POLYGON_2_ALGORITHMS_H
#define CGAL_POLYGON_2_ALGORITHMS_H
#include <CGAL/config.h>
#include <CGAL/enum.h>
#include <CGAL/Bbox_2.h>
#include <CGAL/Polygon_2/polygon_assertions.h>
///
namespace CGAL {
//-----------------------------------------------------------------------//
// algorithms for sequences of 2D points
//-----------------------------------------------------------------------//
/// \addtogroup PkgPolygon2Functions
/// @{
/// Returns an iterator to the leftmost point from the range
/// `[first,last)`. In case of a tie, the point
/// with the smallest `y`-coordinate is taken.
///
/// \tparam Traits is a model of the concept `PolygonTraits_2`.
/// Only the members `Less_xy_2` and
/// `less_xy_2_object()` are used.
/// \tparam ForwardIterator must have `Traits::Point_2` as value type.
///
///
/// \sa `CGAL::right_vertex_2()`
/// \sa `CGAL::top_vertex_2()`
/// \sa `CGAL::bottom_vertex_2()`
/// \sa `CGAL::Polygon_2`
template <class ForwardIterator, class PolygonTraits>
ForwardIterator left_vertex_2(ForwardIterator first,
ForwardIterator last,
const PolygonTraits& traits);
/// Returns an iterator to the rightmost point from the range
/// `[first,last)`. In case of a tie, the point
/// with the largest `y`-coordinate is taken.
///
/// \tparam Traits is a model of the concept
/// `PolygonTraits_2`.
/// In fact, only the members `Less_xy_2` and
/// `less_xy_2_object()` are used.
/// \tparam ForwardIterator must have`Traits::Point_2` as value type.
///
///
/// \sa `CGAL::left_vertex_2()`
/// \sa `CGAL::top_vertex_2()`
/// \sa `CGAL::bottom_vertex_2()`
/// \sa `CGAL::Polygon_2`
template <class ForwardIterator, class PolygonTraits>
ForwardIterator right_vertex_2(ForwardIterator first,
ForwardIterator last,
const PolygonTraits& traits);
/// Returns an iterator to the topmost point from the range
/// `[first,last)`. In case of a tie, the point
/// with the largest `x`-coordinate is taken.
///
/// \tparam Traits is a model of the concept
/// `PolygonTraits_2`.
/// Only the members `Less_yx_2` and
/// `less_yx_2_object()` are used.
/// \tparam ForwardIterator must have `Traits::Point_2` as value type.
///
/// \sa `CGAL::left_vertex_2()`
/// \sa `CGAL::right_vertex_2()`
/// \sa `CGAL::bottom_vertex_2()`
/// \sa `CGAL::Polygon_2`
template <class ForwardIterator, class PolygonTraits>
ForwardIterator top_vertex_2(ForwardIterator first,
ForwardIterator last,
const PolygonTraits& traits);
/// Returns an iterator to the bottommost point from the range
/// `[first,last)`. In case of a tie, the point
/// with the smallest `x`-coordinate is taken.
///
/// \tparam Traits is a model of the concept
/// `PolygonTraits_2`.
/// Only the members `Less_yx_2` and
/// `less_yx_2_object()` are used.
/// \tparam ForwardIterator must have `Traits::Point_2` as value type.
///
/// \sa `CGAL::left_vertex_2()`
/// \sa `CGAL::right_vertex_2()`
/// \sa `CGAL::top_vertex_2()`
/// \sa `CGAL::Polygon_2`
/// \sa `PolygonTraits_2`
template <class ForwardIterator, class PolygonTraits>
ForwardIterator bottom_vertex_2(ForwardIterator first,
ForwardIterator last,
const PolygonTraits& traits);
/// Computes the signed area of the polygon defined by the range of points
/// `[first,last)`. The area is returned in the parameter
/// `result`. The sign is positive for counterclockwise polygons, negative for
/// clockwise polygons. If the polygon is not simple, the area is not well defined.
/// The functionality is also available by the `polygon_area_2()` function, which
/// returns the area instead of taking it as a parameter.
///
/// \tparam Traits is a model of the concept
/// `PolygonTraits_2`.
/// Only the following members of this traits class are used:
/// - `Compute_area_2` : Computes the signed area of the
/// oriented triangle defined by 3 `Point_2` passed as arguments.
/// - `FT`
/// - `compute_area_2_object()`
/// \tparam ForwardIterator must have `Traits::Point_2` as value type.
///
/// \sa `CGAL::polygon_area_2()`
/// \sa `PolygonTraits_2`
/// \sa `CGAL::orientation_2()`
/// \sa `CGAL::Polygon_2`
template <class ForwardIterator, class PolygonTraits>
void
area_2( ForwardIterator first, ForwardIterator last,
typename PolygonTraits::FT &result,
const PolygonTraits& traits)
{
typedef typename PolygonTraits::FT FT;
result = FT(0);
// check if the polygon is empty
if (first == last) return;
ForwardIterator second = first; ++second;
// check if the polygon has only one point
if (second == last) return;
typename PolygonTraits::Compute_area_2 compute_area_2 =
traits.compute_area_2_object();
ForwardIterator third = second;
while (++third != last) {
result = result + compute_area_2(*first, *second, *third);
second = third;
}
}
/// Computes the signed area of the polygon defined by the range of points
/// `[first,last)`.
/// The sign is positive for counterclockwise polygons, negative for
/// clockwise polygons. If the polygon is not simple, the area is not well defined.
///
/// \tparam Traits is a model of the concept `PolygonTraits_2`. Only the following members of this traits class are used:
/// - `Compute_area_2` : Computes the signed area of the
/// oriented triangle defined by 3 `Point_2` passed as arguments.
/// - `FT`
/// - `compute_area_2_object`
/// \tparam ForwardIterator must have `Traits::Point_2` as value type.
///
///
/// \sa `PolygonTraits_2 `
/// \sa `CGAL::orientation_2()`
/// \sa `CGAL::Polygon_2 `
template <class ForwardIterator, class PolygonTraits>
typename PolygonTraits::FT
polygon_area_2( ForwardIterator first, ForwardIterator last,
const PolygonTraits& traits)
{
typedef typename PolygonTraits::FT FT;
FT result = FT(0);
// check if the polygon is empty
if (first == last) return result;
ForwardIterator second = first; ++second;
// check if the polygon has only one point
if (second == last) return result;
typename PolygonTraits::Compute_area_2 compute_area_2 =
traits.compute_area_2_object();
ForwardIterator third = second;
while (++third != last) {
result = result + compute_area_2(*first, *second, *third);
second = third;
}
return result;
}
/// Checks if the polygon is convex.
///
/// \tparam Traits is a model of the concept
/// `PolygonTraits_2`.
/// Only the following members of this traits class are used:
/// - `Less_xy_2`
/// - `Orientation_2`
/// - `less_xy_2_object`
/// - `orientation_2_object`
/// \tparam ForwardIterator must have `PolygonTraits::Point_2` as value type.
///
/// \sa `PolygonTraits_2 `
/// \sa `CGAL::Polygon_2 `
template <class ForwardIterator, class PolygonTraits>
bool is_convex_2(ForwardIterator first,
ForwardIterator last,
const PolygonTraits& traits);
/// Checks if the polygon defined by the
/// iterator range `[first,last)` is simple, that is, if the edges
/// do not intersect, except consecutive edges in their common vertex.
///
/// \tparam Traits is a model of the concept
/// `PolygonTraits_2`.
/// Only the following members of this traits class are used:
/// - `Point_2`
/// - `Less_xy_2`
/// - `Orientation_2`
/// - `less_xy_2_object()`
/// - `orientation_2_object()`
/// \tparam ForwardIterator must have `PolygonTraits::Point_2` as value type.
///
/// ### Implementation##
///
/// The simplicity test is implemented by means of a plane sweep algorithm.
/// The algorithm is quite robust when used with inexact number types.
/// The running time is `O(n log n)`, where n is the number of vertices of the
/// polygon.
///
/// \sa `PolygonTraits_2`
/// \sa `CGAL::Polygon_2`
template <class ForwardIterator, class PolygonTraits>
bool is_simple_2(ForwardIterator first,
ForwardIterator last,
const PolygonTraits& traits);
// In the following two functions we would like to use Traits::Point_2
// instead of Point, but this is not allowed by g++ 2.7.2.
///
/// Computes on which side of a polygon a point lies.
/// \tparam Traits is a model of the concept
/// `PolygonTraits_2`.
/// Only the following members of this traits class are used:
/// - `Less_xy_2`
/// - `Compare_x_2`
/// - `Compare_y_2`
/// - `Orientation_2`
/// - `less_xy_2_object()`
/// - `compare_x_2_object()`
/// - `compare_y_2_object()`
/// - `orientation_2_object()`
/// \tparam ForwardIterator must have `PolygonTraits::Point_2` as value type.
///
/// \sa `PolygonTraits_2`
/// \sa `CGAL::bounded_side_2()`
/// \sa `CGAL::is_simple_2()`
/// \sa `CGAL::Polygon_2`
/// \sa `Oriented_side`
template <class ForwardIterator, class Point, class Traits>
Oriented_side oriented_side_2(ForwardIterator first,
ForwardIterator last,
const Point& point,
const Traits& traits);
/// Computes if a point lies inside a polygon.
/// The polygon is defined by the sequence of points `[first,last)`.
/// Being inside is defined by the odd-even rule. If we take a ray starting at the
/// point and extending to infinity (in any direction), we count the number of
/// intersections. If this number is odd, the point is inside, otherwise it is
/// outside. If the point is on a polygon edge, a special value is returned. A
/// simple polygon divides the plane in an unbounded and a bounded region.
/// According to the definition points in the bounded region are inside the polygon.
///
///
/// \tparam Traits is a model of the concept
/// `PolygonTraits_2`.
/// Only the following members of this traits class are used:
/// - `Compare_x_2`
/// - `Compare_y_2`
/// - `Orientation_2`
/// - `compare_x_2_object()`
/// - `compare_y_2_object()`
/// - `orientation_2_object()`
/// \tparam ForwardIterator must have `Traits::Point_2` as value type.
///
/// ### Implementation ###
///
/// The running time is linear in the number of vertices of the polygon.
/// A horizontal ray is taken to count the number of intersections.
/// Special care is taken that the result is correct even if there are degeneracies
/// (if the ray passes through a vertex).
///
///
/// \sa `PolygonTraits_2`
/// \sa `CGAL::oriented_side_2()`
/// \sa `CGAL::Polygon_2 `
/// \sa `CGAL::Bounded_side`
template <class ForwardIterator, class Point, class PolygonTraits>
Bounded_side bounded_side_2(ForwardIterator first,
ForwardIterator last,
const Point& point,
const PolygonTraits& traits);
/// Computes if a polygon is clockwise or counterclockwise oriented.
/// \pre `is_simple_2(first, last, traits);`
///
/// \tparam Traits is a model of the concept
/// `PolygonTraits_2`.
/// Only the following members of this traits class are used:
/// - `Less_xy_2`
/// - `less_xy_2_object()`
/// - `orientation_2_object()`
/// \tparam ForwardIterator must have`Traits::Point_2` as value type.
///
///
///
/// \sa `PolygonTraits_2`
/// \sa `CGAL::is_simple_2()`
/// \sa `CGAL::Polygon_2`
/// \sa `CGAL::Orientation_2`
template <class ForwardIterator, class Traits>
Orientation orientation_2(ForwardIterator first,
ForwardIterator last,
const Traits& traits);
/// @}
//-----------------------------------------------------------------------//
// implementation
//-----------------------------------------------------------------------//
template <class ForwardIterator>
inline
ForwardIterator left_vertex_2(ForwardIterator first,
ForwardIterator last)
{
typedef typename Kernel_traits<
typename std::iterator_traits<ForwardIterator>::value_type>::Kernel K;
return left_vertex_2(first, last, K());
}
template <class ForwardIterator>
inline
ForwardIterator right_vertex_2(ForwardIterator first,
ForwardIterator last)
{
typedef typename Kernel_traits<
typename std::iterator_traits<ForwardIterator>::value_type>::Kernel K;
return right_vertex_2(first, last, K());
}
template <class ForwardIterator>
inline
ForwardIterator top_vertex_2(ForwardIterator first,
ForwardIterator last)
{
typedef typename Kernel_traits<
typename std::iterator_traits<ForwardIterator>::value_type>::Kernel K;
return top_vertex_2(first, last, K());
}
template <class ForwardIterator>
inline
ForwardIterator bottom_vertex_2(ForwardIterator first,
ForwardIterator last)
{
typedef typename Kernel_traits<
typename std::iterator_traits<ForwardIterator>::value_type>::Kernel K;
return bottom_vertex_2(first, last, K());
}
template <class ForwardIterator, class Numbertype>
inline
void area_2(ForwardIterator first,
ForwardIterator last,
Numbertype& result)
{
typedef typename Kernel_traits<
typename std::iterator_traits<ForwardIterator>::value_type>::Kernel K;
area_2(first, last, result, K());
}
template <class ForwardIterator>
inline
bool is_convex_2(ForwardIterator first,
ForwardIterator last)
{
typedef typename Kernel_traits<
typename std::iterator_traits<ForwardIterator>::value_type>::Kernel K;
return is_convex_2(first, last, K());
}
template <class ForwardIterator>
inline
bool is_simple_2(ForwardIterator first,
ForwardIterator last)
{
typedef typename Kernel_traits<
typename std::iterator_traits<ForwardIterator>::value_type>::Kernel K;
return is_simple_2(first, last, K());
}
template <class ForwardIterator>
inline
Oriented_side oriented_side_2(
ForwardIterator first,
ForwardIterator last,
const typename std::iterator_traits<ForwardIterator>::value_type& point)
{
typedef typename Kernel_traits<
typename std::iterator_traits<ForwardIterator>::value_type>::Kernel K;
return oriented_side_2(first, last, point, K());
}
template <class ForwardIterator>
inline
Bounded_side bounded_side_2(
ForwardIterator first,
ForwardIterator last,
const typename std::iterator_traits<ForwardIterator>::value_type& point)
{
typedef typename Kernel_traits<
typename std::iterator_traits<ForwardIterator>::value_type>::Kernel K;
return bounded_side_2(first, last, point, K());
}
template <class ForwardIterator>
inline
Orientation orientation_2(ForwardIterator first,
ForwardIterator last)
{
typedef typename Kernel_traits<
typename std::iterator_traits<ForwardIterator>::value_type>::Kernel K;
return orientation_2(first, last, K());
}
} //namespace CGAL
#include <CGAL/Polygon_2/Polygon_2_algorithms_impl.h>
#endif // CGAL_POLYGON_2_ALGORITHMS_H