Fixed intersection return type

This commit is contained in:
Efi Fogel 2020-04-06 01:23:45 +03:00
parent 4158542c86
commit 7436c149e1
5 changed files with 273 additions and 387 deletions

View File

@ -8,7 +8,8 @@
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Author(s): Baruch Zukerman <baruchzu@post.tau.ac.il>
// Efi Fogel <efifogel@gmail.com>
#ifndef CGAL_BSO_2_GPS_AGG_META_TRAITS_H
#define CGAL_BSO_2_GPS_AGG_META_TRAITS_H
@ -81,8 +82,8 @@ class Gps_agg_meta_traits :
typedef typename Arr::Traits_adaptor_2 Traits;
typedef Traits Gt2;
typedef typename Gt2::X_monotone_curve_2 Base_X_monotone_curve_2;
typedef typename Gt2::Point_2 Base_Point_2;
typedef typename Gt2::X_monotone_curve_2 Base_x_monotone_curve_2;
typedef typename Gt2::Point_2 Base_point_2;
typedef typename Gt2::Construct_min_vertex_2 Base_Construct_min_vertex_2;
typedef typename Gt2::Construct_max_vertex_2 Base_Construct_max_vertex_2;
typedef typename Gt2::Compare_endpoints_xy_2 Base_Compare_endpoints_xy_2;
@ -106,8 +107,8 @@ public:
typedef Point_with_vertex<Arr> Point_data;
private:
typedef Gps_traits_decorator<Gt2, Curve_data, Point_data>
Base;
typedef Gps_agg_meta_traits<Arrangement> Self;
typedef Gps_traits_decorator<Gt2, Curve_data, Point_data> Base;
public:
typedef typename Base::X_monotone_curve_2 X_monotone_curve_2;
@ -145,93 +146,88 @@ public:
class Intersect_2 {
private:
Base_Intersect_2 m_base;
Base_Compare_endpoints_xy_2 m_base_cmp_endpoints;
Base_Compare_xy_2 m_base_cmp_xy;
Base_Construct_min_vertex_2 m_base_ctr_min_v;
const Self& m_traits;
/*! Constructor. */
Intersect_2(const Self& traits) : m_traits(traits) {}
friend Self;
public:
/*! Construct. */
Intersect_2(const Base_Intersect_2& base,
const Base_Compare_endpoints_xy_2& base_cmp_endpoints,
const Base_Compare_xy_2& base_cmp_xy,
const Base_Construct_min_vertex_2& base_ctr_min_v) :
m_base(base),
m_base_cmp_endpoints(base_cmp_endpoints),
m_base_cmp_xy(base_cmp_xy),
m_base_ctr_min_v(base_ctr_min_v)
{}
template <typename OutputIterator>
OutputIterator operator()(const X_monotone_curve_2& cv1,
const X_monotone_curve_2& cv2,
OutputIterator oi) const
{
if (cv1.data().arr() == cv2.data().arr()) {
return oi; // the curves are disjoint-interior because they
// are already at the same arrangement.
}
// Check whether the curves are already in the same arrangement, and thus
// must be interior-disjoint
if (cv1.data().arr() == cv2.data().arr()) return oi;
const std::pair<Base_Point_2, Multiplicity>* base_pt;
const Base_X_monotone_curve_2* overlap_cv;
OutputIterator oi_end;
if(m_base_cmp_xy(m_base_ctr_min_v(cv1.base()),
m_base_ctr_min_v(cv2.base())) == LARGER)
oi_end = m_base(cv1.base(), cv2.base(), oi);
typedef const std::pair<Base_point_2, Multiplicity>
Intersection_base_point;
typedef boost::variant<Intersection_base_point, Base_x_monotone_curve_2>
Intersection_base_result;
typedef const std::pair<Point_2, Multiplicity> Intersection_point;
typedef boost::variant<Intersection_point, X_monotone_curve_2>
Intersection_result;
const auto* base_traits = m_traits.m_base_traits;
auto base_cmp_xy = base_traits->compare_xy_2_object();
auto base_cmp_endpoints = base_traits->compare_endpoints_xy_2_object();
auto base_ctr_min_vertex = base_traits->construct_min_vertex_2_object();
auto base_intersect = base_traits->intersect_2_object();
std::vector<Intersection_base_result> xections;
if (base_cmp_xy(base_ctr_min_vertex(cv1.base()),
base_ctr_min_vertex(cv2.base())) == LARGER)
base_intersect(cv1.base(), cv2.base(), back_inserter(xections));
else
oi_end = m_base(cv2.base(), cv1.base(), oi);
base_intersect(cv2.base(), cv1.base(), back_inserter(xections));
// convert objects that are associated with Base_X_monotone_curve_2 to
// convert objects that are associated with Base_x_monotone_curve_2 to
// the extenede X_monotone_curve_2
for (; oi != oi_end; ++oi) {
base_pt = object_cast<std::pair<Base_Point_2, Multiplicity> >(&(*oi));
for (const auto& xection : xections) {
const Intersection_base_point* base_pt =
boost::get<Intersection_base_point>(&xection);
if (base_pt != nullptr) {
Point_2 point_plus(base_pt->first); // the extended point
*oi = CGAL::make_object(std::make_pair(point_plus,
base_pt->second));
*oi++ =
Intersection_result(std::make_pair(point_plus, base_pt->second));
continue;
}
const Base_x_monotone_curve_2* overlap_cv =
boost::get<Base_x_monotone_curve_2>(&xection);
CGAL_assertion(overlap_cv != nullptr);
unsigned int ov_bc;
unsigned int ov_twin_bc;
if (base_cmp_endpoints(cv1) == base_cmp_endpoints(cv2)) {
// cv1 and cv2 have the same directions
ov_bc = cv1.data().bc() + cv2.data().bc();
ov_twin_bc = cv1.data().twin_bc() + cv2.data().twin_bc();
}
else {
overlap_cv = object_cast<Base_X_monotone_curve_2>(&(*oi));
if (overlap_cv != nullptr) {
unsigned int ov_bc;
unsigned int ov_twin_bc;
if (m_base_cmp_endpoints(cv1) == m_base_cmp_endpoints(cv2)) {
// cv1 and cv2 have the same directions
ov_bc = cv1.data().bc() + cv2.data().bc();
ov_twin_bc = cv1.data().twin_bc() + cv2.data().twin_bc();
}
else {
// cv1 and cv2 have opposite directions
ov_bc = cv1.data().bc() + cv2.data().twin_bc();
ov_twin_bc = cv1.data().twin_bc() + cv2.data().bc();
}
if(m_base_cmp_endpoints(*overlap_cv) != m_base_cmp_endpoints(cv1)) {
// overlap_cv, cv1 have opposite directions
std::swap(ov_bc, ov_twin_bc);
}
Curve_data cv_data(cv1.data().arr(), Halfedge_handle(),
ov_bc, ov_twin_bc);
*oi = CGAL::make_object(X_monotone_curve_2(*overlap_cv, cv_data));
}
// cv1 and cv2 have opposite directions
ov_bc = cv1.data().bc() + cv2.data().twin_bc();
ov_twin_bc = cv1.data().twin_bc() + cv2.data().bc();
}
if (base_cmp_endpoints(*overlap_cv) != base_cmp_endpoints(cv1)) {
// overlap_cv, cv1 have opposite directions
std::swap(ov_bc, ov_twin_bc);
}
Curve_data cv_data(cv1.data().arr(), Halfedge_handle(),
ov_bc, ov_twin_bc);
*oi++ = Intersection_result(X_monotone_curve_2(*overlap_cv, cv_data));
}
//return past-end iterator
return oi_end;
return oi;
}
};
/*! Obtain an Intersect_2 functor object. */
Intersect_2 intersect_2_object() const
{
return Intersect_2(this->m_base_tr->intersect_2_object(),
this->m_base_tr->compare_endpoints_xy_2_object(),
this->m_base_tr->compare_xy_2_object(),
this->m_base_tr->construct_min_vertex_2_object());
}
Intersect_2 intersect_2_object() const { return Intersect_2(*this); }
class Split_2 {
private:
@ -256,7 +252,7 @@ public:
/*! Obtain a Split_2 functor object. */
Split_2 split_2_object() const
{ return Split_2(this->m_base_tr->split_2_object()); }
{ return Split_2(this->m_base_traits->split_2_object()); }
class Construct_min_vertex_2 {
private:
@ -286,7 +282,7 @@ public:
/*! Get a Construct_min_vertex_2 functor object. */
Construct_min_vertex_2 construct_min_vertex_2_object() const
{
return Construct_min_vertex_2(this->m_base_tr->
return Construct_min_vertex_2(this->m_base_traits->
construct_min_vertex_2_object());
}
@ -318,7 +314,7 @@ public:
/*! Get a Construct_min_vertex_2 functor object. */
Construct_max_vertex_2 construct_max_vertex_2_object() const
{
return Construct_max_vertex_2(this->m_base_tr->
return Construct_max_vertex_2(this->m_base_traits->
construct_max_vertex_2_object());
}
@ -348,7 +344,7 @@ public:
/*! Obtain a Construct_min_vertex_2 functor object. */
Compare_xy_2 compare_xy_2_object() const
{ return Compare_xy_2(this->m_base_tr->compare_xy_2_object()); }
{ return Compare_xy_2(this->m_base_traits->compare_xy_2_object()); }
// left-right
class Parameter_space_in_x_2 {
@ -380,7 +376,7 @@ public:
/*! Obtain a Construct_min_vertex_2 functor object. */
Parameter_space_in_x_2 parameter_space_in_x_2_object() const
{
return Parameter_space_in_x_2(this->m_base_tr->
return Parameter_space_in_x_2(this->m_base_traits->
parameter_space_in_x_2_object());
}
@ -404,7 +400,7 @@ public:
/*! Obtain a Construct_min_vertex_2 functor object. */
Compare_y_near_boundary_2 compare_y_near_boundary_2_object() const
{
return Compare_y_near_boundary_2(this->m_base_tr->
return Compare_y_near_boundary_2(this->m_base_traits->
compare_y_near_boundary_2_object()
);
}
@ -443,7 +439,7 @@ public:
/*! Obtain a Construct_min_vertex_2 functor object. */
Parameter_space_in_y_2 parameter_space_in_y_2_object() const
{
return Parameter_space_in_y_2(this->m_base_tr->
return Parameter_space_in_y_2(this->m_base_traits->
parameter_space_in_y_2_object());
}
@ -476,7 +472,7 @@ public:
/*! Obtain a Construct_min_vertex_2 functor object. */
Compare_x_near_boundary_2 compare_x_near_boundary_2_object() const
{
return Compare_x_near_boundary_2(this->m_base_tr->
return Compare_x_near_boundary_2(this->m_base_traits->
compare_x_near_boundary_2_object());
}

View File

@ -75,7 +75,7 @@ public:
Construct_min_vertex_2 construct_min_vertex_2_object () const
{
return Construct_min_vertex_2
(this->m_base_tr->construct_min_vertex_2_object());
(this->m_base_traits->construct_min_vertex_2_object());
}
@ -100,7 +100,7 @@ public:
Construct_max_vertex_2 construct_max_vertex_2_object () const
{
return Construct_max_vertex_2
(this->m_base_tr->construct_max_vertex_2_object());
(this->m_base_traits->construct_max_vertex_2_object());
}
class Compare_xy_2
@ -123,7 +123,7 @@ public:
/*! Get a Compare_xy_2 functor object. */
Compare_xy_2 compare_xy_2_object () const
{
return Compare_xy_2(m_base_tr->compare_xy_2_object());
return Compare_xy_2(m_base_traits->compare_xy_2_object());
}
};

View File

@ -8,7 +8,8 @@
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Author(s): Baruch Zukerman <baruchzu@post.tau.ac.il>
// Efi Fogel <efifogel@gmail.com>
#ifndef CGAL_GPS_SIMPLIFIER_TRAITS_H
#define CGAL_GPS_SIMPLIFIER_TRAITS_H
@ -20,103 +21,67 @@
namespace CGAL {
class Gps_simplifier_curve_data
{
class Gps_simplifier_curve_data {
protected:
unsigned int m_bc;
unsigned int m_twin_bc;
unsigned int m_index;
public:
Gps_simplifier_curve_data()
{}
Gps_simplifier_curve_data() {}
Gps_simplifier_curve_data(unsigned int bc,
unsigned int twin_bc,
Gps_simplifier_curve_data(unsigned int bc, unsigned int twin_bc,
unsigned int index):
m_bc(bc),
m_twin_bc(twin_bc),
m_index(index)
{}
unsigned int bc() const
{
return m_bc;
}
unsigned int bc() const { return m_bc; }
unsigned int twin_bc() const
{
return m_twin_bc;
}
unsigned int twin_bc() const { return m_twin_bc; }
unsigned int index() const
{
return m_index;
}
unsigned int index() const { return m_index; }
unsigned int& index()
{
return m_index;
}
unsigned int& index() { return m_index; }
unsigned int& twin_bc()
{
return m_twin_bc;
}
unsigned int& twin_bc() { return m_twin_bc; }
void set_bc(unsigned int bc)
{
m_bc = bc;
}
void set_bc(unsigned int bc) { m_bc = bc; }
void set_twin_bc(unsigned int twin_bc)
{
m_twin_bc = twin_bc;
}
void set_twin_bc(unsigned int twin_bc) { m_twin_bc = twin_bc; }
void set_index(unsigned int index)
{
m_index = index;
}
void set_index(unsigned int index) { m_index = index; }
};
struct Gps_simplifier_point_data
{
struct Gps_simplifier_point_data {
protected:
unsigned int m_index;
public:
Gps_simplifier_point_data()
{}
Gps_simplifier_point_data() {}
Gps_simplifier_point_data(unsigned int index) : m_index(index)
{}
Gps_simplifier_point_data(unsigned int index) : m_index(index) {}
unsigned int index() const
{
return m_index;
}
unsigned int index() const { return m_index; }
void set_index(unsigned int index)
{
m_index = index;
}
void set_index(unsigned int index) { m_index = index; }
};
template <class Traits_>
template <typename Traits_>
class Gps_simplifier_traits :
public Gps_traits_decorator<Traits_,
Gps_simplifier_curve_data,
Gps_simplifier_point_data>
{
public:
typedef Traits_ Traits;
typedef Traits_ Traits;
typedef Gps_traits_decorator<Traits_,
Gps_simplifier_curve_data,
Gps_simplifier_point_data> Base;
typedef Gps_simplifier_traits<Traits> Self;
typedef typename Traits::X_monotone_curve_2 Base_X_monotone_curve_2;
typedef typename Traits::Point_2 Base_Point_2;
Gps_simplifier_point_data> Base;
typedef Gps_simplifier_traits<Traits> Self;
typedef typename Traits::X_monotone_curve_2 Base_x_monotone_curve_2;
typedef typename Traits::Point_2 Base_point_2;
typedef typename Traits::Construct_min_vertex_2 Base_Construct_min_vertex_2;
typedef typename Traits::Construct_max_vertex_2 Base_Construct_max_vertex_2;
typedef typename Traits::Compare_endpoints_xy_2 Base_Compare_endpoints_xy_2;
@ -129,9 +94,7 @@ public:
protected:
mutable unsigned int m_pgn_size;
public:
typedef typename Base::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Base::Point_2 Point_2;
typedef typename Base::Multiplicity Multiplicity;
@ -139,333 +102,256 @@ public:
typedef typename Base::Curve_data Curve_data;
typedef typename Base::Point_data Point_data;
Gps_simplifier_traits()
{}
Gps_simplifier_traits() {}
Gps_simplifier_traits(const Traits & tr) : Base(tr)
{}
Gps_simplifier_traits(const Traits& tr) : Base(tr) {}
unsigned int polygon_size() const
{
return m_pgn_size;
}
unsigned int polygon_size() const { return m_pgn_size; }
void set_polygon_size(unsigned int pgn_size) const
{
m_pgn_size = pgn_size;
}
void set_polygon_size(unsigned int pgn_size) const { m_pgn_size = pgn_size; }
bool is_valid_index(unsigned int index) const
{
return (index < m_pgn_size);
}
{ return (index < m_pgn_size); }
unsigned int invalid_index() const
{
return (m_pgn_size);
}
unsigned int invalid_index() const { return (m_pgn_size); }
class Intersect_2
{
class Intersect_2 {
private:
Base_Intersect_2 m_base;
Base_Compare_endpoints_xy_2 m_base_cmp_endpoints;
Base_Compare_xy_2 m_base_cmp_xy;
Base_Construct_min_vertex_2 m_ctr_min_v;
const Self * m_self_tr;
public:
/*! The traits (in case it has state) */
const Self& m_traits;
/*! Constructor. */
Intersect_2 (const Base_Intersect_2& base,
const Base_Compare_endpoints_xy_2& base_cmp_endpoints,
const Base_Compare_xy_2& base_cmp_xy,
const Base_Construct_min_vertex_2& ,
const Self* tr) :
m_base(base),
m_base_cmp_endpoints(base_cmp_endpoints),
m_base_cmp_xy(base_cmp_xy),
m_self_tr(tr)
{}
Intersect_2(const Self& tr) : m_traits(tr) {}
template<class OutputIterator>
OutputIterator operator() (const X_monotone_curve_2& cv1,
const X_monotone_curve_2& cv2,
OutputIterator oi) const
friend Self;
public:
template <typename OutputIterator>
OutputIterator operator()(const X_monotone_curve_2& cv1,
const X_monotone_curve_2& cv2,
OutputIterator oi) const
{
typedef const std::pair<Base_point_2, Multiplicity>
Intersection_base_point;
typedef boost::variant<Intersection_base_point, Base_x_monotone_curve_2>
Intersection_base_result;
typedef const std::pair<Point_2, Multiplicity> Intersection_point;
typedef boost::variant<Intersection_point, X_monotone_curve_2>
Intersection_result;
const auto* base_traits = m_traits.m_base_traits;
auto base_cmp_xy = base_traits->compare_xy_2_object();
auto base_cmp_endpoints = base_traits->compare_endpoints_xy_2_object();
auto base_ctr_min_vertex = base_traits->construct_min_vertex_2_object();
auto base_intersect = base_traits->intersect_2_object();
//// if the two curves are incident, do not intersect them
//if(m_self_tr->is_valid_index(cv1.data().index()) &&
// m_self_tr->is_valid_index(cv2.data().index()))
//if (m_traits.is_valid_index(cv1.data().index()) &&
// m_traits.is_valid_index(cv2.data().index()))
//{
// unsigned int index_diff =
// (cv1.data().index() > cv2.data().index()) ?
// (cv1.data().index() - cv2.data().index()):
// (cv2.data().index() - cv1.data().index());
// if(index_diff == 1 ||index_diff == m_self_tr->polygon_size() -1)
// if(index_diff == 1 ||index_diff == m_traits.polygon_size() -1)
// {
// return (oi);
// }
//}
const std::pair<Base_Point_2, Multiplicity> *base_pt;
const Base_X_monotone_curve_2 *overlap_cv;
OutputIterator oi_end;
if(m_base_cmp_xy(m_ctr_min_v(cv1.base()),
m_ctr_min_v(cv2.base())) == LARGER)
oi_end = m_base(cv1.base(), cv2.base(), oi);
std::vector<Intersection_base_result> xections;
if (base_cmp_xy(base_ctr_min_vertex(cv1.base()),
base_ctr_min_vertex(cv2.base())) == LARGER)
base_intersect(cv1.base(), cv2.base(), back_inserter(xections));
else
oi_end = m_base(cv2.base(), cv1.base(), oi);
base_intersect(cv2.base(), cv1.base(), back_inserter(xections));
// convert objects that are associated with Base_X_monotone_curve_2 to
// convert objects that are associated with Base_x_monotone_curve_2 to
// the extenede X_monotone_curve_2
for(; oi != oi_end; ++oi)
{
base_pt = object_cast<std::pair<Base_Point_2, Multiplicity> >(&(*oi));
if (base_pt != nullptr)
{
Point_data pt_data(m_self_tr->invalid_index());
Point_2 point_plus (base_pt->first, pt_data); // the extended point
*oi = CGAL::make_object(std::make_pair(point_plus,
base_pt->second));
for (const auto& xection : xections) {
const Intersection_base_point* base_pt =
boost::get<Intersection_base_point>(&xection);
if (base_pt != nullptr) {
Point_data pt_data(m_traits.invalid_index());
Point_2 point_plus(base_pt->first, pt_data); // the extended point
*oi++ =
Intersection_result(std::make_pair(point_plus, base_pt->second));
continue;
}
else
{
overlap_cv = object_cast<Base_X_monotone_curve_2> (&(*oi));
if (overlap_cv != nullptr)
{
unsigned int ov_bc;
unsigned int ov_twin_bc;
if(m_base_cmp_endpoints(cv1) == m_base_cmp_endpoints(cv2))
{
// cv1 and cv2 have the same directions
ov_bc = cv1.data().bc() + cv2.data().bc();
ov_twin_bc = cv1.data().twin_bc() + cv2.data().twin_bc();
}
else
{
// cv1 and cv2 have opposite directions
ov_bc = cv1.data().bc() + cv2.data().twin_bc();
ov_twin_bc = cv1.data().twin_bc() + cv2.data().bc();
}
const Base_x_monotone_curve_2* overlap_cv =
boost::get<Base_x_monotone_curve_2>(&xection);
if(m_base_cmp_endpoints(*overlap_cv) != m_base_cmp_endpoints(cv1))
{
// overlap_cv, cv1 have opposite directions
std::swap(ov_bc, ov_twin_bc);
}
Curve_data cv_data(ov_bc, ov_twin_bc, m_self_tr->invalid_index());
*oi = CGAL::make_object (X_monotone_curve_2 (*overlap_cv, cv_data));
}
CGAL_assertion_code(overlap_cv != nullptr);
unsigned int ov_bc;
unsigned int ov_twin_bc;
if (base_cmp_endpoints(cv1) == base_cmp_endpoints(cv2)) {
// cv1 and cv2 have the same directions
ov_bc = cv1.data().bc() + cv2.data().bc();
ov_twin_bc = cv1.data().twin_bc() + cv2.data().twin_bc();
}
else {
// cv1 and cv2 have opposite directions
ov_bc = cv1.data().bc() + cv2.data().twin_bc();
ov_twin_bc = cv1.data().twin_bc() + cv2.data().bc();
}
if (base_cmp_endpoints(*overlap_cv) != base_cmp_endpoints(cv1)) {
// overlap_cv, cv1 have opposite directions
std::swap(ov_bc, ov_twin_bc);
}
Curve_data cv_data(ov_bc, ov_twin_bc, m_traits.invalid_index());
*oi++ = Intersection_result(X_monotone_curve_2(*overlap_cv, cv_data));
}
//return past-end iterator
return oi_end;
return oi;
}
};
/*! Get an Intersect_2 functor object. */
Intersect_2 intersect_2_object () const
{
return Intersect_2(this->m_base_tr->intersect_2_object(),
this->m_base_tr->compare_endpoints_xy_2_object(),
this->m_base_tr->compare_xy_2_object(),
this->m_base_tr->construct_min_vertex_2_object(),
this);
}
/*! Obtain an Intersect_2 functor object. */
Intersect_2 intersect_2_object () const { return Intersect_2(*this); }
class Split_2
{
class Split_2 {
private:
Base_Split_2 m_base_split;
const Self * m_self_tr;
public:
const Self& m_traits;
/*! Constructor. */
Split_2 (const Base_Split_2& base, const Self* tr) :
m_base_split(base),
m_self_tr(tr)
{}
Split_2(const Self& tr) : m_traits(tr) {}
void operator() (const X_monotone_curve_2& cv, const Point_2 & p,
X_monotone_curve_2& c1, X_monotone_curve_2& c2) const
friend Self;
public:
void operator()(const X_monotone_curve_2& cv, const Point_2 & p,
X_monotone_curve_2& c1, X_monotone_curve_2& c2) const
{
m_base_split(cv.base(),
p.base(),
c1.base(),
c2.base());
const auto* base_traits = m_traits.m_base_traits;
auto base_split = base_traits->split_2_object();
base_split(cv.base(), p.base(), c1.base(), c2.base());
const Curve_data& cv_data = cv.data();
c1.set_data(Curve_data(cv_data.bc(),
cv_data.twin_bc(),
m_self_tr->invalid_index()));
c1.set_data(Curve_data(cv_data.bc(), cv_data.twin_bc(),
m_traits.invalid_index()));
c2.set_data(Curve_data(cv_data.bc(),
cv_data.twin_bc(),
m_self_tr->invalid_index()));
c2.set_data(Curve_data(cv_data.bc(), cv_data.twin_bc(),
m_traits.invalid_index()));
}
};
/*! Get a Split_2 functor object. */
Split_2 split_2_object () const
{
return Split_2(this->m_base_tr->split_2_object(), this);
}
Split_2 split_2_object () const { return Split_2(*this); }
class Construct_min_vertex_2
{
class Construct_min_vertex_2 {
private:
Base_Construct_min_vertex_2 m_base;
Base_Compare_endpoints_xy_2 m_base_cmp_endpoints;
const Self * m_self_tr;
const Self& m_traits;
Construct_min_vertex_2(const Self& tr) : m_traits(tr) {}
friend Self;
public:
Construct_min_vertex_2(const Base_Construct_min_vertex_2& base,
const Base_Compare_endpoints_xy_2& base_cmp_endpoints,
const Self * tr):
m_base(base),
m_base_cmp_endpoints(base_cmp_endpoints),
m_self_tr(tr)
{}
/*!
* Get the left endpoint of the x-monotone curve (segment).
/*! Obtain the left endpoint of the x-monotone curve (segment).
* \param cv The curve.
* \return The left endpoint.
*/
Point_2 operator() (const X_monotone_curve_2 & cv) const
Point_2 operator()(const X_monotone_curve_2 & cv) const
{
if(!m_self_tr->is_valid_index(cv.data().index()))
{
return Point_2 (m_base(cv.base()), m_self_tr->invalid_index());
}
const auto* base_traits = m_traits.m_base_traits;
auto base_ctr_min_vertex = base_traits->construct_min_vertex_2_object();
Comparison_result res = m_base_cmp_endpoints(cv);
if (! m_traits.is_valid_index(cv.data().index()))
return Point_2(base_ctr_min_vertex(cv.base()), m_traits.invalid_index());
auto base_cmp_endpoints = base_traits->compare_endpoints_xy_2_object();
Comparison_result res = base_cmp_endpoints(cv);
Point_data pt_data;
if(res == SMALLER)
{
if (res == SMALLER) {
// min vertex is the source
pt_data.set_index(cv.data().index());
}
else
{
else {
// min vertex is the target
pt_data.set_index((cv.data().index() + 1) % m_self_tr->polygon_size());
pt_data.set_index((cv.data().index() + 1) % m_traits.polygon_size());
}
return Point_2 (m_base(cv.base()), pt_data);
return Point_2(base_ctr_min_vertex(cv.base()), pt_data);
}
};
/*! Get a Construct_min_vertex_2 functor object. */
Construct_min_vertex_2 construct_min_vertex_2_object () const
{
return Construct_min_vertex_2
(this->m_base_tr->construct_min_vertex_2_object(),
this->m_base_tr->compare_endpoints_xy_2_object(),
this);
}
{ return Construct_min_vertex_2(*this); }
class Construct_max_vertex_2
{
class Construct_max_vertex_2 {
private:
Base_Construct_max_vertex_2 m_base;
Base_Compare_endpoints_xy_2 m_base_cmp_endpoints;
const Self * m_self_tr;
const Self& m_traits;
Construct_max_vertex_2(const Self& tr) : m_traits(tr) {}
friend Self;
public:
Construct_max_vertex_2(const Base_Construct_max_vertex_2& base,
const Base_Compare_endpoints_xy_2& base_cmp_endpoints,
const Self * tr):
m_base(base),
m_base_cmp_endpoints(base_cmp_endpoints),
m_self_tr(tr)
{}
/*!
* Get the right endpoint of the x-monotone curve (segment).
/*! Obtain the right endpoint of the x-monotone curve (segment).
* \param cv The curve.
* \return The left endpoint.
*/
Point_2 operator() (const X_monotone_curve_2 & cv) const
{
if(!m_self_tr->is_valid_index(cv.data().index()))
{
return Point_2 (m_base(cv.base()), m_self_tr->invalid_index());
}
Comparison_result res = m_base_cmp_endpoints(cv);
const auto* base_traits = m_traits.m_base_traits;
auto base_ctr_max_vertex = base_traits->construct_max_vertex_2_object();
if (! m_traits.is_valid_index(cv.data().index()))
return Point_2(base_ctr_max_vertex(cv.base()), m_traits.invalid_index());
auto base_cmp_endpoints = base_traits->compare_endpoints_xy_2_object();
Comparison_result res = base_cmp_endpoints(cv);
Point_data pt_data;
if(res == SMALLER)
{
if (res == SMALLER) {
// min vertex is the target
pt_data.set_index((cv.data().index() + 1) % m_self_tr->polygon_size());
pt_data.set_index((cv.data().index() + 1) % m_traits.polygon_size());
}
else
{
else {
// min vertex is the source
pt_data.set_index(cv.data().index());
}
return Point_2 (m_base(cv.base()), pt_data);
return Point_2(base_ctr_max_vertex(cv.base()), pt_data);
}
};
/*! Get a Construct_min_vertex_2 functor object. */
Construct_max_vertex_2 construct_max_vertex_2_object () const
{
return Construct_max_vertex_2
(this->m_base_tr->construct_max_vertex_2_object(),
this->m_base_tr->compare_endpoints_xy_2_object(),
this);
}
{ return Construct_max_vertex_2(*this); }
class Compare_xy_2
{
class Compare_xy_2 {
private:
Base_Compare_xy_2 m_base;
const Self * m_self_tr;
const Self& m_traits;
Compare_xy_2(const Self& tr) : m_traits(tr) {}
friend Self;
public:
Compare_xy_2(const Base_Compare_xy_2& base,
const Self * tr):
m_base(base),
m_self_tr(tr)
{}
/*!
* Get the left endpoint of the x-monotone curve (segment).
/*! Obtain the left endpoint of the x-monotone curve (segment).
* \param cv The curve.
* \return The left endpoint.
*/
Comparison_result operator() (const Point_2& p1, const Point_2& p2) const
Comparison_result operator()(const Point_2& p1, const Point_2& p2) const
{
const auto* base_traits = m_traits.m_base_traits;
auto base_cmp_xy = base_traits->compare_xy_2_object();
//if one of the indexes is invalid, compare p1 and p2
if(! m_self_tr->is_valid_index(p1.data().index()) ||
! m_self_tr->is_valid_index(p2.data().index()))
return (m_base(p1.base(), p2.base()));
if (! m_traits.is_valid_index(p1.data().index()) ||
! m_traits.is_valid_index(p2.data().index()))
return (base_cmp_xy(p1.base(), p2.base()));
// if the two point has the same index, return EQUAL
if(p1.data().index() == p2.data().index())
{
return EQUAL;
}
if (p1.data().index() == p2.data().index()) return EQUAL;
return (m_base(p1.base(), p2.base()));
return (base_cmp_xy(p1.base(), p2.base()));
}
};
/*! Get a Construct_min_vertex_2 functor object. */
Compare_xy_2 compare_xy_2_object () const
{
return Compare_xy_2(this->m_base_tr->compare_xy_2_object(), this);
}
Compare_xy_2 compare_xy_2_object () const { return Compare_xy_2(*this); }
};
} //namespace CGAL

View File

@ -202,25 +202,27 @@ public:
protected:
//Data members
const Base * m_base_tr;
const Base* m_base_traits;
bool m_traits_owner;
public:
Gps_traits_decorator() :
m_base_tr(new Base()),
m_base_traits(new Base()),
m_traits_owner(true)
{}
Gps_traits_decorator(const Base & base_traits) :
m_base_tr(&base_traits),
Gps_traits_decorator(const Base& base_traits) :
m_base_traits(&base_traits),
m_traits_owner(false)
{}
~Gps_traits_decorator()
{
if (m_traits_owner)
delete m_base_tr;
if (m_traits_owner) {
delete m_base_traits;
m_base_traits = nullptr;
}
}
class Compare_x_2
@ -242,7 +244,7 @@ public:
/*! Get a Compare_x_2 functor object. */
Compare_x_2 compare_x_2_object () const
{
return Compare_x_2(m_base_tr->compare_x_2_object());
return Compare_x_2(m_base_traits->compare_x_2_object());
}
@ -265,7 +267,7 @@ public:
/*! Get a Compare_xy_2 functor object. */
Compare_xy_2 compare_xy_2_object () const
{
return Compare_xy_2(m_base_tr->compare_xy_2_object());
return Compare_xy_2(m_base_traits->compare_xy_2_object());
}
class Construct_min_vertex_2
@ -288,7 +290,7 @@ public:
/*! Get a Construct_min_vertex_2 functor object. */
Construct_min_vertex_2 construct_min_vertex_2_object () const
{
return Construct_min_vertex_2(m_base_tr->construct_min_vertex_2_object());
return Construct_min_vertex_2(m_base_traits->construct_min_vertex_2_object());
}
class Construct_max_vertex_2
@ -311,7 +313,7 @@ public:
/*! Get a Construct_max_vertex_2 functor object. */
Construct_max_vertex_2 construct_max_vertex_2_object () const
{
return Construct_max_vertex_2(m_base_tr->construct_max_vertex_2_object());
return Construct_max_vertex_2(m_base_traits->construct_max_vertex_2_object());
}
@ -334,7 +336,7 @@ public:
/*! Get a Is_vertical_2 functor object. */
Is_vertical_2 is_vertical_2_object() const
{
return Is_vertical_2(m_base_tr->is_vertical_2_object());
return Is_vertical_2(m_base_traits->is_vertical_2_object());
}
@ -358,7 +360,7 @@ public:
/*! Get a compare_y_at_x_2_object functor object. */
Compare_y_at_x_2 compare_y_at_x_2_object() const
{
return Compare_y_at_x_2(m_base_tr->compare_y_at_x_2_object());
return Compare_y_at_x_2(m_base_traits->compare_y_at_x_2_object());
}
@ -384,7 +386,7 @@ public:
/*! Get a Compare_y_at_x_right_2 functor object. */
Compare_y_at_x_right_2 compare_y_at_x_right_2_object() const
{
return Compare_y_at_x_right_2(m_base_tr->compare_y_at_x_right_2_object());
return Compare_y_at_x_right_2(m_base_traits->compare_y_at_x_right_2_object());
}
@ -407,7 +409,7 @@ public:
/*! Get a Equal_2 functor object. */
Equal_2 equal_2_object() const
{
return Equal_2(m_base_tr->equal_2_object());
return Equal_2(m_base_traits->equal_2_object());
}
@ -432,7 +434,7 @@ public:
/*! Get a Split_2 functor object. */
Split_2 split_2_object() const
{
return Split_2(m_base_tr->split_2_object());
return Split_2(m_base_traits->split_2_object());
}
@ -495,9 +497,9 @@ public:
/*! Get a Intersect_2 functor object. */
Intersect_2 intersect_2_object() const
{
return Intersect_2(m_base_tr->intersect_2_object(),
m_base_tr->compare_xy_2_object(),
m_base_tr->construct_min_vertex_2_object());
return Intersect_2(m_base_traits->intersect_2_object(),
m_base_traits->compare_xy_2_object(),
m_base_traits->construct_min_vertex_2_object());
}
@ -522,7 +524,7 @@ public:
/*! Get a Compare_endpoints_xy_2 functor object. */
Compare_endpoints_xy_2 compare_endpoints_xy_2_object() const
{
return Compare_endpoints_xy_2(m_base_tr->compare_endpoints_xy_2_object());
return Compare_endpoints_xy_2(m_base_traits->compare_endpoints_xy_2_object());
}
@ -545,7 +547,7 @@ public:
/*! Get a Construct_opposite_2 functor object. */
Construct_opposite_2 construct_opposite_2_object() const
{
return Construct_opposite_2(m_base_tr->construct_opposite_2_object());
return Construct_opposite_2(m_base_traits->construct_opposite_2_object());
}
};

View File

@ -35,6 +35,8 @@ public:
typedef typename Base::Point_2 Point_2;
typedef typename Base::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Base::Multiplicity Multiplicity;
//Polygon_2 type is required by GeneralPolygonSetTraits Concept
typedef General_polygon_t Polygon_2;
//Polygon_2 is a model of the GeneralPolygon2 concept