Add Polygon in body-docs from doxygen branch.

This commit is contained in:
Philipp Möller 2012-09-19 14:42:11 +00:00
parent 2987470868
commit fd70d2f0e3
11 changed files with 708 additions and 87 deletions

7
.gitattributes vendored
View File

@ -4871,6 +4871,13 @@ Point_set_processing_3/test/Point_set_processing_3/normal_estimation_test.cmd eo
Point_set_processing_3/test/Point_set_processing_3/remove_outliers_test.cmd eol=lf
Point_set_processing_3/test/Point_set_processing_3/smoothing_test.cmd eol=lf
Point_set_processing_3/test/Point_set_processing_3/smoothing_test.cpp -text
Polygon/doc/Polygon/Concepts/PolygonTraits_2.h -text
Polygon/doc/Polygon/PackageDescription.txt -text
Polygon/doc/Polygon/Polygon.txt -text
Polygon/doc/Polygon/examples.txt -text
Polygon/doc/Polygon/fig/pgn_algos.gif -text svneol=unset#image/gif
Polygon/doc/Polygon/fig/pgn_algos.pdf -text svneol=unset#application/pdf
Polygon/doc/Polygon/fig/polygon.png -text svneol=unset#image/png
Polygon/doc_tex/Polygon/pgn_algos.gif -text svneol=unset#image/gif
Polygon/doc_tex/Polygon/pgn_algos.ipe -text svneol=unset#application/postscript
Polygon/doc_tex/Polygon/pgn_algos.pdf -text svneol=unset#application/pdf

View File

@ -78,6 +78,24 @@ namespace for the XML file to be processed properly. -->
</doxygen>
</project>
<project>
<name>2D Polygons</name>
<input>../Polygon/doc</input>
<input>../Polygon/include</input>
<doxygen>
<string name="STRIP_FROM_PATH">../Polygon/doc/Polygon/</string>
<string name="STRIP_FROM_INC_PATH">../Polygon/include</string>
<string name="GENERATE_TAGFILE">./tags/Polygon.tag</string>
<string name="IMAGE_PATH">../Polygon/doc/Polygon/fig</string>
<string name="EXAMPLE_PATH">../Polygon/examples</string>
<bool name="EXTRACT_ALL">false</bool>
<bool name="HIDE_UNDOC_MEMBERS">true</bool>
<bool name="HIDE_UNDOC_CLASSES">true</bool>
<bool name="SHOW_INCLUDE_FILES">true</bool>
</doxygen>
</project>
<project>
<name>Planar Parameterization of Triangulated Surface Meshes</name>
<input>../Surface_mesh_parameterization/doc/Surface_mesh_parameterization</input>
@ -1210,6 +1228,7 @@ namespace for the XML file to be processed properly. -->
<item>./doc/fig</item>
<item>../Algebraic_foundations/doc/Algebraic_foundations/fig</item>
<item>../AABB_tree/doc/AABB_tree/fig</item>
<item>../Polygon/doc/Polygon/fig</item>
<item>../Number_types/doc/Number_types/fig</item>
<item>../Alpha_shapes_2/doc/Alpha_shapes_2/fig</item>
<item>../Alpha_shapes_3/doc/Alpha_shapes_3/fig</item>
@ -1287,6 +1306,7 @@ namespace for the XML file to be processed properly. -->
<list name="TAGFILES" append="false">
<item>./tags/Algebraic_foundations.tag=../../CGAL.CGAL.Algebraic-Foundations/html</item>
<item>./tags/AABB_tree.tag=../../CGAL.CGAL.3D-Fast-Intersection-and-Distance-Computation/html</item>
<item>./tags/Polygon.tag=../../CGAL.CGAL.2D-Polygons/html</item>
<item>./tags/Number_types.tag=../../CGAL.CGAL.Number-Types/html</item>
<item>./tags/Alpha_shapes_2.tag=../../CGAL.CGAL.2D-Alpha-Shapes/html</item>
<item>./tags/Alpha_shapes_3.tag=../../CGAL.CGAL.3D-Alpha-Shapes/html</item>

View File

