Merge pull request #3848 from afabri/Partition_2-Traits_with_state-GF

Partition_2:  Make it work for a traits class with state
This commit is contained in:
Laurent Rineau 2019-05-06 15:45:56 +02:00
commit 90d6afdeb6
48 changed files with 608 additions and 615 deletions

View File

@ -4,15 +4,17 @@ namespace CGAL {
\ingroup PkgPartition2Ref
Traits class that can be used with all the
2-dimensional polygon partitioning algorithms. It is parameterized by
a representation class `R`.
2-dimensional polygon partitioning algorithms.
\tparam R a representation class
\tparam PointPropertyMap a property map that maps to points of type `R::Point_2`
\cgalModels `ConvexPartitionIsValidTraits_2`
\cgalModels `IsYMonotoneTraits_2`
\cgalModels `OptimalConvexPartitionTraits_2`
\cgalModels `PartitionTraits_2`
\cgalModels `YMonotonePartitionIsValidTraits_2`
\cgalModels `YMonotonePartitionTraits_2`
\sa `CGAL::approx_convex_partition_2()`
\sa `CGAL::convex_partition_is_valid_2()`
@ -24,7 +26,7 @@ a representation class `R`.
\sa `CGAL::y_monotone_partition_is_valid_2()`
*/
template< typename R >
template< typename R, typename PointPropertyMap = Identity_property_map<R::Point_2> >
class Partition_traits_2 {
public:
@ -34,102 +36,7 @@ public:
/*!
*/
typedef R::Line_2 Line_2;
/*!
*/
typedef R::Segment_2 Segment_2;
/*!
*/
typedef R::Ray_2 Ray_2;
/*!
*/
typedef R::Less_yx_2 Less_yx_2;
/*!
*/
typedef R::Less_xy_2 Less_xy_2;
/*!
*/
typedef R::Left_turn_2 Left_turn_2;
/*!
*/
typedef R::Orientation_2 Orientation_2;
/*!
*/
typedef R::Compare_y_2 Compare_y_2;
/*!
*/
typedef R::Compare_x_2 Compare_x_2;
/*!
*/
typedef R::Construct_line_2 Construct_line_2;
/*!
*/
typedef R::Construct_ray_2 Construct_ray_2;
/*!
*/
typedef R::Construct_segment_2 Construct_segment_2;
/*!
*/
typedef R::Collinear_are_ordered_along_line_2 Collinear_are_ordered_along_line_2;
/*!
*/
typedef R::Are_strictly_ordered_along_line_2 Are_strictly_ordered_along_line_2;
/*!
*/
typedef CGAL::Polygon_traits_2<R> Poly_Traits;
/*!
*/
typedef Poly_Traits::Point_2 Point_2;
/*!
*/
typedef std::list<Point_2> Container;
/*!
*/
typedef CGAL::Polygon_2<Poly_Traits, Container> Polygon_2;
/*!
*/
typedef R::Less_xy_2 Less_xy;
/*!
*/
typedef Poly_Traits::Vector_2 Vector_2;
typedef Partition_traits_2<R,PMap> Self;
/*!
@ -139,10 +46,65 @@ typedef R::FT FT;
/*!
*/
typedef Partition_traits_2<R> Self;
typedef boost::property_traits<PointPropertyMap>::key_type Point_2;
/*!
*/
typedef std::list<Point_2> Container;
/*!
*/
typedef CGAL::Polygon_2<Self, Container> Polygon_2;
/*!
A functor with an operator which first obtains points of type `R::Point_2`
with the function `get()` applied on the point property map, and
then applies the functor of `R::Less_yx_2` to these points.
*/
typedef unspecified_type Less_yx_2;
/*!
*/
typedef unspecified_type Less_xy_2;
/*!
*/
typedef unspecified_type Left_turn_2;
/*!
*/
typedef unspecified_type Orientation_2;
/*!
*/
typedef unspecified_type Compare_y_2;
/*!
*/
typedef unspecified_type Compare_x_2;
/*!
*/
typedef unspecified_type Collinear_are_ordered_along_line_2;
/*!
*/
typedef unspecified_type Are_strictly_ordered_along_line_2;
/*!
*/
typedef CGAL::Is_convex_2<Self> Is_convex_2;
@ -167,13 +129,22 @@ Partition_traits_2();
*/
Partition_traits_2(Partition_traits_2& tr);
/*!
*/
Partition_traits_2(const R& rep);
/*!
*/
Partition_traits_2(const R& rep, PointPropertyMap pmap);
/// @}
/// \name Operations
/// For each predicate object type `Pred_object_type` listed above
/// (i.e., `Less_yx_2`, `Less_xy_2`, `Left_turn_2`,
/// `Orientation_2`, `Compare_y_2`, `Compare_x_2`, `Construct_line_2`,
/// `Construct_ray_2`, `Construct_segment_2`,
/// `Orientation_2`, `Compare_y_2`, `Compare_x_2`,
/// `Collinear_are_ordered_along_line_2`,
/// `Are_strictly_ordered_along_line_2`, `Is_convex_2`,
/// `Is_y_monotone_2`) there is a corresponding function of the

View File

@ -88,8 +88,7 @@ the resulting sequence of polygons is returned.
\cgalHeading{Requirements}
<OL>
<LI>`Traits` is a model of the concepts `PartitionTraits_2`
and `YMonotonePartitionTraits_2`.
<LI>`Traits` is a model of the concepts `PartitionTraits_2`.
For the purpose of
checking the validity of the \f$ y\f$-monotone partition produced as
a preprocessing step for the convex partitioning, it must also
@ -232,8 +231,7 @@ the resulting sequence of polygons is returned.
\cgalHeading{Requirements}
<OL>
<LI>`Traits` is a model of the concept
`YMonotonePartitionTraits_2`
<LI>`Traits` is a model of the concept `PartitionTraits_2`
and, for the purposes
of checking the postcondition that the partition is valid, it should
also be a model of `YMonotonePartitionIsValidTraits_2`.

View File

@ -35,7 +35,7 @@ with the representation type determined by `std::iterator_traits<InputIterator>:
\sa `CGAL::greene_approx_convex_partition_2()`
\sa `CGAL::optimal_convex_partition_2()`
\sa `CGAL::partition_is_valid_2()`
\sa `CGAL::is_convex_2()`
\sa `CGAL::Is_convex_2`
\cgalHeading{Implementation}
@ -76,7 +76,7 @@ same as the original polygon.
Each polygon must also satisfy the property
tested by `Traits::Is_valid()`.
\pre Points in the range [`point_first`, `point_beyond`) define a simple, counterclockwise-oriented polygon.
\pre The points in the range [`point_first`, `point_beyond`) define a simple, counterclockwise-oriented polygon.
\cgalHeading{Requires}
@ -99,7 +99,7 @@ with the representation type determined by `std::iterator_traits<InputIterator>:
\sa `CGAL::optimal_convex_partition_2()`
\sa `CGAL::Partition_is_valid_traits_2<Traits, PolygonIsValid>`
\sa `CGAL::y_monotone_partition_2()`
\sa `CGAL::is_convex_2()`
\sa `CGAL::Is_convex_2`
\cgalHeading{Implementation}
@ -134,9 +134,8 @@ A valid partition is one in
which the polygons are nonoverlapping and the union of the polygons is the
same as the original polygon and each polygon is \f$ y\f$-monotone
\pre P
The function returns `true` iff the partition is valid and otherwise
returns false.
returns ` false`.

View File

@ -23,34 +23,6 @@ public:
/// `PartitionTraits_2`, the following types are required:
/// @{
/*!
A segment type
*/
typedef unspecified_type Segment_2;
/*!
A ray type
*/
typedef unspecified_type Ray_2;
/*!
A general object type that can be either a point or a segment
*/
typedef unspecified_type Object_2;
/*!
Function object type that provides
`Segment_2 operator()(Point_2 p, Point_2 q)`, which constructs and
returns the segment defined by the points \f$ p\f$ and \f$ q\f$.
*/
typedef unspecified_type Construct_segment_2;
/*!
Function object type that provides
`Ray_2 operator()(Point_2 p, Point_2 q)`, which constructs and returns
the ray from point \f$ p\f$ through point \f$ q\f$.
*/
typedef unspecified_type Construct_ray_2;
/*!
Predicate object type that
@ -73,21 +45,6 @@ and `r`. Note that `false` should be returned if
*/
typedef unspecified_type Are_stritcly_ordered_along_line_2;
/*!
Function object type that provides
`Object_2 operator()(Segment_2 s1, Segment_2 s2)` that returns
the intersection of two segments (which may be either a segment or
a point).
*/
typedef unspecified_type Intersect_2;
/*!
Function object type that provides
`bool operator()(Segment_2 s1, Object_2 o)` that returns
`true` if `o` is a segment and assigns the value of `o`
to `s1`; returns `false` otherwise.
*/
typedef unspecified_type Assign_2;
/// @}
@ -113,15 +70,6 @@ OptimalConvexPartitionTraits_2(OptimalConvexPartitionTraits_2 tr);
*/
Collinear_are_ordered_along_line_2 collinear_are_ordered_along_line_2_object() const;
/*!
*/
Construct_segment_2 construct_segment_2_object() const;
/*!
*/
Construct_ray_2 construct_ray_2_object() const;
/*!

View File

@ -3,14 +3,14 @@
\cgalConcept
Requirements of a traits class that is used
by `partition_is_valid_2`, `convex_partition_is_valid_2`,
and `y_monotone_partition_is_valid_2` for testing if a given set of
by `CGAL::partition_is_valid_2()`, `CGAL::convex_partition_is_valid_2()`,
and `CGAL::y_monotone_partition_is_valid_2()` for testing if a given set of
polygons are nonoverlapping and if their union is a polygon that is the
same as a polygon represented by a given sequence of points. Note that the
traits class for `partition_is_valid_2` may have to satisfy additional
traits class for `CGAL::partition_is_valid_2()` may have to satisfy additional
requirements if each partition polygon is to be tested for having a
particular property; see, for example, the descriptions of the
function `is_convex_2()`
function `CGAL::is_convex_2()`
and the concept `YMonotonePartitionTraits_2` for the additional requirements
for testing for convexity and \f$ y\f$-monotonicity, respectively.

View File

@ -1,89 +0,0 @@
/*!
\ingroup PkgPartition2Concepts
\cgalConcept
Requirements of a traits class to be
used with the function `y_monotone_partition_2()`.
\cgalRefines `PartitionTraits_2`
\cgalHasModel `CGAL::Partition_traits_2<R>`
*/
class YMonotonePartitionTraits_2 {
public:
/// \name Types
/// In addition to the types defined for the concept `PartitionTraits_2`, the following types are also required:
/// @{
/*!
*/
typedef unspecified_type Line_2;
/*!
Predicate object type that provides
`CGAL::Comparision_result operator()(Point_2 p, Line_2 h)` to compare
the \f$ x\f$ coordinate of `p` and the horizontal projection of `p`
on `h`.
*/
typedef unspecified_type Compare_x_at_y_2;
/*!
Function object type that provides
`Line_2 operator()(Point_2 p, Point_2 q)`, which constructs and
returns the line defined by the points \f$ p\f$ and \f$ q\f$.
*/
typedef unspecified_type Construct_line_2;
/*!
Function object type that provides
`bool operator()(Line_2 l)`, which returns `true` iff the
line `l` is horizontal.
*/
typedef unspecified_type Is_horizontal_2;
/// @}
/// \name Creation
/// A copy constructor and default constructor are required.
/// @{
/*!
*/
YMonotonePartitionTraits();
/*!
*/
YMonotonePartitionTraits(const YMonotonePartitionTraits tr);
/// @}
/// \name Operations
/// In addition to the functions required for the concept
/// `PartitionTraits_2`, the following functions that create instances
/// of the above function object types must exist.
/// @{
/*!
*/
Construct_line_2 construct_line_2_object();
/*!
*/
Compare_x_at_y_2 compare_x_at_y_2_object();
/*!
*/
Is_horizontal_2 is_horizontal_2_object();
/// @}
}; /* end YMonotonePartitionTraits_2 */

View File

@ -74,14 +74,13 @@ original polygon).
- `PartitionTraits_2`
- `PartitionIsValidTraits_2`
- `YMonotonePartitionIsValidTraits_2`
- `YMonotonePartitionTraits_2`
\cgalCRPSection{Function Object Concepts}
- `PolygonIsValid`
\cgalCRPSection{Classes}
- `CGAL::Partition_is_valid_traits_2<Traits, PolygonIsValid>`
- `CGAL::Partition_traits_2<R>`
- `CGAL::Partition_traits_2<R,P>`
\cgalCRPSection{Function Object Classes}

View File

@ -95,9 +95,32 @@ as the algorithm of Hertel and Mehlhorn implemented with
`approx_convex_partition_2()` but can sometimes produce better
results (i.e., convex partitions with fewer pieces).
Examples of the uses of all of these functions are provided with the
\section secpartition_2_examples Examples
Examples of the uses of all of the above partition functions are provided with the
corresponding reference pages.
In the following we illustrate how to use a property map to enable the trais class to
deal with polygons where the vertices are not points. In the example the points
are in a vector and the polygons are sequences of indices.
The class `Partition_2` has two template parameters, namely
a geometric traits class, and a property map to obtain points, in the example by accessing `points[i]` for
the polygon vertex `i`, and it then performs the predicates required by
the concept `PartitionTraits_2` on these points.
\cgalExample{Partition_2/y_monotone_partition_indices_2.cpp}
In a similar way, the use of an appropriate property map enables to partition faces of a polygonal mesh,
or to access points which are a component of a `std::tuple`.
\section secpartition_2_history Implementation History
This package has originally been written by Susan Hert while working at the Max-Planck Institute for Infomatics in Germany.
The algorithms have been made free of constructions, and the property map has been added by GeometryFactory
for \cgal 5.0.
*/
} /* namespace CGAL */