@ -0,0 +1,143 @@
/*!
\ingroup PkgPolygon2Concepts
\cgalconcept
The `Polygon_2` class and the functions that implement the
functionality found in that class each are parameterized by a traits
class that defines the primitives used in the algorithms. The concept
`PolygonTraits_2` defines this common set of requirements.
The requirements of `PolygonTraits_2` are a subset of the kernel
requirements. We only list the types and methods which are required
and refer to the description of the kernel concept for details.
\hasModel The kernels supplied by \cgal are models of `PolygonTraits_2`.
\hasModel `CGAL::Projection_traits_xy_3<K>`
\hasModel `CGAL::Projection_traits_yz_3<K>`
\hasModel `CGAL::Projection_traits_zx_3<K>`
\sa `CGAL::Polygon_2<PolygonTraits_2, Container>`
*/
class PolygonTraits_2 {
public:
/// \name Creation
/// @{
///
PolygonTraits_2();
///
PolygonTraits_2(const PolygonTraits_2&);
/// @}
/// \name Types
/// @{
/*!
*/
typedef Hidden_type FT;
/*!
The point type.
*/
typedef Hidden_type Point_2;
/*!
The segment type.
*/
typedef Hidden_type Segment_2;
/*!
*/
typedef Hidden_type Construct_segment_2;
/*!
*/
typedef Hidden_type Equal_2;
/*!
*/
typedef Hidden_type Less_xy_2;
/*!
*/
typedef Hidden_type Less_yx_2;
/*!
*/
typedef Hidden_type Compare_x_2;
/*!
*/
typedef Hidden_type Compare_y_2;
/*!
*/
typedef Hidden_type Orientation_2;
/*!
Computes the signed area of the oriented
triangle defined by 3 `Point_2` passed as arguments.
*/
typedef Hidden_type Compute_area_2;
/// @}
/// \name Operations
CONVERROR Check if this needs to be spread\n/// The following functions that create instances of the above predicate object types must exist.
/// @{
/*!
*/
Equal_2 equal_2_object();
/*!
*/
Less_xy_2 less_xy_2_object();
/*!
*/
Less_yx_2 less_yx_2_object();
/*!
*/
Compare_y_2 compare_y_2_object();
/*!
*/
Compare_x_2 compare_x_2_object();
/*!
*/
Orientation_2 orientation_2_object();
/*!
*/
Compute_area_2 compute_area_2_object();
/*!
*/
Construct_segment_2 construct_segment_2_object();
/// @}
}; /* end PolygonTraits_2 */

View File

@ -0,0 +1,26 @@
/// \defgroup PkgPolygon2 2D Polygon
/// \defgroup PkgPolygon2Concepts Concepts
/// \ingroup PkgPolygon2
/// \defgroup PkgPolygon2Functions Global Functions
/// \ingroup PkgPolygon2
/*!
\addtogroup PkgPolygon2
\todo check generated documentation
\PkgDescriptionBegin{2D Polygons}
\PkgPicture{polygon.png}
\PkgAuthor{Geert-Jan Giezeman and Wieger Wesselink}
\PkgDesc{This package provides a 2D polygon class and operations on sequences of points, like bounding box, extremal points, signed area, simplicity and convexity test, orientation, and point location. The demo includes operations on polygons, such as computing a convex partition, and the straight skeleton.}
\PkgSince{0.9}
\cgalbib{cgal:gw-p2}
\license{\ref licensesLGPL "LGPL"}
\PkgDescriptionEnd
## Assertions ##
The assertion flags for the polygons and polygon operations use
`POLYGON` in their names (<I>e.g.</I>, `CGAL_POLYGON_NO_ASSERTIONS`).
*/

View File