View File

@ -3,4 +3,5 @@
\example Partition_2/greene_approx_convex_partition_2.cpp
\example Partition_2/optimal_convex_partition_2.cpp
\example Partition_2/y_monotone_partition_2.cpp
\example Partition_2/y_monotone_partition_indices_2.cpp
*/

View File

@ -1,8 +1,6 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Partition_traits_2.h>
#include <CGAL/partition_2.h>
#include <CGAL/point_generators_2.h>
#include <CGAL/random_polygon_2.h>
#include <cassert>
#include <list>
@ -11,10 +9,7 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Partition_traits_2<K> Traits;
typedef Traits::Point_2 Point_2;
typedef Traits::Polygon_2 Polygon_2;
typedef Polygon_2::Vertex_iterator Vertex_iterator;
typedef std::list<Polygon_2> Polygon_list;
typedef CGAL::Creator_uniform_2<int, Point_2> Creator;
typedef CGAL::Random_points_in_square_2<Point_2, Creator> Point_generator;
void make_polygon(Polygon_2& polygon)
{
@ -40,11 +35,8 @@ int main()
Polygon_2 polygon;
Polygon_list partition_polys;
/*
CGAL::random_polygon_2(50, std::back_inserter(polygon),
Point_generator(100));
*/
make_polygon(polygon);
CGAL::approx_convex_partition_2(polygon.vertices_begin(),
polygon.vertices_end(),
std::back_inserter(partition_polys));

View File

@ -1,8 +1,6 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Partition_traits_2.h>
#include <CGAL/partition_2.h>
#include <CGAL/point_generators_2.h>
#include <CGAL/random_polygon_2.h>
#include <cassert>
#include <list>
@ -10,10 +8,7 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Partition_traits_2<K> Traits;
typedef Traits::Point_2 Point_2;
typedef Traits::Polygon_2 Polygon_2;
typedef Polygon_2::Vertex_iterator Vertex_iterator;
typedef std::list<Polygon_2> Polygon_list;
typedef CGAL::Creator_uniform_2<int, Point_2> Creator;
typedef CGAL::Random_points_in_square_2< Point_2, Creator > Point_generator;
void make_polygon(Polygon_2& polygon)
{
@ -38,21 +33,14 @@ int main()
{
Polygon_2 polygon;
Polygon_list partition_polys;
Traits partition_traits;
/*
CGAL::random_polygon_2(50, std::back_inserter(polygon),
Point_generator(100));
*/
make_polygon(polygon);
CGAL::greene_approx_convex_partition_2(polygon.vertices_begin(),
polygon.vertices_end(),
std::back_inserter(partition_polys),
partition_traits);
std::back_inserter(partition_polys));
assert(CGAL::convex_partition_is_valid_2(polygon.vertices_begin(),
polygon.vertices_end(),
partition_polys.begin(),
partition_polys.end(),
partition_traits));
partition_polys.end()));
return 0;
}

View File

@ -1,25 +1,15 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Partition_traits_2.h>
#include <CGAL/Partition_is_valid_traits_2.h>
#include <CGAL/polygon_function_objects.h>
#include <CGAL/partition_2.h>
#include <CGAL/point_generators_2.h>
#include <CGAL/random_polygon_2.h>
#include <cassert>
#include <list>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Partition_traits_2<K> Traits;
typedef CGAL::Is_convex_2<Traits> Is_convex_2;
typedef Traits::Polygon_2 Polygon_2;
typedef Traits::Point_2 Point_2;
typedef Polygon_2::Vertex_const_iterator Vertex_iterator;
typedef std::list<Polygon_2> Polygon_list;
typedef CGAL::Partition_is_valid_traits_2<Traits, Is_convex_2>
Validity_traits;
typedef CGAL::Creator_uniform_2<int, Point_2> Creator;
typedef CGAL::Random_points_in_square_2<Point_2, Creator> Point_generator;
void make_polygon(Polygon_2& polygon)
{
@ -43,22 +33,16 @@ int main()
{
Polygon_2 polygon;
Polygon_list partition_polys;
Traits partition_traits;
Validity_traits validity_traits;
/*
CGAL::random_polygon_2(50, std::back_inserter(polygon),
Point_generator(100));
*/
make_polygon(polygon);
CGAL::optimal_convex_partition_2(polygon.vertices_begin(),
polygon.vertices_end(),
std::back_inserter(partition_polys),
partition_traits);
std::back_inserter(partition_polys));
assert(CGAL::partition_is_valid_2(polygon.vertices_begin(),
polygon.vertices_end(),
partition_polys.begin(),
partition_polys.end(),
validity_traits));
partition_polys.end()));
return 0;
}

View File

@ -1,8 +1,6 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Partition_traits_2.h>
#include <CGAL/partition_2.h>
#include <CGAL/point_generators_2.h>
#include <CGAL/random_polygon_2.h>
#include <cassert>
#include <list>
@ -12,8 +10,6 @@ typedef CGAL::Partition_traits_2<K> Traits;
typedef Traits::Point_2 Point_2;
typedef Traits::Polygon_2 Polygon_2;
typedef std::list<Polygon_2> Polygon_list;
typedef CGAL::Creator_uniform_2<int, Point_2> Creator;
typedef CGAL::Random_points_in_square_2<Point_2, Creator> Point_generator;
void make_polygon(Polygon_2& polygon)
{
@ -39,10 +35,6 @@ int main( )
Polygon_2 polygon;
Polygon_list partition_polys;
/*
CGAL::random_polygon_2(50, std::back_inserter(polygon),
Point_generator(100));
*/
make_polygon(polygon);
CGAL::y_monotone_partition_2(polygon.vertices_begin(),
polygon.vertices_end(),
@ -60,5 +52,6 @@ int main( )
polygon.vertices_end(),
partition_polys.begin(),
partition_polys.end()));
return 0;
}

View File

@ -0,0 +1,64 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/partition_2.h>
#include <CGAL/Partition_traits_2.h>
#include <CGAL/property_map.h>
#include <vector>
#include <cassert>
#include <list>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Partition_traits_2<K, CGAL::Pointer_property_map<K::Point_2>::type > Partition_traits_2;
typedef Partition_traits_2::Point_2 Point_2;
typedef Partition_traits_2::Polygon_2 Polygon_2; // a polygon of indices
typedef std::list<Polygon_2> Polygon_list;
/*
v4 v2
| \ /|
| \ / |
| v3 |
| |
v0-----v1
*/
int main( )
{
std::vector<K::Point_2> points = { K::Point_2(0,0), K::Point_2(2,0), K::Point_2(2,2), K::Point_2(1,1), K::Point_2(0,2) };
Partition_traits_2 traits(CGAL::make_property_map(points));
Polygon_2 polygon;
polygon.push_back(0);
polygon.push_back(1);
polygon.push_back(2);
polygon.push_back(3);
polygon.push_back(4);
Polygon_list partition_polys;
CGAL::y_monotone_partition_2(polygon.vertices_begin(),
polygon.vertices_end(),
std::back_inserter(partition_polys),
traits);
for (const Polygon_2& poly : partition_polys){
for(Point_2 p : poly.container()){
std::cout << "points[" << p << "] = " << points[p] << ", ";
}
std::cout << std::endl;
}
assert(CGAL::partition_is_valid_2(polygon.vertices_begin(),
polygon.vertices_end(),
partition_polys.begin(),
partition_polys.end(),
traits));
return 0;
}

View File

@ -37,20 +37,15 @@ template <class ForwardCirculator, class Traits>
class Indirect_edge_compare
{
public:
typedef typename Traits::Orientation_2 Orientation_2;
typedef typename Traits::Compare_y_2 Compare_y_2;
typedef typename Traits::Compare_x_2 Compare_x_2;
typedef typename Traits::Construct_line_2 Construct_line_2;
typedef typename Traits::Compare_x_at_y_2 Compare_x_at_y_2;
typedef typename Traits::Is_horizontal_2 Is_horizontal_2;
typedef typename Traits::Line_2 Line_2;
typedef typename Traits::Point_2 Point_2;
Indirect_edge_compare() :
_compare_y_2(Traits().compare_y_2_object()),
_compare_x_2(Traits().compare_x_2_object()),
_construct_line_2(Traits().construct_line_2_object()),
_compare_x_at_y_2(Traits().compare_x_at_y_2_object()),
_is_horizontal_2(Traits().is_horizontal_2_object())
Indirect_edge_compare(const Traits& traits) :
_orientation_2(traits.orientation_2_object()),
_compare_y_2(traits.compare_y_2_object()),
_compare_x_2(traits.compare_x_2_object())
{ }
// determines if the edge (edge_vtx_1, edge_vtx_1++) has a larger
@ -73,8 +68,21 @@ class Indirect_edge_compare
else
{
// construct supporting line for edge
Line_2 line = _construct_line_2(*edge_vtx_1, *edge_vtx_2);
return _compare_x_at_y_2(Point_2(*vertex), line) == SMALLER;
return compare_x_at_y(Point_2(*vertex), Point_2(*edge_vtx_1), Point_2(*edge_vtx_2)) == SMALLER;
}
}
Comparison_result compare_x_at_y(const Point_2& p, const Point_2& a, const Point_2& b) const
{
Orientation ori = _orientation_2(a, b, p);
if(ori == COLLINEAR){
return EQUAL;
}
if(_compare_y_2(a, b) == SMALLER){ // a below b
return (ori == RIGHT_TURN) ? LARGER : SMALLER;
}else { // a above b
return (ori == LEFT_TURN) ? LARGER : SMALLER;
}
}
@ -102,12 +110,9 @@ class Indirect_edge_compare
// else neither endpoint is shared
// construct supporting line
Line_2 l_p = _construct_line_2(*p, *after_p);
if (_is_horizontal_2(l_p))
if(_compare_y_2(Point_2(*p), Point_2(*after_p)) == EQUAL)
{
Line_2 l_q = _construct_line_2(*q, *after_q);
if (_is_horizontal_2(l_q))
if(_compare_y_2(Point_2(*q), Point_2(*after_q)) == EQUAL)
{
Point_2 p_max;
Point_2 q_max;
@ -123,31 +128,29 @@ class Indirect_edge_compare
}
else // p and after_p must both be on same side of l_q
{
return (_compare_x_at_y_2(Point_2(*p), l_q) == LARGER);
return (compare_x_at_y(Point_2(*p), Point_2(*q), Point_2(*after_q)) == LARGER);
}
}
bool q_larger_x =_compare_x_at_y_2(Point_2(*q), l_p) == SMALLER;
bool after_q_larger_x = _compare_x_at_y_2(Point_2(*after_q), l_p) == SMALLER;
// lp is not horizontal
bool q_larger_x = compare_x_at_y(Point_2(*q), Point_2(*p), Point_2(*after_p)) == SMALLER;
bool after_q_larger_x = compare_x_at_y(Point_2(*after_q), Point_2(*p), Point_2(*after_p)) == SMALLER;
if (q_larger_x == after_q_larger_x)
return q_larger_x;
// else one smaller and one larger
// construct the other line
Line_2 l_q = _construct_line_2(*q, *after_q);
if (_is_horizontal_2(l_q)) // p is not horizontal
if(_compare_y_2(Point_2(*q), Point_2(*after_q)) == EQUAL)
{
return _compare_x_at_y_2(Point_2(*q), l_p) == LARGER;
return compare_x_at_y(Point_2(*q), Point_2(*p), Point_2(*after_p)) == LARGER;
}
return _compare_x_at_y_2(Point_2(*p), l_q) != SMALLER;
return compare_x_at_y(Point_2(*p), Point_2(*q), Point_2(*after_q)) != SMALLER;
}
private:
Orientation_2 _orientation_2;
Compare_y_2 _compare_y_2;
Compare_x_2 _compare_x_2;
Construct_line_2 _construct_line_2;
Compare_x_at_y_2 _compare_x_at_y_2;
Is_horizontal_2 _is_horizontal_2;
};
}

View File

@ -33,7 +33,7 @@ class Indirect_less_xy_2
public:
typedef typename Traits::Less_xy_2 Less_xy_2;
Indirect_less_xy_2() : _less_xy_2(Traits().less_xy_2_object())
Indirect_less_xy_2(const Traits& traits) : _less_xy_2(traits.less_xy_2_object())
{ }
template <class Iterator>

View File

@ -19,8 +19,8 @@
//
// Author(s) : Susan Hert <hert@mpi-sb.mpg.de>
#ifndef CGAL_MATRIX_H
#define CGAL_MATRIX_H
#ifndef CGAL_PARTITION_MATRIX_H
#define CGAL_PARTITION_MATRIX_H
#include <CGAL/license/Partition_2.h>
@ -67,4 +67,4 @@ std::ostream& operator<<(std::ostream& os, const Matrix<T>& m)
}
#endif // CGAL_MATRIX_H
#endif // CGAL_PARTITION_MATRIX_H

View File