@ -0,0 +1,67 @@
/*!
\mainpage 2D Polygon
\authors Geert-Jan Giezeman and Wieger Wesselink
\autotoc
\section Introduction
A polygon is a closed chain of edges. Several algorithms are available for
polygons. For some of those algorithms, it is necessary that the polygon is
simple. A polygon is simple if edges don't intersect, except consecutive edges,
which intersect in their common vertex.
The following algorithms are available:
- find the leftmost, rightmost, topmost and bottommost vertex.
- compute the (signed) area.
- check if a polygon is simple.
- check if a polygon is convex.
- find the orientation (clockwise or counterclockwise)
- check if a point lies inside a polygon.
All those operations take two forward iterators as parameters in order to
describe the polygon. These parameters have a point type as value type.
The type Polygon_2 can be used to represent polygons.
Polygons are dynamic. Vertices can be modified, inserted and erased.
They provide the algorithms described above as member functions.
Moreover, they provide ways of iterating over the vertices and edges.
Currently, the Polygon_2 class is a nice wrapper around a container of
points, but little more. Especially, computed values are not cached.
That is, when the Polygon_2::is_simple() member function is called
twice or more, the result is computed each time anew.
\section Examples
\subsection The Polygon Class
The following example creates a polygon and illustrates the usage of
some member functions.
\include Polygon.cpp
\image latex pgn_algos.gif "A polygon and some points"
\image html pgn_algos.gif "A polygon and some points"
\subsection Algorithms Operating on Sequences of Points
The following example creates a polygon and illustrates the usage of
some global functions that operate on sequences of points.
\include polygon_algorithms.cpp
\subsection Polygons in 3D Space
Sometimes it is useful to run a 2D algorithm on 3D data.
Polygons may be contours of a 3D object, where the contours
are organized in parallel slices, generated by segmentation
of image data from a scanner.
In order to avoid an explixit projection on the \c xy plane, one can
use the traits class Projection_traits_xy_3 which is part of the 2D
and 3D Linear Geometric Kernel.
\include projected_polygon.cpp
*/

View File