@ -62,10 +62,6 @@ public:
friend bool operator != ( Vertex_info const& a, Vertex_info const& b ) { return !(a==b); }
friend bool operator < ( Vertex_info const& a, Vertex_info const& b )
{
return Traits().less_xy_2_object()(*a.vertex_it(), *b.vertex_it());
}
private:
@ -73,6 +69,24 @@ private:
Polygon_2 const* m_poly_ptr ;
} ;
template<class Traits_>
class Vertex_info_less
{
public:
Vertex_info_less(const Traits_& traits)
: traits(traits)
{}
bool operator()(Vertex_info<Traits_> const& a, Vertex_info<Traits_> const& b ) const
{
return traits.less_xy_2_object()(*a.vertex_it(), *b.vertex_it());
}
private:
const Traits_& traits;
};
template <class Traits_>
class Edge_info
{
@ -117,9 +131,9 @@ public:
typedef typename Traits::Less_xy_2 Less_xy_2;
typedef typename Traits::Point_2 Point_2;
CW_indirect_edge_info_compare (Vertex_const_iterator v_info) : vertex_it(v_info),
left_turn(Traits().left_turn_2_object()),
less_xy(Traits().less_xy_2_object())
CW_indirect_edge_info_compare (Vertex_const_iterator v_info, const Traits& traits) : vertex_it(v_info),
left_turn(traits.left_turn_2_object()),
less_xy(traits.less_xy_2_object())
{}
bool operator()(Edge_info e1, Edge_info e2)
@ -185,6 +199,12 @@ public:
Edge_info const& back() const { return m_list.back() ; }
Edge_info & back() { return m_list.back() ; }
Edge_list(const Traits& traits)
: traits(traits)
{}
template<class Compare> void sort ( Compare c ) { m_list.sort(c); }
void insert_next(Vertex_info endpoint_ref, int num)
@ -242,7 +262,7 @@ public:
// polygon.
if (m_list.size() > 2)
{
m_list.sort(CW_indirect_edge_info_compare<Traits>(vertex_it));
m_list.sort(CW_indirect_edge_info_compare<Traits>(vertex_it,traits));
}
#ifdef CGAL_PARTITION_CHECK_DEBUG
@ -301,7 +321,7 @@ public:
}
private :
const Traits& traits;
List m_list ;
};
@ -335,7 +355,8 @@ public:
typedef Partition_vertex_map<Traits> Self;
typedef std::map<Vertex_info, Edge_list> Map ;
typedef Vertex_info_less<Traits> Less;
typedef std::map<Vertex_info, Edge_list,Less> Map ;
typedef typename Map::const_iterator Self_const_iterator;
typedef typename Map::iterator Self_iterator;
@ -348,7 +369,9 @@ public:
Partition_vertex_map() {}
template <class InputIterator>
Partition_vertex_map(InputIterator first_poly, InputIterator last_poly)
Partition_vertex_map(InputIterator first_poly, InputIterator last_poly, const Traits& traits)
: traits(traits)
, m_map(traits)
{ _build(first_poly, last_poly); }
Self_const_iterator begin() const { return m_map.begin() ; }
@ -419,7 +442,7 @@ public:
if ((*m_it).second.size() > 2)
{
(*m_it).second.sort(
CW_indirect_edge_info_compare<Traits>((*m_it).first.vertex_it()));
CW_indirect_edge_info_compare<Traits>((*m_it).first.vertex_it(),traits));
}
// find the previous vertex in this vertex's list
@ -474,7 +497,7 @@ private :
vtx_begin = (*poly_first).vertices_begin();
vtx_end = (*poly_first).vertices_end();
begin_v_loc_pair = m_map.insert(P_Vertex( Vertex_info(vtx_begin,poly_ptr), Edge_list()));
begin_v_loc_pair = m_map.insert(P_Vertex( Vertex_info(vtx_begin,poly_ptr), Edge_list(traits)));
prev_v_loc_pair = begin_v_loc_pair;
v_it = vtx_begin;
@ -482,7 +505,7 @@ private :
for (v_it++; v_it != vtx_end; v_it++)
{
v_loc_pair = m_map.insert(P_Vertex( Vertex_info(v_it,poly_ptr), Edge_list()));
v_loc_pair = m_map.insert(P_Vertex( Vertex_info(v_it,poly_ptr), Edge_list(traits)));
insert_next_edge(prev_v_loc_pair.first, v_loc_pair.first, poly_num);
@ -509,7 +532,7 @@ private :
}
private :
const Traits& traits;
Map m_map ;
};

View File

@ -43,8 +43,9 @@ public:
Indirect_CW_diag_compare(){}
Indirect_CW_diag_compare(Point_2 vertex, Iterator prev_ref,
Iterator next_ref) :
_orientation(Traits().orientation_2_object()),
Iterator next_ref,
const Traits& traits) :
_orientation(traits.orientation_2_object()),
_vertex(vertex),
_prev_v_ref(prev_ref)
{
@ -99,8 +100,8 @@ class Partition_vertex;
//
template <class Traits_>
class Partitioned_polygon_2 :
public std::vector< Partition_vertex< Traits_ > >
class Partitioned_polygon_2
: public std::vector< Partition_vertex< Traits_ > >
{
public:
typedef Traits_ Traits;
@ -114,12 +115,13 @@ public:
typedef typename Diagonal_list::iterator Diagonal_iterator;
Partitioned_polygon_2() : _left_turn(Traits().left_turn_2_object())
{ }
Partitioned_polygon_2(const Traits& traits)
: _left_turn(traits.left_turn_2_object()), traits(traits)
{}
template <class InputIterator>
Partitioned_polygon_2(InputIterator first, InputIterator beyond) :
_left_turn(Traits().left_turn_2_object())
Partitioned_polygon_2(InputIterator first, InputIterator beyond, const Traits& traits) :
_left_turn(traits.left_turn_2_object()), traits(traits)
{
for (; first != beyond; first++) {
this->push_back(Vertex(*first));
@ -180,7 +182,7 @@ public:
{
next = c;
next++;
(*c).sort_diagonals(prev, next);
(*c).sort_diagonals(prev, next, traits);
#ifdef CGAL_PARTITIONED_POLY_DEBUG
(*c).print_diagonals();
#endif
@ -288,11 +290,13 @@ private:
}
Left_turn_2 _left_turn;
const Traits& traits;
};
template <class Traits_>
class Partition_vertex : public Traits_::Point_2
{
class Partition_vertex {
private:
typename Traits_::Point_2 point;
public:
typedef Traits_ Traits;
typedef typename Traits::Point_2 Base_point;
@ -310,25 +314,31 @@ class Partition_vertex : public Traits_::Point_2
typedef typename Diagonal_list::iterator Diagonal_iterator;
//default constructor added for EPECK
Partition_vertex(): Base_point()
Partition_vertex()
{
current_diag = diag_endpoint_refs.end() ;
}
Partition_vertex(Base_point p)
: Base_point(p)
: point(p)
{
current_diag = diag_endpoint_refs.end() ;
}
Partition_vertex(const Partition_vertex& other)
: Base_point(other)
: point(other.point)
{
// No need to deep copy.
// We initialize in order to avoid problem with g++ safe STL
current_diag = diag_endpoint_refs.end() ;
}
operator Base_point() const
{
return point;
}
Partition_vertex& operator=(const Partition_vertex&)=default;
void insert_diagonal(Circulator v_ref)
@ -367,9 +377,9 @@ class Partition_vertex : public Traits_::Point_2
// sort the diagonals ccw around the point they have in common
// and remove any duplicate diagonals
void sort_diagonals(const Circulator& prev, const Circulator& next)
void sort_diagonals(const Circulator& prev, const Circulator& next, const Traits& traits)
{
diag_endpoint_refs.sort(Indirect_CW_diag_compare<Circulator,Traits>(*this, prev, next));
diag_endpoint_refs.sort(Indirect_CW_diag_compare<Circulator,Traits>(*this, prev, next, traits));
diag_endpoint_refs.unique();
current_diag = diag_endpoint_refs.begin();

View File

@ -42,7 +42,7 @@ class Point_pair_less_xy_2
typedef typename Traits::Less_xy_2 Less_xy_2;
public:
Point_pair_less_xy_2() : _less_xy_2(Traits().less_xy_2_object())
Point_pair_less_xy_2(const Traits& traits) : _less_xy_2(traits.less_xy_2_object())
{ }

View File

@ -57,6 +57,7 @@ public:
typedef typename Traits::Point_2 Point_2;
using internal::vector< Rotation_tree_node_2<Traits_> >::push_back;
using internal::vector< Rotation_tree_node_2<Traits_> >::back;
class Greater {
typename Traits::Less_xy_2 less;
@ -70,24 +71,33 @@ public:
}
};
struct Equal {
bool operator()(const Point_2& p, const Point_2& q) const
{
return p == q;
}
};
// constructor
template<class ForwardIterator>
Rotation_tree_2(ForwardIterator first, ForwardIterator beyond)
Rotation_tree_2(ForwardIterator first, ForwardIterator beyond, const Traits& traits)
{
for (ForwardIterator it = first; it != beyond; it++)
push_back(*it);
Greater greater (Traits().less_xy_2_object());
Greater greater (traits.less_xy_2_object());
Equal equal;
std::sort(this->begin(), this->end(), greater);
std::unique(this->begin(), this->end());
std::unique(this->begin(), this->end(),equal);
// front() is the point with the largest x coordinate
// Add two auxiliary points that have a special role and whose coordinates are not used
// push the point p_minus_infinity; the coordinates should never be used
push_back(Point_2( 1, -1));
push_back(back());
// push the point p_infinity; the coordinates should never be used
push_back(Point_2(1, 1));
push_back(back());
_p_inf = this->end(); // record the iterators to these extreme points
_p_inf--;

View File

@ -45,8 +45,9 @@ namespace CGAL {
template <class Traits> class Rotation_tree_2;
template <class Traits>
class Rotation_tree_node_2 : public Traits::Point_2
class Rotation_tree_node_2
{
typename Traits::Point_2 point;
public:
typedef typename Traits::Point_2 Base_point;
@ -56,7 +57,7 @@ public:
typedef std::pair<Tree_iterator, bool> Node_ref;
Rotation_tree_node_2(Base_point p) : Base_point(p)
Rotation_tree_node_2(Base_point p) : point(p)
{
_parent.second = false;
_left_sibling.second = false;
@ -64,6 +65,9 @@ public:
_rightmost_child.second = false;
}
operator Base_point() const
{ return point;}
bool has_left_sibling() const
{ return _left_sibling.second; }

View File

@ -50,11 +50,11 @@ class Segment_less_yx_2
typedef Turn_reverser<Point_2, Left_turn_2> Right_turn_2;
public:
Segment_less_yx_2() :
_less_xy_2(Traits().less_xy_2_object()),
_compare_x_2(Traits().compare_x_2_object()),
_compare_y_2(Traits().compare_y_2_object()),
_left_turn_2(Traits().left_turn_2_object()),
Segment_less_yx_2(const Traits& traits) :
_less_xy_2(traits.less_xy_2_object()),
_compare_x_2(traits.compare_x_2_object()),
_compare_y_2(traits.compare_y_2_object()),
_left_turn_2(traits.left_turn_2_object()),
_right_turn_2(Right_turn_2(_left_turn_2))
{ }

View File

@ -61,14 +61,11 @@
#include <CGAL/license/Partition_2.h>
#include <CGAL/Segment_2.h>
#include <CGAL/Partition_2/Rotation_tree_2.h>
#include <CGAL/Partition_2/Indirect_less_xy_2.h>
#include <CGAL/Partition_2/Iterator_list.h>
#include <CGAL/Partition_2/Turn_reverser.h>
#include <CGAL/Partition_2/Point_pair_less_xy_2.h>
#include <CGAL/Intersections_2/Ray_2_Segment_2.h>
#include <CGAL/Partition_2/Segment_less_yx_2.h>
#include <cmath>
#include <list>
@ -86,9 +83,6 @@ class Vertex_visibility_graph_2
private:
typedef Vertex_visibility_graph_2<Traits> Self;
typedef typename Traits::Point_2 Point_2;
typedef typename Traits::Segment_2 Segment_2;
typedef typename Traits::Ray_2 Ray_2;
typedef typename Traits::Object_2 Object_2;
typedef typename Traits::Left_turn_2 Left_turn_2;
typedef typename Traits::Less_xy_2 Less_xy_2;
typedef typename Traits::Orientation_2 Orientation_2;
@ -96,11 +90,6 @@ private:
Collinear_are_ordered_along_line_2;
typedef typename Traits::Are_strictly_ordered_along_line_2
Are_strictly_ordered_along_line_2;
typedef typename Traits::Construct_segment_2
Construct_segment_2;
typedef typename Traits::Construct_ray_2 Construct_ray_2;
typedef typename Traits::Intersect_2 Intersect_2;
typedef typename Traits::Assign_2 Assign_2;
typedef CGAL::Segment_less_yx_2<Traits> Segment_less_yx_2;
typedef Rotation_tree_2<Traits> Tree;
@ -133,30 +122,27 @@ public:
// first and beyond should be iterators over vertices of a polygon
//
template <class ForwardIterator>
Vertex_visibility_graph_2(ForwardIterator first, ForwardIterator beyond):
left_turn_2(Traits().left_turn_2_object()),
orientation_2(Traits().orientation_2_object()),
collinear_ordered_2(Traits().collinear_are_ordered_along_line_2_object()),
Vertex_visibility_graph_2(ForwardIterator first, ForwardIterator beyond, const Traits& traits):
left_turn_2(traits.left_turn_2_object()),
orientation_2(traits.orientation_2_object()),
collinear_ordered_2(traits.collinear_are_ordered_along_line_2_object()),
are_strictly_ordered_along_line_2(
Traits().are_strictly_ordered_along_line_2_object()),
less_xy_2(Traits().less_xy_2_object()),
construct_segment_2(Traits().construct_segment_2_object()),
construct_ray_2(Traits().construct_ray_2_object()),
intersect_2(Traits().intersect_2_object()),
assign_2(Traits().assign_2_object())
traits.are_strictly_ordered_along_line_2_object()),
less_xy_2(traits.less_xy_2_object()),
edges(Point_pair_compare(traits))
{
build(first, beyond);
build(first, beyond, traits);
}
// Pre: ccw order of points; no repeated points
template <class ForwardIterator>
void build(ForwardIterator first, ForwardIterator beyond)
void build(ForwardIterator first, ForwardIterator beyond, const Traits& traits)
{
Polygon polygon(first,beyond);
Tree tree(polygon.begin(), polygon.end());
Tree tree(polygon.begin(), polygon.end(),traits);
Vertex_map vertex_map;
initialize_vertex_map(polygon, vertex_map);
Vertex_map vertex_map(less_xy_2);
initialize_vertex_map(polygon, vertex_map, traits);
// NOTE: use the std::list as the basis here because otherwise the basis
// is a deque, which is buggy under MSVC++
@ -353,7 +339,8 @@ private:
// immediately below it. For vertical edges, the segment below is not the
// one that begins at the other endpoint of the edge.
void initialize_vertex_map(const Polygon& polygon,
Vertex_map& vertex_map);
Vertex_map& vertex_map,
const Traits& traits);
// determines if one makes a left turn going from p to q to q's parent.
// if q's parent is p_infinity, then a left turn is made when p's x value
@ -419,10 +406,6 @@ private:
Collinear_are_ordered_along_line_2 collinear_ordered_2;
Are_strictly_ordered_along_line_2 are_strictly_ordered_along_line_2;
Less_xy_2 less_xy_2;
Construct_segment_2 construct_segment_2;
Construct_ray_2 construct_ray_2;
Intersect_2 intersect_2;
Assign_2 assign_2;
Edge_set edges;
};

View File

@ -56,8 +56,9 @@ Vertex_visibility_graph_2<Traits>::is_valid(ForwardIterator first,
// one that begins at the other endpoint of the edge.
template <class Traits>
void
Vertex_visibility_graph_2<Traits>::initialize_vertex_map(
const Polygon& polygon, Vertex_map& vertex_map)
Vertex_visibility_graph_2<Traits>::initialize_vertex_map(const Polygon& polygon,
Vertex_map& vertex_map,
const Traits& traits)
{
typedef typename Vertex_map::value_type Map_pair;
@ -67,12 +68,12 @@ Vertex_visibility_graph_2<Traits>::initialize_vertex_map(
// Sort the event list (iterators to points) from left to right
// (using less_xy)
iterator_list.sort(Indirect_less_xy_2<Traits>());
iterator_list.sort(Indirect_less_xy_2<Traits>(traits));
// Create an ordered list of edge endpoints (iterators), initially empty
typedef std::set< Point_pair, Segment_less_yx_2 > Ordered_edge_set;
typedef typename Ordered_edge_set::iterator Ordered_edge_set_iterator;
Ordered_edge_set ordered_edges;
Segment_less_yx_2 less_xy(traits);
Ordered_edge_set ordered_edges(less_xy);
Ordered_edge_set_iterator edge_it;
Vertex_map_iterator vm_it;
Vertex_map_iterator vis_it;
@ -521,58 +522,49 @@ void Vertex_visibility_graph_2<Traits>::update_visibility(
// don't need to do this for the previous visibility point since
// if it were closer to p than q when looking from p to q, q would
// not be visible.
Segment_2 next_seg = construct_segment_2(*(*p_it).second.second,
*next_v_p);
Ray_2 ray = construct_ray_2((*p_it).first, (*q_it).first);
Segment_2 i_seg;
Point_2 i_point;
Object_2 next_result = intersect_2(next_seg, ray);
if (assign_2(i_point, next_result))
{
if (collinear_ordered_2((*p_it).first, (*q_it).first, i_point))
{
// Segment ab and Ray pq
Point_2 a = *(*p_it).second.second;
Point_2 b = *next_v_p;
Point_2 p = (*p_it).first;
Point_2 q = (*q_it).first;
Orientation pqa = orientation_2(p,q,a);
Orientation pqb = orientation_2(p,q,b);
Orientation abp = orientation_2(a,b,p);
Orientation abq = orientation_2(a,b,q);
bool change = false;
if((pqa == COLLINEAR)&& (pqb == COLLINEAR)){
// the segment lies on the supporting line of the ray
if(collinear_ordered_2(p,q,a) && collinear_ordered_2(p,q,b)){
change = true;
}
} else if (pqa == COLLINEAR){
if (collinear_ordered_2(p,q,a)){ // forget about b as it is not collinear
change = true;
}
} else if (pqb == COLLINEAR){
if (collinear_ordered_2(p,q,b)){ // forget about a
change = true;
}
}else if(pqa == pqb){
// no intersection as the segment is completely to the left or to the right of the ray
change = true;
}else if((abp == COLLINEAR) || (abq == COLLINEAR) ){
// do nothing because when a ray point lies on the segment collinear_ordered_2 will be false
} else if (abp != abq){
// do nothing as i between p and q
} else if(pqb == RIGHT_TURN){
if(abp == RIGHT_TURN){
change = true;
}
} else {
CGAL_assertion(pqa == RIGHT_TURN);
if(abp == LEFT_TURN){
change = true;
}
}
if(change){
(*p_it).second.second = (*q_it).second.first;
#ifdef CGAL_VISIBILITY_GRAPH_DEBUG
std::cout << "p sees something in direction of q, but q is closer;"
<< " p sees q" << std::endl;
#endif
}
#ifdef CGAL_VISIBILITY_GRAPH_DEBUG
else
{
std::cout << "p sees something in direction of q that's closer "
<< "than q; p doesn't see q" << std::endl;
}
#endif
}
else if (assign_2(i_seg, next_result))
{
if (collinear_ordered_2((*p_it).first,(*q_it).first,i_seg.source()) &&
collinear_ordered_2((*p_it).first,(*q_it).first,i_seg.target()))
{
(*p_it).second.second = (*q_it).second.first;
#ifdef CGAL_VISIBILITY_GRAPH_DEBUG
std::cout << "p sees something in direction of q, but q is closer;"
<< " p sees q" << std::endl;
#endif
}
#ifdef CGAL_VISIBILITY_GRAPH_DEBUG
else
{
std::cout << "p sees something in direction of q that's closer "
<< " than q; p doesn't see q" << std::endl;
}
#endif
}
else
{
(*p_it).second.second = (*q_it).second.first;
#ifdef CGAL_VISIBILITY_GRAPH_DEBUG
std::cout << "p doesn't see something in direction of q; p sees q"
<< std::endl;
#endif
}
}
else // p sees what q sees

View File

@ -145,7 +145,7 @@ OutputIterator partition_approx_convex_2(InputIterator first,
typedef typename Constrained_tri_2::Vertex_handle Vertex_handle;
typedef typename Gt::Segment_2 Segment_2;
P_Polygon_2 polygon(first, beyond);
P_Polygon_2 polygon(first, beyond,traits);
CGAL_partition_precondition(
orientation_2(polygon.begin(), polygon.end(), traits) == COUNTERCLOCKWISE);
@ -163,8 +163,6 @@ OutputIterator partition_approx_convex_2(InputIterator first,
triangles.insert(c, next);
} while (++c != first_c);
Segment_2 edge;
#ifdef CGAL_PARTITION_APPROX_CONVEX_DEBUG
std::cout << "Inserting diagonals: " << std::endl;
#endif
@ -189,8 +187,8 @@ OutputIterator partition_approx_convex_2(InputIterator first,
{
if ((*e_circ).first->is_constrained((*e_circ).second))
{
edge = triangles.segment((*e_circ).first, (*e_circ).second);
#ifdef CGAL_PARTITION_APPROX_CONVEX_DEBUG
Segment_2 edge = triangles.segment((*e_circ).first, (*e_circ).second);
std::cout << "edge " << *edge.source() << " " << *edge.target()
<< " is constrained " << std::endl;
#endif
@ -199,11 +197,11 @@ OutputIterator partition_approx_convex_2(InputIterator first,
{
if (!triangles.is_infinite(*e_circ))
{
edge = triangles.segment((*e_circ).first, (*e_circ).second);
Segment_2 edge = triangles.segment((*e_circ).first, (*e_circ).second);
Circulator source = edge.source();
Circulator target = edge.target();
Circulator before_s = source; before_s--;
Circulator after_s = source; after_s++;
Circulator before_s = edge.source(); before_s--;
Circulator after_s = edge.source(); after_s++;
#ifdef CGAL_PARTITION_APPROX_CONVEX_DEBUG
std::cout << "considering " << *source << " " << *target
<< "...";

View File

@ -457,7 +457,7 @@ void partition_opt_cvx_preprocessing(Polygon& polygon,
typedef typename Traits::Point_2 Point_2;
typedef std::pair<Point_2, Point_2> Point_pair;
Vis_graph graph(polygon.begin(), polygon.end());
Vis_graph graph(polygon.begin(), polygon.end(), traits);
size_type prev_i, i, next_i, next_next_i;
size_type prev_j, j, next_j;
@ -528,7 +528,7 @@ OutputIterator partition_optimal_convex_2(InputIterator first,
Tee_for_output_iterator<OutputIterator, Polygon_2> res(result);
#endif // no postconditions
P_Polygon_2 polygon(first, beyond);
P_Polygon_2 polygon(first, beyond,traits);
CGAL_partition_precondition(
orientation_2(polygon.begin(), polygon.end(), traits) == COUNTERCLOCKWISE);

View File

@ -45,8 +45,6 @@
#include <CGAL/Partition_2/Indirect_not_less_yx_2.h>
#include <CGAL/Partition_2/Indirect_edge_compare.h>
#include <CGAL/Intersections_2/Ray_2_Segment_2.h>
#include <CGAL/Object.h>
#include <CGAL/Partition_2/Partitioned_polygon_2.h>
#include <CGAL/ch_selected_extreme_points_2.h>
#include <CGAL/IO/Tee_for_output_iterator.h>
@ -436,7 +434,7 @@ OutputIterator partition_y_monotone_2(InputIterator first,
Tee_for_output_iterator<OutputIterator, Polygon_2> res(result);
#endif // no postcondition
P_Polygon_2 polygon(first, beyond);
P_Polygon_2 polygon(first, beyond, traits);
CGAL_partition_precondition(
orientation_2(polygon.begin(), polygon.end(), traits) == COUNTERCLOCKWISE);
@ -457,9 +455,10 @@ OutputIterator partition_y_monotone_2(InputIterator first,
std::cout << std::endl;
#endif
typedef std::map<Circulator, Circulator,
Indirect_edge_compare<Circulator, Traits> > Tree;
Tree tree;
typedef Indirect_edge_compare<Circulator, Traits> Cmp;
typedef std::map<Circulator, Circulator, Cmp> Tree;
Cmp cmp(traits);
Tree tree(cmp);
typename std::vector<Circulator>::iterator it = circulators.begin();
for (; it != circulators.end(); it++) {

View File

@ -39,6 +39,13 @@ public:
typedef PolygonIsValid Is_valid;
Partition_is_valid_traits_2()
{}
Partition_is_valid_traits_2(const Traits& traits)
: Traits(traits)
{}
public:
Is_valid
is_valid_object(const Traits& traits) const
{ return Is_valid(traits); }

View File

@ -25,83 +25,128 @@
#include <CGAL/license/Partition_2.h>
#include <CGAL/Polygon_2.h>
#include <CGAL/Partition_2/Partition_traits_2_base.h>
#include <boost/call_traits.hpp>
#include <CGAL/property_map.h>
#include <CGAL/polygon_function_objects.h>
#include <CGAL/Polygon_2.h>
#include <list>
namespace CGAL {
template <class Kernel_>
class Partition_traits_2 : public Partition_traits_2_base<Kernel_>
template <class Base_traits, class PointPropertyMap = Identity_property_map<typename Base_traits::Point_2> >
class Partition_traits_2;
template <typename BT, typename PM>
struct Polygon_traits_getter{
typedef Partition_traits_2<BT,PM> type;
};
template <typename BT>
struct Polygon_traits_getter<BT,Identity_property_map<typename BT::Point_2> > {
typedef BT type;
};
template <class Base_traits, class PointPropertyMap>
class Partition_traits_2 : public Base_traits
{
private:
typedef Kernel_ Kernel;
typedef Partition_traits_2<Kernel_> Self;
public:
typedef typename Kernel::Point_2 Point_2;
private:
typedef Base_traits Kernel;
typedef Partition_traits_2<Base_traits,PointPropertyMap> Self;
PointPropertyMap ppmap;
public:
Partition_traits_2(const Base_traits& base=Base_traits())
: Base_traits(base)
{}
Partition_traits_2(const PointPropertyMap& ppmap,
const Base_traits& base=Base_traits())
: Base_traits(base),ppmap(ppmap)
{}
typedef typename Kernel::FT FT;
typedef typename boost::property_traits<PointPropertyMap>::key_type Point_2;
typedef typename boost::call_traits<Point_2>::param_type Arg_type;
typedef ::std::list<Point_2> Container;
typedef CGAL::Polygon_2<Kernel, Container> Polygon_2;
typedef typename Kernel::Less_yx_2 Less_yx_2;
typedef typename Kernel::Less_xy_2 Less_xy_2;
typedef typename Kernel::Left_turn_2 Left_turn_2;
typedef typename Kernel::Orientation_2 Orientation_2;
typedef typename Kernel::Compare_y_2 Compare_y_2;
typedef typename Kernel::Compare_x_2 Compare_x_2;
typedef typename Polygon_traits_getter<Base_traits,PointPropertyMap>::type PolygonTraits;
typedef CGAL::Polygon_2<PolygonTraits, Container> Polygon_2;
template <typename BaseFct>
struct Pmap_fct : public BaseFct {
Pmap_fct(const PointPropertyMap& ppmap, const BaseFct& base)
: BaseFct(base),ppmap(ppmap)
{}
const PointPropertyMap& ppmap;
typename BaseFct::result_type operator()(const Arg_type& p, const Arg_type& q) const {
return static_cast<const BaseFct*>(this)->operator()(get(ppmap,p),get(ppmap,q));
}
typename BaseFct::result_type operator()(const Arg_type& p, const Arg_type& q, const Arg_type& r) const {
return static_cast<const BaseFct*>(this)->operator()(get(ppmap,p),get(ppmap,q),get(ppmap,r));
}
};
typedef Pmap_fct<typename Kernel::Equal_2> Equal_2;
typedef Pmap_fct<typename Kernel::Less_yx_2> Less_yx_2;
typedef Pmap_fct<typename Kernel::Less_xy_2> Less_xy_2;
typedef Pmap_fct<typename Kernel::Left_turn_2> Left_turn_2;
typedef Pmap_fct<typename Kernel::Orientation_2> Orientation_2;
typedef Pmap_fct<typename Kernel::Compare_y_2> Compare_y_2;
typedef Pmap_fct<typename Kernel::Compare_x_2> Compare_x_2;
typedef CGAL::Is_convex_2<Self> Is_convex_2;
typedef CGAL::Is_y_monotone_2<Self> Is_y_monotone_2;
// needed by Indirect_edge_compare, used in y_monotone and greene_approx
typedef typename Kernel::Line_2 Line_2;
typedef typename Kernel::Construct_line_2 Construct_line_2;
typedef typename Kernel::Compare_x_at_y_2 Compare_x_at_y_2;
typedef typename Kernel::Is_horizontal_2 Is_horizontal_2;
// needed by visibility graph and thus by optimal convex
typedef typename Kernel::Ray_2 Ray_2;
typedef typename Kernel::Collinear_are_ordered_along_line_2
Collinear_are_ordered_along_line_2;
typedef typename Kernel::Are_strictly_ordered_along_line_2
typedef Pmap_fct<typename Kernel::Collinear_are_ordered_along_line_2> Collinear_are_ordered_along_line_2;
typedef Pmap_fct<typename Kernel::Are_strictly_ordered_along_line_2>
Are_strictly_ordered_along_line_2;
typedef typename Kernel::Intersect_2 Intersect_2;
typedef typename Kernel::Assign_2 Assign_2;
typedef typename Kernel::Object_2 Object_2;
// needed by approx_convex (for constrained triangulation)
// and optimal convex (for vis. graph)
typedef typename Kernel::Segment_2 Segment_2;
// needed by optimal convex (for vis. graph)
typedef typename Kernel::Construct_segment_2 Construct_segment_2;
typedef typename Kernel::Construct_ray_2 Construct_ray_2;
Construct_line_2
construct_line_2_object() const
{ return Construct_line_2(); }
Equal_2
equal_2_object() const
{ return Equal_2(ppmap,static_cast<const Base_traits*>(this)->equal_2_object()); }
Compare_x_at_y_2
compare_x_at_y_2_object() const
{ return Compare_x_at_y_2(); }
Orientation_2
orientation_2_object() const
{ return Orientation_2(ppmap,static_cast<const Base_traits*>(this)->orientation_2_object()); }
Construct_segment_2
construct_segment_2_object() const
{ return Construct_segment_2(); }
Less_yx_2
less_yx_2_object() const
{ return Less_yx_2(ppmap,static_cast<const Base_traits*>(this)->less_yx_2_object()); }
Less_xy_2
less_xy_2_object() const
{ return Less_xy_2(ppmap,static_cast<const Base_traits*>(this)->less_xy_2_object()); }
Left_turn_2
left_turn_2_object() const
{ return Left_turn_2(ppmap,static_cast<const Base_traits*>(this)->left_turn_2_object()); }
Compare_y_2
compare_y_2_object() const
{ return Compare_y_2(ppmap,static_cast<const Base_traits*>(this)->compare_y_2_object()); }
Compare_x_2
compare_x_2_object() const
{ return Compare_x_2(ppmap,static_cast<const Base_traits*>(this)->compare_x_2_object()); }
Construct_ray_2
construct_ray_2_object() const
{ return Construct_ray_2(); }
Collinear_are_ordered_along_line_2
collinear_are_ordered_along_line_2_object() const
{ return Collinear_are_ordered_along_line_2(); }
{ return Collinear_are_ordered_along_line_2(ppmap,static_cast<const Base_traits*>(this)->collinear_are_ordered_along_line_2_object()); }
Are_strictly_ordered_along_line_2
are_strictly_ordered_along_line_2_object() const
{ return Are_strictly_ordered_along_line_2(); }
{ return Are_strictly_ordered_along_line_2(ppmap,static_cast<const Base_traits*>(this)->are_strictly_ordered_along_line_2_object()); }
Is_horizontal_2
is_horizontal_2_object() const
{ return Is_horizontal_2(); }
Is_convex_2
is_convex_2_object(const Self& traits) const
@ -111,15 +156,11 @@ class Partition_traits_2 : public Partition_traits_2_base<Kernel_>
is_y_monotone_2_object(const Self& traits) const
{ return Is_y_monotone_2(traits); }
Intersect_2
intersect_2_object() const
{ return Intersect_2(); }
Assign_2
assign_2_object() const
{ return Assign_2(); }
};
}
#endif // CGAL_PARTITION_TRAITS_2_H

View File

@ -0,0 +1,27 @@
// Copyright (c) 2019 Max-Planck-Institute Saarbruecken (Germany).
// 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
// 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: GPL-3.0+
//
//
// Author(s) : Andreas Fabri
#ifndef CGAL_PARTITION_TRAITS_2_H
#define CGAL_PARTITION_TRAITS_2_H
#include <CGAL/license/Partition_2.h>
#endif // CGAL_PARTITION_TRAITS_2_H

View File

@ -132,6 +132,8 @@ polygons_are_equal(Circulator1 orig_first, Circulator2 new_first)
}
namespace internal {
template<class InputIterator, class ForwardIterator, class Traits>
bool
partition_is_valid_2 (InputIterator point_first, InputIterator point_last,
@ -157,7 +159,7 @@ partition_is_valid_2 (InputIterator point_first, InputIterator point_last,
CGAL_partition_precondition(orientation_2(orig_poly.begin(),orig_poly.end(),
traits) == COUNTERCLOCKWISE);
P_Vertex_map output_vertex_set(poly_first, poly_last);
P_Vertex_map output_vertex_set(poly_first, poly_last, traits);
if (output_vertex_set.polygons_overlap()) return false;
@ -206,6 +208,7 @@ partition_is_valid_2 (InputIterator point_first, InputIterator point_last,
return polygons_w_steiner_are_equal(orig_poly_circ, union_poly_circ,
traits);
}
} // namespace internal
template<class InputIterator, class FowardIterator>
bool
@ -219,23 +222,42 @@ partition_is_valid_2 (InputIterator point_first, InputIterator point_last,
Partition_is_valid_traits_2<Traits, Is_valid> validity_traits;
return partition_is_valid_2(point_first, point_last,
return internal::partition_is_valid_2(point_first, point_last,
poly_first, poly_last, validity_traits);
}
template<class InputIterator, class FowardIterator, class Traits>
bool
partition_is_valid_2 (InputIterator point_first, InputIterator point_last,
FowardIterator poly_first, FowardIterator poly_last,
const Traits& traits)
{
//typedef typename std::iterator_traits<InputIterator>::value_type Point_2;
//typedef typename Kernel_traits<Point_2>::Kernel K;
//typedef Partition_traits_2<K> Traits;
typedef Is_vacuously_valid<Traits> Is_valid;
Partition_is_valid_traits_2<Traits, Is_valid> validity_traits(traits);
return internal::partition_is_valid_2(point_first, point_last,
poly_first, poly_last, validity_traits);
}
template<class InputIterator, class ForwardIterator, class Traits>
bool
convex_partition_is_valid_2(InputIterator point_first,
InputIterator point_last,
ForwardIterator poly_first,
ForwardIterator poly_last,
const Traits& )
const Traits& traits)
{
typedef typename Traits::Is_convex_2 Is_convex_2;
Partition_is_valid_traits_2<Traits, Is_convex_2> validity_traits;
Partition_is_valid_traits_2<Traits, Is_convex_2> validity_traits(traits);
return partition_is_valid_2(point_first, point_last, poly_first, poly_last,
return internal::partition_is_valid_2(point_first, point_last, poly_first, poly_last,
validity_traits);
}
@ -260,13 +282,13 @@ y_monotone_partition_is_valid_2(InputIterator point_first,
InputIterator point_last,
ForwardIterator poly_first,
ForwardIterator poly_last,
const Traits& )
const Traits& traits)
{
typedef typename Traits::Is_y_monotone_2 Is_y_monotone_2;
Partition_is_valid_traits_2<Traits, Is_y_monotone_2> validity_traits;
Partition_is_valid_traits_2<Traits, Is_y_monotone_2> validity_traits(traits);
return partition_is_valid_2(point_first, point_last, poly_first, poly_last,
return internal::partition_is_valid_2(point_first, point_last, poly_first, poly_last,
validity_traits);
}

View File

@ -47,28 +47,28 @@ template <class Traits>
class Is_convex_2
{
public:
Is_convex_2(Traits t): traits(t) {}
Is_convex_2(const Traits& t): traits(t) {}
template <class ForwardIterator>
bool operator()(ForwardIterator first, ForwardIterator last)
{ return is_convex_2(first, last, traits); }
private:
Traits traits;
const Traits& traits;
};
template <class Traits>
class Is_y_monotone_2
{
public:
Is_y_monotone_2(Traits t): traits(t) {}
Is_y_monotone_2(const Traits& t): traits(t) {}
template <class ForwardIterator>
bool operator()(ForwardIterator first, ForwardIterator last)
{ return is_y_monotone_2(first, last, traits); }
private:
Traits traits;
const Traits& traits;
};
}

View File

@ -28,14 +28,14 @@
// implementation: Testing of convex partitioning functions
// ============================================================================
#include <CGAL/Cartesian.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Polygon_2.h>
#include <CGAL/partition_2.h>
#include <list>
#include <cassert>
typedef double NT;
typedef CGAL::Cartesian<NT> K;
typedef CGAL::Simple_cartesian<NT> K;
typedef K::Point_2 Point_2;
typedef std::list<Point_2> Container;
typedef CGAL::Polygon_2<K, Container> Polygon_2;

View File

@ -26,14 +26,14 @@
// implementation: Testing of convex partitioning functions
// ============================================================================
#include <CGAL/Homogeneous.h>
#include <CGAL/Simple_homogeneous.h>
#include <CGAL/Polygon_2.h>
#include <CGAL/partition_2.h>
#include <list>
#include <cassert>
typedef double NT;
typedef CGAL::Homogeneous<NT> K;
typedef CGAL::Simple_homogeneous<NT> K;
typedef K::Point_2 Point_2;
typedef std::list<Point_2> Container;
typedef CGAL::Polygon_2<K, Container> Polygon_2;

View File

@ -26,13 +26,13 @@
// implementation: Testing of convex partitioning functions
// ============================================================================
#include <CGAL/Cartesian.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Polygon_2.h>
#include <CGAL/partition_2.h>
#include <list>
#include <cassert>
typedef CGAL::Cartesian<double> K;
typedef CGAL::Simple_cartesian<double> K;
typedef K::Point_2 Point_2;
typedef std::list<Point_2> Container;
typedef CGAL::Polygon_2<K, Container> Polygon_2;

View File

@ -26,13 +26,13 @@
// implementation: Testing of convex partitioning functions
// ============================================================================
#include <CGAL/Homogeneous.h>
#include <CGAL/Simple_homogeneous.h>
#include <CGAL/Polygon_2.h>
#include <CGAL/partition_2.h>
#include <list>
#include <cassert>
typedef CGAL::Homogeneous<double> K;
typedef CGAL::Simple_homogeneous<double> K;
typedef K::Point_2 Point_2;
typedef std::list<Point_2> Container;
typedef CGAL::Polygon_2<K, Container> Polygon_2;

View File

@ -26,20 +26,20 @@
// implementation: testing of is_y_monotone_2 function
// ============================================================================
#include <CGAL/Homogeneous.h>
#include <CGAL/Cartesian.h>
#include <CGAL/Simple_homogeneous.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Polygon_2.h>
#include <CGAL/is_y_monotone_2.h>
#include <list>
#include <vector>
#include <cassert>
typedef CGAL::Cartesian<double> CR;
typedef CGAL::Simple_cartesian<double> CR;
typedef CR::Point_2 CPoint_2;
typedef std::list<CPoint_2> CContainer;
typedef CGAL::Polygon_2<CR, CContainer> CPolygon_2;
typedef CGAL::Homogeneous<double> HR;
typedef CGAL::Simple_homogeneous<double> HR;
typedef HR::Point_2 HPoint_2;
typedef std::vector<HPoint_2> HContainer;
typedef CGAL::Polygon_2<HR, HContainer> HPolygon_2;

View File

@ -3,12 +3,12 @@
#if TESTR==1
typedef double NT;
typedef CGAL::Cartesian<NT> K;
typedef CGAL::Simple_cartesian<NT> K;
#endif
#if TESTR==2
typedef double NT;
typedef CGAL::Homogeneous<NT> K;
typedef CGAL::Simple_homogeneous<NT> K;
#endif

View File

@ -1,7 +1,7 @@
#if TESTR == 1
#include <CGAL/Cartesian.h>
#include <CGAL/Simple_cartesian.h>
#endif
#if TESTR == 2
#include <CGAL/Homogeneous.h>
#include <CGAL/simple_homogeneous.h>
#endif

View File

@ -26,13 +26,13 @@
// implementation: Testing of convex partitioning functions
// ============================================================================
#include <CGAL/Cartesian.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Polygon_2.h>
#include <CGAL/partition_2.h>
#include <list>
#include <cassert>
typedef CGAL::Cartesian<double> K;
typedef CGAL::Simple_cartesian<double> K;
typedef K::Point_2 Point_2;
typedef std::list<Point_2> Container;
typedef CGAL::Polygon_2<K, Container> Polygon_2;

View File

@ -26,13 +26,13 @@
// implementation: Testing of convex partitioning functions
// ============================================================================
#include <CGAL/Homogeneous.h>
#include <CGAL/Simple_homogeneous.h>
#include <CGAL/Polygon_2.h>
#include <CGAL/partition_2.h>
#include <list>
#include <cassert>
typedef CGAL::Homogeneous<double> K;
typedef CGAL::Simple_homogeneous<double> K;
typedef K::Point_2 Point_2;
typedef std::list<Point_2> Container;
typedef CGAL::Polygon_2<K, Container> Polygon_2;

View File

@ -26,13 +26,13 @@
// implementation: testing of use of default traits classes for partitioning
// ============================================================================
#include <CGAL/Cartesian.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Partition_traits_2.h>
#include <CGAL/partition_2.h>
#include <list>
#include <cassert>
typedef CGAL::Cartesian<double> K;
typedef CGAL::Simple_cartesian<double> K;
typedef CGAL::Partition_traits_2<K> Traits;
typedef Traits::Point_2 Point_2;
typedef Traits::Polygon_2 Polygon_2;

View File

@ -26,13 +26,13 @@
// implementation: testing of use of default traits classes for partitioning
// ============================================================================
#include <CGAL/Homogeneous.h>
#include <CGAL/Simple_homogeneous.h>
#include <CGAL/Partition_traits_2.h>
#include <CGAL/partition_2.h>
#include <list>
#include <cassert>
typedef CGAL::Homogeneous<double> K;
typedef CGAL::Simple_homogeneous<double> K;
typedef CGAL::Partition_traits_2<K> Traits;
typedef Traits::Point_2 Point_2;
typedef Traits::Polygon_2 Polygon_2;

View File

@ -26,13 +26,13 @@
// implementation: Testing of y-monotone partitioning function
// ============================================================================
#include <CGAL/Cartesian.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Polygon_2.h>
#include <CGAL/partition_2.h>
#include <list>
#include <cassert>
typedef CGAL::Cartesian<double> K;
typedef CGAL::Simple_cartesian<double> K;
typedef K::Point_2 Point_2;
typedef std::list<Point_2> Container;
typedef CGAL::Polygon_2<K, Container> Polygon_2;

View File

@ -26,13 +26,13 @@
// implementation: Testing of y-monotone partitioning function
// ============================================================================
#include <CGAL/Homogeneous.h>
#include <CGAL/Simple_homogeneous.h>
#include <CGAL/Polygon_2.h>
#include <CGAL/partition_2.h>
#include <list>
#include <cassert>
typedef CGAL::Homogeneous<double> K;
typedef CGAL::Simple_homogeneous<double> K;
typedef K::Point_2 Point_2;
typedef std::list<Point_2> Container;
typedef CGAL::Polygon_2<K, Container> Polygon_2;

View File

@ -148,13 +148,16 @@ class Polygon_2 {
/// @{
/// Creates an empty polygon.
Polygon_2(const Traits & p_traits = Traits()) : traits(p_traits) {}
Polygon_2() : traits() {}
/// Creates an empty polygon.
Polygon_2(const Traits & p_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
/// Creates 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>

View File

@ -25,7 +25,7 @@ public:
/*!
*/
boost::property_traits<PointPropertyMap>::key_type Point_2;
typedef boost::property_traits<PointPropertyMap>::key_type Point_2;
/// @}