@ -0,0 +1,6 @@
/*!
\example Example.cpp
\example polygon_algorithms.cpp
\example Polygon.cpp
\example projected_polygon.cpp
*/

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 B

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -23,6 +23,10 @@
// Author(s) : Geert-Jan Giezeman <geert@cs.uu.nl>
// Wieger Wesselink
/*!
\file Polygon_2.h
*/
#ifndef CGAL_POLYGON_2_H
#define CGAL_POLYGON_2_H
@ -43,19 +47,50 @@
namespace CGAL {
/// \ingroup PkgPolygon2
/// The class Polygon_2 implements polygons. The Polygon_2 is
/// parameterized by a traits class and a container class. The latter
/// can be any class that fulfills the requirements for an STL
/// container. It defaults to the std::vector class.
///
/// Implementation
/// --------------
///
/// The methods `is_simple()`, `is_convex()`, `orientation()`,
/// `oriented_side()`, `bounded_side()`, `bbox()`, `area()`, `left_vertex()`,
/// `right_vertex()`, `top_vertex()` and `bottom_vertex()` are all
/// implemented using the algorithms on sequences of 2D points. See
/// the corresponding global functions for information about which
/// algorithms were used and what complexity they have.
///
/// Example
/// -------
/// The following code fragment creates a polygon and checks if it is convex.
///
/// \cgalexample{Polygon.cpp}
template <class Traits_P, class Container_P
= std::vector<typename Traits_P::Point_2> >
class Polygon_2 {
public:
/// \name Types
/// @{
/// The traits type.
typedef Traits_P Traits;
/// The container type.
typedef Container_P Container;
/// The number type, which is the {\em field type} of the points of the polygon.
typedef typename Traits_P::FT FT;
/// The point type of the polygon.
typedef typename Traits_P::Point_2 Point_2;
/// The type of a segment between two points of the polygon.
typedef typename Traits_P::Segment_2 Segment_2;
/// @}
typedef typename Container_P::difference_type difference_type;
typedef typename Container_P::value_type value_type;
typedef typename Container_P::pointer pointer;
@ -69,28 +104,60 @@ class Polygon_2 {
typedef typename Container_P::const_iterator const_iterator;
//-------------------------------------------------------//
typedef typename Container::iterator Vertex_iterator;
typedef typename Container::iterator Vertex_const_iterator;
//typedef typename Container::const_iterator Vertex_const_iterator; ??
/// \name Iterators
///
/// The following types denote iterators that allow to traverse
/// the vertices and edges of a polygon. Since it is questionable
/// whether a polygon should be viewed as a circular or as a
/// linear data structure both circulators and iterators are
/// defined. The circulators and iterators are
/// non-mutable.
///
/// \note At least conceptually. The enforcement
/// depends on preprocessor flags.
///
/// The iterator category is in all cases bidirectional, except
/// for Vertex_iterator, which has the same iterator category as
/// Container::iterator. **N.B.** In fact all of them should have
/// the same iterator category as Container::iterator. However,
/// due to compiler problems this is currently not possible.
///
/// @{
typedef Polygon_circulator<Container_P> Vertex_const_circulator;
///
typedef typename Container::iterator Vertex_iterator;
///
typedef Vertex_const_circulator Vertex_circulator;
//typedef typename Container::const_iterator Vertex_const_iterator; ??
///
typedef Polygon_2_edge_iterator<Traits_P,Container_P>
Edge_const_iterator;
///
typedef Polygon_2_const_edge_circulator<Traits_P,Container_P>
Edge_const_circulator;
/// @}
//--------------------------------------------------------
// Creation
//--------------------------------------------------------
typedef typename Container::iterator Vertex_const_iterator;
typedef Polygon_circulator<Container_P> Vertex_const_circulator;
/// \name Creation
/// @{
/// Creates an empty polygon.
Polygon_2(const Traits & p_traits = Traits()) : traits(p_traits) {}
/// Copy constructor.
Polygon_2(const Polygon_2<Traits_P,Container_P>& polygon)
: d_container(polygon.d_container), traits(polygon.traits) {}
/// Introduces a polygon with vertices from the sequence
/// defined by the range \c [first,last).
/// The value type of \c InputIterator must be \c Point_2.
template <class InputIterator>
Polygon_2(InputIterator first, InputIterator last,
Traits p_traits = Traits())
@ -100,59 +167,73 @@ class Polygon_2 {
std::copy(first, last, std::back_inserter(d_container));
}
//--------------------------------------------------------
// Operations
//--------------------------------------------------------
/// @}
void set(Vertex_iterator pos, const Point_2& x)
{ *pos = x; }
/// \name Modifiers
/// @{
void set(Polygon_circulator<Container>const &pos, const Point_2& x)
/// Acts as `*i = q`, except that that would be illegal because
/// the iterator is not mutable.
void set(Vertex_iterator i, const Point_2& q)
{ *i = q; }
void set(Polygon_circulator<Container>const &i, const Point_2& q)
{
*pos.mod_iterator() = x;
*i.mod_iterator() = q;
}
Vertex_iterator insert(Vertex_iterator pos, const Point_2& x)
/// Inserts the vertex `q` before `i`. The return value points to
/// the inserted vertex.
Vertex_iterator insert(Vertex_iterator i, const Point_2& q)
{
return d_container.insert(pos,x);
return d_container.insert(i,q);
}
Vertex_iterator insert(Vertex_circulator pos, const Point_2& x)
Vertex_iterator insert(Vertex_circulator i, const Point_2& q)
{
return d_container.insert(pos.mod_iterator(),x);
return d_container.insert(i.mod_iterator(),q);
}
/// Inserts the vertices in the range `[first, last)`
/// before `i`. The value type of points in the range
/// `[first,last)} must be \ccStyle{Point_2`.
template <class InputIterator>
void insert(Vertex_iterator pos,
void insert(Vertex_iterator i,
InputIterator first,
InputIterator last)
{ d_container.insert(pos, first, last); }
{ d_container.insert(i, first, last); }
template <class InputIterator>
void insert(Vertex_circulator pos,
void insert(Vertex_circulator i,
InputIterator first,
InputIterator last)
{ d_container.insert(pos.mod_iterator(), first, last); }
{ d_container.insert(i.mod_iterator(), first, last); }
/// Has the same semantics as `p.insert(p.vertices_end(), q)`.
void push_back(const Point_2& x)
{ d_container.insert(d_container.end(), x); }
void erase(Vertex_iterator pos)
{ d_container.erase(pos); }
/// Erases the vertex pointed to by `i`.
void erase(Vertex_iterator i)
{ d_container.erase(i); }
void erase(Vertex_circulator pos)
{ d_container.erase(pos.mod_iterator()); }
void erase(Vertex_circulator i)
{ d_container.erase(i.mod_iterator()); }
/// Erases the vertices in the range `[first, last)`.
void erase(Vertex_iterator first, Vertex_iterator last)
{
d_container.erase(first, last);
}
/// Erases the vertices in the range `[first, last)`.
void clear()
{
d_container.clear();
}
/// Reverses the orientation of the polygon. The vertex pointed to
/// by `p.vertices_begin()` remains the same.
void reverse_orientation()
{
if (size() <= 1)
@ -161,25 +242,28 @@ class Polygon_2 {
std::reverse(++i, d_container.end());
}
//--------------------------------------------------------
// Traversal of a polygon
//--------------------------------------------------------
/// @}
// Vertex_iterator vertices_begin()
// { return d_container.begin(); }
// Vertex_iterator vertices_end()
// { return d_container.end(); }
/// \name Access
/// The following methods of the class Polygon_2
/// return circulators and iterators that allow to traverse the
/// vertices and edges.
/// @{
/// Returns a constant iterator that allows to traverse the
/// vertices of the polygon.
Vertex_const_iterator vertices_begin() const
{ return const_cast<Polygon_2&>(*this).d_container.begin(); }
/// Returns the corresponding past-the-end iterator.
Vertex_const_iterator vertices_end() const
{ return const_cast<Polygon_2&>(*this).d_container.end(); }
// Vertex_const_circulator vertices_circulator() const
// { return Vertex_const_circulator(&d_container, d_container.begin()); }
/// Returns a mutable circulator that allows to traverse the
/// vertices of the polygon.
Vertex_const_circulator vertices_circulator() const
{
Polygon_2& self = const_cast<Polygon_2&>(*this);
@ -187,40 +271,59 @@ class Polygon_2 {
self.d_container.begin());
}
/// Returns a non-mutable iterator that allows to traverse the
/// edges of the polygon.
Edge_const_iterator edges_begin() const
{ return Edge_const_iterator(&d_container, d_container.begin()); }
/// Returns the corresponding past-the-end iterator.
Edge_const_iterator edges_end() const
{ return Edge_const_iterator(&d_container, d_container.end()); }
/// Returns a non-mutable circulator that allows to traverse the
/// edges of the polygon.
Edge_const_circulator edges_circulator() const
{ return Edge_const_circulator(vertices_circulator()); }
//--------------------------------------------------------
// Predicates
//--------------------------------------------------------
/// @}
/// \name Predicates
/// @{
/// Returns whether this is a simple polygon.
bool is_simple() const
{
return is_simple_2(d_container.begin(),d_container.end(), traits);
}
/// Returns whether this is convex.
bool is_convex() const
{
return is_convex_2(d_container.begin(),d_container.end(), traits);
}
/// Returns the orientation. If the number of vertices
/// \f$ p.size() < 3 \f$ then \c COLLINEAR is returned.
/// \pre `p.is_simple()`.
Orientation orientation() const
{
return orientation_2(d_container.begin(), d_container.end(), traits);
}
/// Returns `POSITIVE_SIDE`, or `NEGATIVE_SIDE`,
/// or `ON_ORIENTED_BOUNDARY`, depending on where point
/// `q` is.
/// \pre `p.is_simple()`.
Oriented_side oriented_side(const Point_2& value) const
{
return oriented_side_2(d_container.begin(), d_container.end(),
value, traits);
}
/// Returns the symbolic constant `ON_BOUNDED_SIDE`,
/// `ON_BOUNDARY` or `ON_UNBOUNDED_SIDE`,
/// depending on where point `q` is. \pre
/// `p.is_simple()`.
Bounded_side bounded_side(const Point_2& value) const
{
CGAL_polygon_precondition(is_simple());
@ -228,16 +331,22 @@ class Polygon_2 {
value, traits);
}
/// Returns the smallest bounding box containing this polygon.
Bbox_2 bbox() const
{
return bbox_2(d_container.begin(), d_container.end());
}
/// Returns the signed area of the polygon. This means that the
/// area is positive for counter clockwise polygons and negative
/// for clockwise polygons.
FT area() const
{
return polygon_area_2(d_container.begin(), d_container.end(), traits);
}
/// Returns the leftmost vertex of the polygon with the smallest
/// `x`-coordinate.
Vertex_const_iterator left_vertex() const
{
Polygon_2 &self = const_cast<Polygon_2&>(*this);
@ -245,11 +354,8 @@ class Polygon_2 {
self.d_container.end(), traits);
}
//Vertex_iterator left_vertex()
//{
//return left_vertex_2(d_container.begin(), d_container.end(), traits);
//}
/// Returns the rightmost vertex of the polygon with the largest
/// `x`-coordinate.
Vertex_const_iterator right_vertex() const
{
Polygon_2 &self = const_cast<Polygon_2&>(*this);
@ -257,11 +363,8 @@ class Polygon_2 {
self.d_container.end(), traits);
}
// Vertex_iterator right_vertex()
// {
// return right_vertex_2(d_container.begin(), d_container.end(), traits);
// }
/// Returns topmost vertex of the polygon with the largest
/// `y`-coordinate.
Vertex_const_iterator top_vertex() const
{
Polygon_2 &self = const_cast<Polygon_2&>(*this);
@ -269,11 +372,8 @@ class Polygon_2 {
self.d_container.end(), traits);
}
// Vertex_iterator top_vertex()
// {
// return top_vertex_2(d_container.begin(), d_container.end(), traits);
// }
/// Returns the bottommost vertex of the polygon with the
/// smallest `y`-coordinate.
Vertex_const_iterator bottom_vertex() const
{
Polygon_2 &self = const_cast<Polygon_2&>(*this);
@ -281,10 +381,12 @@ class Polygon_2 {
self.d_container.end(), traits);
}
// Vertex_iterator bottom_vertex()
// {
// return bottom_vertex_2(d_container.begin(), d_container.end(), traits);
// }
/// @}
/// \name Convenience
/// For convenience we provide the following Boolean functions:
/// @{
bool is_counterclockwise_oriented() const
{ return orientation() == COUNTERCLOCKWISE; }
@ -310,42 +412,47 @@ class Polygon_2 {
bool has_on_unbounded_side(const Point_2& q) const
{ return bounded_side(q) == ON_UNBOUNDED_SIDE; }
//--------------------------------------------------------
// Random access methods
//--------------------------------------------------------
/// @}
const Point_2& vertex(std::size_t i) const
/// \name Random Access Methos
/// @{
/// Returns a (const) reference to the \f$i\f$-th vertex.
const Point_2& vertex(std::size_t i) const
{ return *(d_container.begin() + i); }
// Point_2& vertex(std::size_t i)
// { return *(d_container.begin() + i); }
const Point_2& operator[](std::size_t i) const
/// Returns a (const) reference to the \f$i\f$-th vertex.
const Point_2& operator[](std::size_t i) const
{ return vertex(i); }
// Point_2& operator[](std::size_t i)
// { return vertex(i); }
Segment_2 edge(std::size_t i) const
/// Returns the \f$i\f$-th edge.
Segment_2 edge(std::size_t i) const
{ return *(edges_begin() + i); }
//--------------------------------------------------------
// Miscellaneous
//--------------------------------------------------------
/// @}
std::size_t size() const
/// \name Miscellaneous
/// @{
/// Returns the number of vertices of the polygon.
std::size_t size() const
{ return d_container.size(); }
/// Returns `size() == 0`.
bool is_empty() const
{ return d_container.empty(); }
/// Returns a const reference to the sequence of vertices of the polygon.
const Container_P& container() const
{ return d_container; }
/// @}
bool identical(const Polygon_2<Traits_P,Container_P> &q) const
{ return this == &q; }
Traits_P const &traits_member() const { return traits;}
private:
@ -353,41 +460,62 @@ class Polygon_2 {
Traits_P traits;
};
//-----------------------------------------------------------------------//
// Globally defined operators
//-----------------------------------------------------------------------//
/// @} // polygon_2
/// \name Global Operators
/// @{
/// Test for equality: two polygons are equal iff there exists a
/// cyclic permutation of the vertices of `p2` such that they are
/// equal to the vertices of `p1`. Note that the template argument
/// `Container` of `p1` and `p2` may be different.
/// \memberof Polygon_2
template <class Traits_P, class Container1_P, class Container2_P>
bool operator==( const Polygon_2<Traits_P,Container1_P> &x,
const Polygon_2<Traits_P,Container2_P> &y );
bool operator==( const Polygon_2<Traits_P,Container1_P> &p1,
const Polygon_2<Traits_P,Container2_P> &p2 );
/// Test for inequality.
/// \memberof Polygon_2
template <class Traits_P, class Container1_P, class Container2_P>
inline
bool
operator!=(const Polygon_2<Traits_P,Container1_P> &x,
const Polygon_2<Traits_P,Container2_P> &y);
operator!=(const Polygon_2<Traits_P,Container1_P> &p1,
const Polygon_2<Traits_P,Container2_P> &p2);
/// Returns the image of the polygon \c p under the transformation \c t.
/// \memberof Polygon_2
template <class Transformation, class Traits_P, class Container_P>
Polygon_2<Traits_P,Container_P>
transform(const Transformation& t, const Polygon_2<Traits_P,Container_P>& p);
//-----------------------------------------------------------------------//
// I/O
//-----------------------------------------------------------------------//
/// @} // global operators
/// \name I/O
/// The information output in the `std::iostream` is the number of points
/// followed by the output of the coordinates of the vertices.
/// @{
/// Inserts the polygon `p` into the stream `os`. \pre The insert
/// operator must be defined for `Point_2`.
/// \memberof Polygon_2
template <class Traits_P, class Container_P>
std::istream &operator>>(std::istream &is, Polygon_2<Traits_P,Container_P>& p);
/// Reads a polygon from stream `is` and assigns it
/// to `p`. \pre The extract operator must be defined for `Point_2`.
/// \memberof Polygon_2
template <class Traits_P, class Container_P>
std::ostream
&operator<<(std::ostream &os, const Polygon_2<Traits_P,Container_P>& p);
/// @} // IO
} //namespace CGAL
//-----------------------------------------------------------------------//
// implementation
//-----------------------------------------------------------------------//
} //namespace CGAL
#include <CGAL/Polygon_2/Polygon_2_impl.h>
namespace CGAL {

View File

@ -22,6 +22,10 @@
//
// 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
@ -30,38 +34,130 @@
#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.
///
/// \requires `Traits` is a model of the concept `PolygonTraits_2`.
/// In fact, only the members `Less_xy_2` and
/// `less_xy_2_object()` are used.
/// \requires The value type of `ForwardIterator` must be `Traits::Point_2`,
///
/// \sa `CGAL::right_vertex_2()`
/// \sa `CGAL::top_vertex_2()`
/// \sa `CGAL::bottom_vertex_2()`
/// \sa `CGAL::Polygon_2`
template <class ForwardIterator, class Traits>
ForwardIterator left_vertex_2(ForwardIterator first,
ForwardIterator last,
const Traits& 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.
///
/// \requires `Traits` is a model of the concept
/// `PolygonTraits_2`
/// In fact, only the members `Less_xy_2` and
/// `less_xy_2_object()` are used.
/// \requires The value type of `ForwardIterator` must be `Traits::Point_2`,
///
///
/// \sa `CGAL::left_vertex_2()`
/// \sa `CGAL::top_vertex_2`
/// \sa `CGAL::bottom_vertex_2`
/// \sa `CGAL::Polygon_2`
template <class ForwardIterator, class Traits>
ForwardIterator right_vertex_2(ForwardIterator first,
ForwardIterator last,
const Traits& 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.
///
/// \requires `Traits` is a model of the concept
/// `PolygonTraits_2`
/// In fact, only the members `Less_yx_2` and
/// `less_yx_2_object()` are used.
/// \requires The value type of `ForwardIterator` must be `Traits::Point_2`,
///
/// \sa `CGAL::left_vertex_2()`
/// \sa `CGAL::right_vertex_2()`
/// \sa `CGAL::bottom_vertex_2()`
/// \sa `CGAL::Polygon_2`
template <class ForwardIterator, class Traits>
ForwardIterator top_vertex_2(ForwardIterator first,
ForwardIterator last,
const Traits& 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.
///
/// \requires `Traits` is a model of the concept
/// `PolygonTraits_2`
/// In fact, only the members `Less_yx_2` and
/// `less_yx_2_object()` are used.
/// \requires The value type of `ForwardIterator` must be `Traits::Point_2`,
///
/// \ref CGAL::left_vertex_2
/// \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 Traits>
ForwardIterator bottom_vertex_2(ForwardIterator first,
ForwardIterator last,
const Traits& traits);
/// Returns the bounding box of the range `[first,last)`.
///
/// \requires `Traits` is a model of the concept
/// `PolygonTraits_2`
/// In fact, only the members `Construct_bbox_2` and
/// `construct_bbox_2_object()` are used.
/// \requires The value type of `InputIterator` must be `Traits::Point_2`.
///
/// \sa `CGAL::Polygon_2`
template <class InputIterator, class Traits>
Bbox_2 bbox_2(InputIterator first,
InputIterator last,
const Traits& 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.
///
/// \requires `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()`
/// \requires The value type of `ForwardIterator` must be `Traits::Point_2`,
///
/// \sa `CGAL::polygon_area_2`
/// \sa `PolygonTraits_2`
/// \sa `CGAL::orientation_2`
/// \sa `CGAL::Polygon_2`
template <class ForwardIterator, class Traits>
void
area_2( ForwardIterator first, ForwardIterator last,
@ -84,6 +180,22 @@ area_2( ForwardIterator first, ForwardIterator last,
}
}
/// 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.
///
/// \requires `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`
/// \requires `ForwardIterator::value_type` should be `Traits::Point_2`,
///
///
/// \sa `PolygonTraits_2 `
/// \sa `CGAL::orientation_2 `
/// \sa `CGAL::Polygon_2 `
template <class ForwardIterator, class Traits>
typename Traits::FT
polygon_area_2( ForwardIterator first, ForwardIterator last,
@ -106,36 +218,148 @@ polygon_area_2( ForwardIterator first, ForwardIterator last,
return result;
}
/// The function is_convex_2 computes if a polygon is convex.
///
/// \requires `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`
/// \requires `ForwardIterator::value_type` should be `Traits::Point_2`,
///
/// \sa `PolygonTraits_2 `
/// \sa `CGAL::Polygon_2 `
template <class ForwardIterator, class Traits>
bool is_convex_2(ForwardIterator first,
ForwardIterator last,
const Traits& traits);
/// The function is_simple_2 computes if a polygon is simple, that is, if the edges
/// do not intersect, except consecutive edges in their common vertex.
///
/// Checks if the polygon defined by the
/// iterator range `[first,last)` is simple.
///
/// \requires `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()`
/// \requires The value type of `ForwardIterator` must be `Traits::Point_2`,
///
/// 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 Traits>
bool is_simple_2(ForwardIterator first,
ForwardIterator last,
const Traits& 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.
// 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.
///
/// The function oriented_side_2 computes on which side of a polygon a point lies.
/// \requires `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()`
/// \requires The value type of `ForwardIterator` must be `Traits::Point_2`,
///
/// \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);
/// The function bounded_side_2 computes if a point lies inside a polygon.
/// The function bounded_side_2 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.
///
///
/// \requires `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()`
/// \requires The value type of `ForwardIterator` must be `Traits::Point_2`,
///
/// 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 Traits>
Bounded_side bounded_side_2(ForwardIterator first,
ForwardIterator last,
const Point& point,
const Traits& traits);
/// The function orientation_2 computes if a polygon is clockwise or counterclockwise
/// oriented.
/// \pre `is_simple_2(first, last, traits);`
///
/// \requires `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()`
/// \requires The value type of `ForwardIterator` must be `Traits::Point_2`,
///
///
///
/// \sa `PolygonTraits_2`
/// \sa `CGAL::is_simple_2`
/// \sa `CGAL::Polygon_2`
/// \sa `CGAL::Orientation`
template <class ForwardIterator, class Traits>
Orientation orientation_2(ForwardIterator first,
ForwardIterator last,
const Traits& traits);
/// @}
//-----------------------------------------------------------------------//
// implementation
//-----------------------------------------------------------------------//