Used the traits adaptor for traits types (instead of the traits itself).

This commit is contained in:
Efi Fogel 2018-10-06 18:53:17 +03:00
parent 5afbc4985a
commit 2df88cb4de
1 changed files with 136 additions and 136 deletions

View File

@ -42,14 +42,14 @@ _construct_envelope_non_vertical(Curve_pointer_iterator begin,
Envelope_diagram_1& out_d) Envelope_diagram_1& out_d)
{ {
out_d.clear(); out_d.clear();
if (begin == end) if (begin == end)
return; return;
// Check if the range contains just a single curve. // Check if the range contains just a single curve.
Curve_pointer_iterator iter = begin; Curve_pointer_iterator iter = begin;
++iter; ++iter;
if (iter == end) if (iter == end)
{ {
// Construct a singleton diagram, which matches a single curve. // Construct a singleton diagram, which matches a single curve.
@ -61,14 +61,14 @@ _construct_envelope_non_vertical(Curve_pointer_iterator begin,
std::size_t size = std::distance(begin, end); std::size_t size = std::distance(begin, end);
Curve_pointer_iterator div_it = begin; Curve_pointer_iterator div_it = begin;
std::advance(div_it, size / 2); std::advance(div_it, size / 2);
// Construct the diagrams (envelopes) for the two sub-ranges recursively // Construct the diagrams (envelopes) for the two sub-ranges recursively
// and then merge the two diagrams to obtain the result. // and then merge the two diagrams to obtain the result.
Envelope_diagram_1 d1; Envelope_diagram_1 d1;
Envelope_diagram_1 d2; Envelope_diagram_1 d2;
_construct_envelope_non_vertical(begin, div_it, d1); _construct_envelope_non_vertical(begin, div_it, d1);
_construct_envelope_non_vertical(div_it, end, d2); _construct_envelope_non_vertical(div_it, end, d2);
_merge_envelopes(d1, d2, out_d); _merge_envelopes(d1, d2, out_d);
@ -88,13 +88,13 @@ _construct_envelope_non_vertical(Curve_pointer_iterator begin,
v = e->right(); v = e->right();
std::cout << "(" << v->point() << ") "; std::cout << "(" << v->point() << ") ";
e = v->right(); e = v->right();
} }
std::cout << "[empty]" << std::endl; std::cout << "[empty]" << std::endl;
*/ */
} }
return; return;
} }
@ -108,7 +108,7 @@ _construct_singleton_diagram(const X_monotone_curve_2& cv,
{ {
CGAL_assertion(out_d.leftmost() == out_d.rightmost()); CGAL_assertion(out_d.leftmost() == out_d.rightmost());
CGAL_assertion(out_d.leftmost()->is_empty()); CGAL_assertion(out_d.leftmost()->is_empty());
// Check if the given curve is bounded from the left and from the right. // Check if the given curve is bounded from the left and from the right.
if (traits->parameter_space_in_x_2_object()(cv, ARR_MIN_END) != ARR_INTERIOR) if (traits->parameter_space_in_x_2_object()(cv, ARR_MIN_END) != ARR_INTERIOR)
{ {
@ -117,7 +117,7 @@ _construct_singleton_diagram(const X_monotone_curve_2& cv,
// The curve is defined over (-oo, oo), so its diagram contains // The curve is defined over (-oo, oo), so its diagram contains
// only a single edge. // only a single edge.
out_d.leftmost()->add_curve(cv); out_d.leftmost()->add_curve(cv);
return; return;
} }
@ -125,50 +125,50 @@ _construct_singleton_diagram(const X_monotone_curve_2& cv,
// Create a vertex and associate it with the right endpoint of cv. // Create a vertex and associate it with the right endpoint of cv.
CGAL_precondition CGAL_precondition
(traits->parameter_space_in_y_2_object()(cv, ARR_MAX_END) == ARR_INTERIOR); (traits->parameter_space_in_y_2_object()(cv, ARR_MAX_END) == ARR_INTERIOR);
Vertex_handle v = Vertex_handle v =
out_d.new_vertex(traits->construct_max_vertex_2_object()(cv)); out_d.new_vertex(traits->construct_max_vertex_2_object()(cv));
Edge_handle e_right = out_d.new_edge(); Edge_handle e_right = out_d.new_edge();
v->add_curve(cv); v->add_curve(cv);
v->set_left(out_d.leftmost()); v->set_left(out_d.leftmost());
v->set_right(e_right); v->set_right(e_right);
// The leftmost edge is associated with cv, and the rightmost is empty. // The leftmost edge is associated with cv, and the rightmost is empty.
out_d.leftmost()->add_curve(cv); out_d.leftmost()->add_curve(cv);
out_d.leftmost()->set_right(v); out_d.leftmost()->set_right(v);
e_right->set_left(v); e_right->set_left(v);
out_d.set_rightmost(e_right); out_d.set_rightmost(e_right);
return; return;
} }
if (traits->parameter_space_in_x_2_object()(cv, ARR_MAX_END) != ARR_INTERIOR) if (traits->parameter_space_in_x_2_object()(cv, ARR_MAX_END) != ARR_INTERIOR)
{ {
// The curve is defined over [x, +oo), where x is finite. // The curve is defined over [x, +oo), where x is finite.
// Create a vertex and associate it with the left endpoint of cv. // Create a vertex and associate it with the left endpoint of cv.
CGAL_precondition CGAL_precondition
(traits->parameter_space_in_y_2_object()(cv, ARR_MIN_END) == ARR_INTERIOR); (traits->parameter_space_in_y_2_object()(cv, ARR_MIN_END) == ARR_INTERIOR);
Vertex_handle v = Vertex_handle v =
out_d.new_vertex(traits->construct_min_vertex_2_object()(cv)); out_d.new_vertex(traits->construct_min_vertex_2_object()(cv));
Edge_handle e_left = out_d.new_edge(); Edge_handle e_left = out_d.new_edge();
v->add_curve(cv); v->add_curve(cv);
v->set_left(e_left); v->set_left(e_left);
v->set_right(out_d.rightmost()); v->set_right(out_d.rightmost());
// The rightmost edge is associated with cv, and the leftmost is empty. // The rightmost edge is associated with cv, and the leftmost is empty.
out_d.rightmost()->add_curve(cv); out_d.rightmost()->add_curve(cv);
out_d.rightmost()->set_left(v); out_d.rightmost()->set_left(v);
e_left->set_right(v); e_left->set_right(v);
out_d.set_leftmost(e_left); out_d.set_leftmost(e_left);
return; return;
} }
// If we reached here, the curve is defined over a bounded x-range. // If we reached here, the curve is defined over a bounded x-range.
// We therefore create the following diagram: // We therefore create the following diagram:
// //
@ -179,33 +179,33 @@ _construct_singleton_diagram(const X_monotone_curve_2& cv,
(traits->parameter_space_in_y_2_object()(cv, ARR_MIN_END) == ARR_INTERIOR); (traits->parameter_space_in_y_2_object()(cv, ARR_MIN_END) == ARR_INTERIOR);
CGAL_precondition CGAL_precondition
(traits->parameter_space_in_y_2_object()(cv, ARR_MAX_END) == ARR_INTERIOR); (traits->parameter_space_in_y_2_object()(cv, ARR_MAX_END) == ARR_INTERIOR);
Vertex_handle v1 = Vertex_handle v1 =
out_d.new_vertex(traits->construct_min_vertex_2_object()(cv)); out_d.new_vertex(traits->construct_min_vertex_2_object()(cv));
Vertex_handle v2 = Vertex_handle v2 =
out_d.new_vertex(traits->construct_max_vertex_2_object()(cv)); out_d.new_vertex(traits->construct_max_vertex_2_object()(cv));
Edge_handle e_left = out_d.new_edge(); Edge_handle e_left = out_d.new_edge();
Edge_handle e_right = out_d.new_edge(); Edge_handle e_right = out_d.new_edge();
Edge_handle e = out_d.leftmost(); Edge_handle e = out_d.leftmost();
v1->add_curve(cv); v1->add_curve(cv);
v1->set_left(e_left); v1->set_left(e_left);
v1->set_right(e); v1->set_right(e);
v2->add_curve(cv); v2->add_curve(cv);
v2->set_left(e); v2->set_left(e);
v2->set_right(e_right); v2->set_right(e_right);
e->add_curve(cv); e->add_curve(cv);
e->set_left(v1); e->set_left(v1);
e->set_right(v2); e->set_right(v2);
e_left->set_right(v1); e_left->set_right(v1);
e_right->set_left(v2); e_right->set_left(v2);
out_d.set_leftmost(e_left); out_d.set_leftmost(e_left);
out_d.set_rightmost(e_right); out_d.set_rightmost(e_right);
return; return;
} }
@ -235,7 +235,7 @@ _merge_envelopes(const Envelope_diagram_1& d1,
// If both have the same x-ccordinate, find the one that should be in // If both have the same x-ccordinate, find the one that should be in
// the envelope. // the envelope.
same_x = false; same_x = false;
if (e1 == d1.rightmost()) if (e1 == d1.rightmost())
{ {
if (e2 == d2.rightmost()) if (e2 == d2.rightmost())
@ -265,14 +265,14 @@ _merge_envelopes(const Envelope_diagram_1& d1,
res_v = _compare_vertices(v1, v2, same_x); res_v = _compare_vertices(v1, v2, same_x);
next_v = (res_v == SMALLER) ? v1 : v2; next_v = (res_v == SMALLER) ? v1 : v2;
} }
// Check if the current edges represent empty intervals or not. // Check if the current edges represent empty intervals or not.
if (! e1->is_empty() && ! e2->is_empty()) if (! e1->is_empty() && ! e2->is_empty())
{ {
// Both edges are not empty, and there are curves defined on them. // Both edges are not empty, and there are curves defined on them.
_merge_two_intervals(e1, is_leftmost1, e2, is_leftmost2, _merge_two_intervals(e1, is_leftmost1, e2, is_leftmost2,
next_v, next_exists, res_v, out_d); next_v, next_exists, res_v, out_d);
} }
else if (! e1->is_empty() && e2->is_empty()) else if (! e1->is_empty() && e2->is_empty())
{ {
@ -304,7 +304,7 @@ _merge_envelopes(const Envelope_diagram_1& d1,
} }
} }
} }
// Proceed to the next diagram edge(s), if possible. // Proceed to the next diagram edge(s), if possible.
if (next_exists) if (next_exists)
{ {
@ -336,14 +336,14 @@ _merge_envelopes(const Envelope_diagram_1& d1,
{ {
e1 = v1->right(); e1 = v1->right();
is_leftmost1 = false; is_leftmost1 = false;
e2 = v2->right(); e2 = v2->right();
is_leftmost2 = false; is_leftmost2 = false;
} }
} }
} while (next_exists); } while (next_exists);
return; return;
} }
@ -358,7 +358,7 @@ _compare_vertices(Vertex_const_handle v1,
{ {
Comparison_result res = Comparison_result res =
traits->compare_x_2_object()(v1->point(), v2->point()); traits->compare_x_2_object()(v1->point(), v2->point());
if (res != EQUAL) if (res != EQUAL)
{ {
same_x = false; same_x = false;
@ -396,15 +396,15 @@ _merge_single_interval(Edge_const_handle e, Edge_const_handle other_edge,
out_d.rightmost()->add_curves(e->curves_begin(), e->curves_end()); out_d.rightmost()->add_curves(e->curves_begin(), e->curves_end());
return; return;
} }
Vertex_handle new_v; Vertex_handle new_v;
if (origin_of_v == SMALLER) if (origin_of_v == SMALLER)
{ {
// The non-empty edge ends at v, so we simply insert it to out_d. // The non-empty edge ends at v, so we simply insert it to out_d.
new_v = _append_vertex(out_d, v->point(), e); new_v = _append_vertex(out_d, v->point(), e);
new_v->add_curves(v->curves_begin(), v->curves_end()); new_v->add_curves(v->curves_begin(), v->curves_end());
return; return;
} }
@ -412,7 +412,7 @@ _merge_single_interval(Edge_const_handle e, Edge_const_handle other_edge,
{ {
new_v = _append_vertex(out_d, v->point(), e); new_v = _append_vertex(out_d, v->point(), e);
new_v->add_curves(e->right()->curves_begin(), e->right()->curves_end()); new_v->add_curves(e->right()->curves_begin(), e->right()->curves_end());
new_v->add_curves(other_edge->right()->curves_begin(), new_v->add_curves(other_edge->right()->curves_begin(),
other_edge->right()->curves_end()); other_edge->right()->curves_end());
return; return;
} }
@ -421,7 +421,7 @@ _merge_single_interval(Edge_const_handle e, Edge_const_handle other_edge,
// is below (or above, in case of an upper envelope) the curves of e. // is below (or above, in case of an upper envelope) the curves of e.
Comparison_result res = Comparison_result res =
traits->compare_y_at_x_2_object()(v->point(), e->curve()); traits->compare_y_at_x_2_object()(v->point(), e->curve());
if ((res == EQUAL) || if ((res == EQUAL) ||
(env_type == LOWER && res == SMALLER) || (env_type == LOWER && res == SMALLER) ||
(env_type == UPPER && res == LARGER)) (env_type == UPPER && res == LARGER))
@ -441,15 +441,15 @@ _merge_single_interval(Edge_const_handle e, Edge_const_handle other_edge,
/*@{*/ /*@{*/
//! Compare the $y$-coordinates of two curves at their endpoints //! Compare the $y$-coordinates of two curves at their endpoints
/*! The function compares the $y$ values of two curves with a joint /*! The function compares the $y$ values of two curves with a joint
range of $x$ values, at the end of the joint range. range of $x$ values, at the end of the joint range.
\param xcv1 The first curve \param xcv1 The first curve
\param xcv2 The second curve \param xcv2 The second curve
\param curve_end ARR_MIN_END - compare the $y$ value of the smaller \param curve_end ARR_MIN_END - compare the $y$ value of the smaller
endpoint, ARR_MAX_END - compare the $y$ value of the larger endpoint. endpoint, ARR_MAX_END - compare the $y$ value of the larger endpoint.
\pre The two $x$-monotone curves need to have a partially overlapping \pre The two $x$-monotone curves need to have a partially overlapping
$x$-ranges. $x$-ranges.
\return \return
\todo Move it to Arr_traits_adaptor ? \todo Move it to Arr_traits_adaptor ?
*/ */
template <class Traits, class Diagram> template <class Traits, class Diagram>
@ -460,7 +460,7 @@ compare_y_at_end(const X_monotone_curve_2& xcv1,
{ {
CGAL_precondition(traits->is_in_x_range_2_object()(xcv1, xcv2)); CGAL_precondition(traits->is_in_x_range_2_object()(xcv1, xcv2));
typedef typename Traits::Compare_xy_2 Compare_xy_2; typedef typename Traits_adaptor_2::Compare_xy_2 Compare_xy_2;
typedef typename Traits::Compare_y_at_x_2 Compare_y_at_x_2; typedef typename Traits::Compare_y_at_x_2 Compare_y_at_x_2;
typedef typename Traits::Construct_min_vertex_2 Construct_min_vertex_2; typedef typename Traits::Construct_min_vertex_2 Construct_min_vertex_2;
typedef typename Traits::Construct_max_vertex_2 Construct_max_vertex_2; typedef typename Traits::Construct_max_vertex_2 Construct_max_vertex_2;
@ -470,30 +470,30 @@ compare_y_at_end(const X_monotone_curve_2& xcv1,
traits->construct_min_vertex_2_object(); traits->construct_min_vertex_2_object();
Construct_max_vertex_2 max_vertex = Construct_max_vertex_2 max_vertex =
traits->construct_max_vertex_2_object(); traits->construct_max_vertex_2_object();
// First check whether any of the curves is defined at x boundary. // First check whether any of the curves is defined at x boundary.
const Arr_parameter_space ps_x1 = const Arr_parameter_space ps_x1 =
traits->parameter_space_in_x_2_object()(xcv1, curve_end); traits->parameter_space_in_x_2_object()(xcv1, curve_end);
const Arr_parameter_space ps_x2 = const Arr_parameter_space ps_x2 =
traits->parameter_space_in_x_2_object()(xcv2, curve_end); traits->parameter_space_in_x_2_object()(xcv2, curve_end);
Comparison_result res; Comparison_result res;
if (ps_x1 != ARR_INTERIOR) { if (ps_x1 != ARR_INTERIOR) {
if (ps_x2 != ARR_INTERIOR) { if (ps_x2 != ARR_INTERIOR) {
// Compare the relative position of the curves at x boundary. // Compare the relative position of the curves at x boundary.
return (traits->compare_y_near_boundary_2_object()(xcv1, xcv2, return (traits->compare_y_near_boundary_2_object()(xcv1, xcv2,
curve_end)); curve_end));
} }
// Check if the left end of xcv2 lies at y boundary. // Check if the left end of xcv2 lies at y boundary.
const Arr_parameter_space ps_y2 = const Arr_parameter_space ps_y2 =
traits->parameter_space_in_y_2_object()(xcv2, curve_end); traits->parameter_space_in_y_2_object()(xcv2, curve_end);
if (ps_y2 == ARR_BOTTOM_BOUNDARY) if (ps_y2 == ARR_BOTTOM_BOUNDARY)
return (LARGER); // xcv2 is obviously below xcv1. return (LARGER); // xcv2 is obviously below xcv1.
else if (ps_y2 == ARR_TOP_BOUNDARY) else if (ps_y2 == ARR_TOP_BOUNDARY)
return (SMALLER); // xcv2 is obviously above xcv1. return (SMALLER); // xcv2 is obviously above xcv1.
// Compare the position of the left end of xcv2 (which is a normal // Compare the position of the left end of xcv2 (which is a normal
// point) to xcv1. // point) to xcv1.
res = (curve_end == ARR_MIN_END) ? res = (curve_end == ARR_MIN_END) ?
@ -507,12 +507,12 @@ compare_y_at_end(const X_monotone_curve_2& xcv1,
// Check if the left end of xcv1 lies at y boundary. // Check if the left end of xcv1 lies at y boundary.
const Arr_parameter_space ps_y1 = traits->parameter_space_in_y_2_object() const Arr_parameter_space ps_y1 = traits->parameter_space_in_y_2_object()
(xcv1, curve_end); (xcv1, curve_end);
if (ps_y1 == ARR_BOTTOM_BOUNDARY) if (ps_y1 == ARR_BOTTOM_BOUNDARY)
return (SMALLER); // xcv1 is obviously below xcv2. return (SMALLER); // xcv1 is obviously below xcv2.
else if (ps_y1 == ARR_TOP_BOUNDARY) else if (ps_y1 == ARR_TOP_BOUNDARY)
return (LARGER); // xcv1 is obviously above xcv2. return (LARGER); // xcv1 is obviously above xcv2.
// Compare the position of the left end of xcv1 (which is a normal // Compare the position of the left end of xcv1 (which is a normal
// point) to xcv2. // point) to xcv2.
res = (curve_end == ARR_MIN_END) ? res = (curve_end == ARR_MIN_END) ?
@ -520,14 +520,14 @@ compare_y_at_end(const X_monotone_curve_2& xcv1,
compare_y_at_x(max_vertex(xcv1), xcv2); compare_y_at_x(max_vertex(xcv1), xcv2);
return (res); return (res);
} }
// Check if the left curve end lies at y = +/- oo. // Check if the left curve end lies at y = +/- oo.
const Arr_parameter_space ps_y1 = const Arr_parameter_space ps_y1 =
traits->parameter_space_in_y_2_object()(xcv1, curve_end); traits->parameter_space_in_y_2_object()(xcv1, curve_end);
const Arr_parameter_space ps_y2 = const Arr_parameter_space ps_y2 =
traits->parameter_space_in_y_2_object()(xcv2, curve_end); traits->parameter_space_in_y_2_object()(xcv2, curve_end);
Comparison_result l_res; Comparison_result l_res;
if (ps_y1 != ARR_INTERIOR) { if (ps_y1 != ARR_INTERIOR) {
if (ps_y2 != ARR_INTERIOR) { if (ps_y2 != ARR_INTERIOR) {
// The curve ends have boundary conditions with oposite signs in y, // The curve ends have boundary conditions with oposite signs in y,
@ -544,7 +544,7 @@ compare_y_at_end(const X_monotone_curve_2& xcv1,
l_res = traits->compare_x_curve_ends_2_object()(xcv1, curve_end, l_res = traits->compare_x_curve_ends_2_object()(xcv1, curve_end,
xcv2, curve_end); xcv2, curve_end);
CGAL_assertion(l_res != EQUAL); CGAL_assertion(l_res != EQUAL);
if (ps_y1 == ARR_TOP_BOUNDARY) if (ps_y1 == ARR_TOP_BOUNDARY)
return (l_res); return (l_res);
else else
@ -555,10 +555,10 @@ compare_y_at_end(const X_monotone_curve_2& xcv1,
// Compare the x-positions of this endpoint and the asymptote. // Compare the x-positions of this endpoint and the asymptote.
const Point_2& left2 = const Point_2& left2 =
(curve_end == ARR_MIN_END) ? min_vertex(xcv2) : max_vertex(xcv2); (curve_end == ARR_MIN_END) ? min_vertex(xcv2) : max_vertex(xcv2);
l_res = l_res =
traits->compare_x_point_curve_end_2_object()(left2, xcv1, curve_end); traits->compare_x_point_curve_end_2_object()(left2, xcv1, curve_end);
if (l_res == LARGER) { if (l_res == LARGER) {
// left2 lies in the x-range of xcv1, so it is safe to compare: // left2 lies in the x-range of xcv1, so it is safe to compare:
res = compare_y_at_x(left2, xcv1); res = compare_y_at_x(left2, xcv1);
@ -571,12 +571,12 @@ compare_y_at_end(const X_monotone_curve_2& xcv1,
else if (ps_y2 != ARR_INTERIOR) { else if (ps_y2 != ARR_INTERIOR) {
// xcv2 has a vertical asymptote and xcv1 has a normal left endpoint. // xcv2 has a vertical asymptote and xcv1 has a normal left endpoint.
// Compare the x-positions of this endpoint and the asymptote. // Compare the x-positions of this endpoint and the asymptote.
const Point_2& left1 = const Point_2& left1 =
(curve_end == ARR_MIN_END) ? min_vertex(xcv1) : max_vertex(xcv1); (curve_end == ARR_MIN_END) ? min_vertex(xcv1) : max_vertex(xcv1);
l_res = l_res =
traits->compare_x_point_curve_end_2_object()(left1, xcv2, curve_end); traits->compare_x_point_curve_end_2_object()(left1, xcv2, curve_end);
return ((l_res == LARGER) ? return ((l_res == LARGER) ?
// left1 lies in the x-range of xcv2, so it is safe to compare: // left1 lies in the x-range of xcv2, so it is safe to compare:
(compare_y_at_x(left1, xcv2)) : (compare_y_at_x(left1, xcv2)) :
@ -584,21 +584,21 @@ compare_y_at_end(const X_monotone_curve_2& xcv1,
} }
// In this case we compare two normal points. // In this case we compare two normal points.
Compare_xy_2 compare_xy = traits->compare_xy_2_object(); Compare_xy_2 compare_xy = traits->compare_xy_2_object();
// Get the left endpoints of xcv1 and xcv2. // Get the left endpoints of xcv1 and xcv2.
const Point_2& left1 = const Point_2& left1 =
(curve_end == ARR_MIN_END) ? min_vertex(xcv1) : max_vertex(xcv1); (curve_end == ARR_MIN_END) ? min_vertex(xcv1) : max_vertex(xcv1);
const Point_2& left2 = const Point_2& left2 =
(curve_end == ARR_MIN_END) ? min_vertex(xcv2) : max_vertex(xcv2); (curve_end == ARR_MIN_END) ? min_vertex(xcv2) : max_vertex(xcv2);
// Locate the rightmost point of left1 and left2 and compare its position // Locate the rightmost point of left1 and left2 and compare its position
// to the other curve. // to the other curve.
l_res = compare_xy(left1, left2); l_res = compare_xy(left1, left2);
return ((l_res != SMALLER) ? return ((l_res != SMALLER) ?
// left1 is in the x-range of xcv2: // left1 is in the x-range of xcv2:
compare_y_at_x(left1, xcv2) : compare_y_at_x(left1, xcv2) :
// left2 is in the x-range of xcv1: // left2 is in the x-range of xcv1:
CGAL::opposite(compare_y_at_x(left2, xcv1))); CGAL::opposite(compare_y_at_x(left2, xcv1)));
} }
@ -609,7 +609,7 @@ compare_y_at_end(const X_monotone_curve_2& xcv1,
// //
template <class Traits, class Diagram> template <class Traits, class Diagram>
void Envelope_divide_and_conquer_2<Traits,Diagram>:: void Envelope_divide_and_conquer_2<Traits,Diagram>::
_merge_two_intervals(Edge_const_handle e1, bool is_leftmost1, _merge_two_intervals(Edge_const_handle e1, bool is_leftmost1,
Edge_const_handle e2, bool is_leftmost2, Edge_const_handle e2, bool is_leftmost2,
Vertex_const_handle v, bool v_exists, Vertex_const_handle v, bool v_exists,
Comparison_result origin_of_v, Comparison_result origin_of_v,
@ -619,7 +619,7 @@ _merge_two_intervals(Edge_const_handle e1, bool is_leftmost1,
Comparison_result current_res; Comparison_result current_res;
bool equal_at_v = false; bool equal_at_v = false;
// Get the relative position of two curves associated with e1 and e2 // Get the relative position of two curves associated with e1 and e2
// at the rightmost of the left endpoints of e1 and e2. // at the rightmost of the left endpoints of e1 and e2.
current_res = compare_y_at_end(e1->curve(), e2->curve(), ARR_MIN_END); current_res = compare_y_at_end(e1->curve(), e2->curve(), ARR_MIN_END);
@ -659,24 +659,24 @@ _merge_two_intervals(Edge_const_handle e1, bool is_leftmost1,
CGAL::Object obj; CGAL::Object obj;
const X_monotone_curve_2* intersection_curve; const X_monotone_curve_2* intersection_curve;
const Intersection_point* intersection_point; const Intersection_point* intersection_point;
traits->intersect_2_object()(e1->curve(), e2->curve(), traits->intersect_2_object()(e1->curve(), e2->curve(),
std::back_inserter(objects)); std::back_inserter(objects));
while (! objects.empty()) { while (! objects.empty()) {
// Pop the xy-lexicographically smallest intersection object. // Pop the xy-lexicographically smallest intersection object.
obj = objects.front(); obj = objects.front();
objects.pop_front(); objects.pop_front();
if ((intersection_point = CGAL::object_cast<Intersection_point>(&obj)) != if ((intersection_point = CGAL::object_cast<Intersection_point>(&obj)) !=
NULL) NULL)
{ {
// We have a simple intersection point. // We have a simple intersection point.
bool is_in_x_range = true; // true if the intersection point is to the bool is_in_x_range = true; // true if the intersection point is to the
// right of v_leftmost. // right of v_leftmost.
// check if we are before the leftmost point. // check if we are before the leftmost point.
if (v_leftmost && if (v_leftmost &&
traits->compare_xy_2_object() (intersection_point->first, traits->compare_xy_2_object() (intersection_point->first,
(*v_leftmost)->point()) != LARGER) (*v_leftmost)->point()) != LARGER)
{ {
// The point is to the left of the current rightmost vertex in out_d, // The point is to the left of the current rightmost vertex in out_d,
@ -684,22 +684,22 @@ _merge_two_intervals(Edge_const_handle e1, bool is_leftmost1,
// However, we update the last intersection point observed. // However, we update the last intersection point observed.
is_in_x_range = false; is_in_x_range = false;
} }
// check if we arrived at the rightmost point (stop if indeed we are // check if we arrived at the rightmost point (stop if indeed we are
// there). // there).
if (is_in_x_range && v_exists) { if (is_in_x_range && v_exists) {
Comparison_result res = traits->compare_xy_2_object() Comparison_result res = traits->compare_xy_2_object()
(intersection_point->first, v->point()); (intersection_point->first, v->point());
// v is an intersection points, so both curves are equal there: // v is an intersection points, so both curves are equal there:
if (res == EQUAL) if (res == EQUAL)
equal_at_v = true; equal_at_v = true;
// We passed the next vertex, so we can stop here. // We passed the next vertex, so we can stop here.
if (res == LARGER) if (res == LARGER)
break; break;
} }
// Create a new vertex in the output diagram that corrsponds to the // Create a new vertex in the output diagram that corrsponds to the
// current intersection point. // current intersection point.
if (is_in_x_range) { if (is_in_x_range) {
@ -708,7 +708,7 @@ _merge_two_intervals(Edge_const_handle e1, bool is_leftmost1,
Vertex_handle new_v = (current_res == SMALLER) ? Vertex_handle new_v = (current_res == SMALLER) ?
_append_vertex(out_d, intersection_point->first, e1) : _append_vertex(out_d, intersection_point->first, e1) :
_append_vertex(out_d, intersection_point->first, e2); _append_vertex(out_d, intersection_point->first, e2);
// if we are at v, then this is a special case that is handled after // if we are at v, then this is a special case that is handled after
// the loop. We need to add the curves from the original vertices. // the loop. We need to add the curves from the original vertices.
if (equal_at_v == false) { if (equal_at_v == false) {
@ -716,7 +716,7 @@ _merge_two_intervals(Edge_const_handle e1, bool is_leftmost1,
new_v->add_curves(e1->curves_begin(), e1->curves_end()); new_v->add_curves(e1->curves_begin(), e1->curves_end());
new_v->add_curves(e2->curves_begin(), e2->curves_end()); new_v->add_curves(e2->curves_begin(), e2->curves_end());
} }
// Update the handle to the rightmost vertex in the output diagram. // Update the handle to the rightmost vertex in the output diagram.
v_leftmost = new_v; v_leftmost = new_v;
} }
@ -724,7 +724,7 @@ _merge_two_intervals(Edge_const_handle e1, bool is_leftmost1,
// Update the relative position of the two curves, which is their // Update the relative position of the two curves, which is their
// order immediately to the right of their last observed intersection // order immediately to the right of their last observed intersection
// point. // point.
// Get the curve order immediately to the right of the intersection // Get the curve order immediately to the right of the intersection
// point. Note that in case of even (non-zero) multiplicity the order // point. Note that in case of even (non-zero) multiplicity the order
// remains the same. // remains the same.
@ -750,22 +750,22 @@ _merge_two_intervals(Edge_const_handle e1, bool is_leftmost1,
// We have an x-monotone curve representing an overlap of the two // We have an x-monotone curve representing an overlap of the two
// curves. // curves.
intersection_curve = CGAL::object_cast<X_monotone_curve_2>(&obj); intersection_curve = CGAL::object_cast<X_monotone_curve_2>(&obj);
if (intersection_curve == NULL) if (intersection_curve == NULL)
CGAL_error_msg("unrecognized intersection object."); CGAL_error_msg("unrecognized intersection object.");
// Get the endpoints of the overlapping curves. // Get the endpoints of the overlapping curves.
const bool has_left = const bool has_left =
(traits->parameter_space_in_x_2_object() (traits->parameter_space_in_x_2_object()
(*intersection_curve, ARR_MIN_END) == ARR_INTERIOR); (*intersection_curve, ARR_MIN_END) == ARR_INTERIOR);
const bool has_right = const bool has_right =
(traits->parameter_space_in_x_2_object() (traits->parameter_space_in_x_2_object()
(*intersection_curve, ARR_MAX_END) == ARR_INTERIOR); (*intersection_curve, ARR_MAX_END) == ARR_INTERIOR);
Point_2 p_left, p_right; Point_2 p_left, p_right;
if (has_left) if (has_left)
p_left = traits->construct_min_vertex_2_object()(*intersection_curve); p_left = traits->construct_min_vertex_2_object()(*intersection_curve);
if (has_right) if (has_right)
p_right = traits->construct_max_vertex_2_object()(*intersection_curve); p_right = traits->construct_max_vertex_2_object()(*intersection_curve);
@ -781,22 +781,22 @@ _merge_two_intervals(Edge_const_handle e1, bool is_leftmost1,
// However, we update the last intersection point observed. // However, we update the last intersection point observed.
is_in_x_range = false; is_in_x_range = false;
} }
if (is_in_x_range && v_exists && has_left) { if (is_in_x_range && v_exists && has_left) {
Comparison_result res = Comparison_result res =
traits->compare_xy_2_object()(p_left, v->point()); traits->compare_xy_2_object()(p_left, v->point());
// v is an intersection points, so both curves are equal there: // v is an intersection points, so both curves are equal there:
if (res == EQUAL) if (res == EQUAL)
equal_at_v = true; equal_at_v = true;
// We passed the next vertex, so we can stop here. // We passed the next vertex, so we can stop here.
if (res == LARGER) if (res == LARGER)
break; break;
} }
// There is an overlap between the range [u, v] and intersection_curve. // There is an overlap between the range [u, v] and intersection_curve.
if (is_in_x_range && has_left && if (is_in_x_range && has_left &&
(! v_leftmost || (! v_leftmost ||
(traits->compare_xy_2_object()(p_left, (*v_leftmost)->point()) == (traits->compare_xy_2_object()(p_left, (*v_leftmost)->point()) ==
LARGER))) LARGER)))
@ -808,7 +808,7 @@ _merge_two_intervals(Edge_const_handle e1, bool is_leftmost1,
Vertex_handle new_v = (current_res == SMALLER) ? Vertex_handle new_v = (current_res == SMALLER) ?
_append_vertex(out_d, p_left, e1) : _append_vertex(out_d, p_left, e1) :
_append_vertex(out_d, p_left, e2); _append_vertex(out_d, p_left, e2);
// if we are at v, then this is a special case that is handled after // if we are at v, then this is a special case that is handled after
// the loop. We need to add the curves from the original vertices. // the loop. We need to add the curves from the original vertices.
if (equal_at_v == false) { if (equal_at_v == false) {
@ -817,11 +817,11 @@ _merge_two_intervals(Edge_const_handle e1, bool is_leftmost1,
new_v->add_curves(e1->curves_begin(), e1->curves_end()); new_v->add_curves(e1->curves_begin(), e1->curves_end());
new_v->add_curves(e2->curves_begin(), e2->curves_end()); new_v->add_curves(e2->curves_begin(), e2->curves_end());
} }
// Update the handle to the rightmost vertex in the output diagram. // Update the handle to the rightmost vertex in the output diagram.
v_leftmost = new_v; v_leftmost = new_v;
} }
if (is_in_x_range && has_right && if (is_in_x_range && has_right &&
(! v_exists || (! v_exists ||
(traits->compare_xy_2_object()(p_right, v->point()) == SMALLER))) (traits->compare_xy_2_object()(p_right, v->point()) == SMALLER)))
@ -829,7 +829,7 @@ _merge_two_intervals(Edge_const_handle e1, bool is_leftmost1,
// Create an edge that represents the overlapping curve. // Create an edge that represents the overlapping curve.
Vertex_handle new_v = _append_vertex(out_d, p_right, e1); Vertex_handle new_v = _append_vertex(out_d, p_right, e1);
new_v->left()->add_curves(e2->curves_begin(), e2->curves_end()); new_v->left()->add_curves(e2->curves_begin(), e2->curves_end());
// We are not at v becuase p_right is smaller than v. // We are not at v becuase p_right is smaller than v.
// The special case that we are at v is handled in the next // The special case that we are at v is handled in the next
// condition. // condition.
@ -838,12 +838,12 @@ _merge_two_intervals(Edge_const_handle e1, bool is_leftmost1,
CGAL_assertion(equal_at_v == false); CGAL_assertion(equal_at_v == false);
new_v->add_curves(e1->curves_begin(), e1->curves_end()); new_v->add_curves(e1->curves_begin(), e1->curves_end());
new_v->add_curves(e2->curves_begin(), e2->curves_end()); new_v->add_curves(e2->curves_begin(), e2->curves_end());
// Update the handle to the rightmost vertex in the output diagram. // Update the handle to the rightmost vertex in the output diagram.
v_leftmost = new_v; v_leftmost = new_v;
} }
if (has_right == false || if (has_right == false ||
(v_exists && traits->compare_xy_2_object()(p_right, v->point()) != (v_exists && traits->compare_xy_2_object()(p_right, v->point()) !=
SMALLER)) SMALLER))
{ {
@ -852,7 +852,7 @@ _merge_two_intervals(Edge_const_handle e1, bool is_leftmost1,
Vertex_handle new_v = _append_vertex(out_d, v->point(), e1); Vertex_handle new_v = _append_vertex(out_d, v->point(), e1);
new_v->left()->add_curves(e2->curves_begin(), e2->curves_end()); new_v->left()->add_curves(e2->curves_begin(), e2->curves_end());
} }
equal_at_v = true; equal_at_v = true;
current_res = EQUAL; current_res = EQUAL;
break; break;
@ -867,7 +867,7 @@ _merge_two_intervals(Edge_const_handle e1, bool is_leftmost1,
// Flip the result in case of an upper envelope. // Flip the result in case of an upper envelope.
if (env_type == UPPER) if (env_type == UPPER)
current_res = CGAL::opposite (current_res); current_res = CGAL::opposite (current_res);
} }
} // End of the traversal over the intersection objects. } // End of the traversal over the intersection objects.
@ -883,11 +883,11 @@ _merge_two_intervals(Edge_const_handle e1, bool is_leftmost1,
Vertex_handle v_to_be_updated = out_d.rightmost()->left(); Vertex_handle v_to_be_updated = out_d.rightmost()->left();
if (origin_of_v == EQUAL) { if (origin_of_v == EQUAL) {
// If the vertices of the edge are the same, we have to get the // If the vertices of the edge are the same, we have to get the
// curves from there: // curves from there:
v_to_be_updated->add_curves(e1->right()->curves_begin(), v_to_be_updated->add_curves(e1->right()->curves_begin(),
e1->right()->curves_end()); e1->right()->curves_end());
v_to_be_updated->add_curves(e2->right()->curves_begin(), v_to_be_updated->add_curves(e2->right()->curves_begin(),
e2->right()->curves_end()); e2->right()->curves_end());
} }
else { else {
@ -898,10 +898,10 @@ _merge_two_intervals(Edge_const_handle e1, bool is_leftmost1,
v_to_be_updated->add_curves (v->curves_begin(), v->curves_end()); v_to_be_updated->add_curves (v->curves_begin(), v->curves_end());
v_to_be_updated->add_curves (e->curves_begin(), e->curves_end()); v_to_be_updated->add_curves (e->curves_begin(), e->curves_end());
} }
return; return;
} }
if (! v_exists) { if (! v_exists) {
// Both edges are unbounded from the right, so we simply have // Both edges are unbounded from the right, so we simply have
// to update the rightmost edge in out_d. // to update the rightmost edge in out_d.
@ -930,9 +930,9 @@ _merge_two_intervals(Edge_const_handle e1, bool is_leftmost1,
// For example: // For example:
// First diagram is the segment: [(0, -1), (1, 0)] // First diagram is the segment: [(0, -1), (1, 0)]
// Second diagram of the two segments: [(0, 0), (1, 1)], [(1, 0), (2, 1)] // Second diagram of the two segments: [(0, 0), (1, 1)], [(1, 0), (2, 1)]
// Check if we need to insert v into the diagram. // Check if we need to insert v into the diagram.
if (current_res == SMALLER) { if (current_res == SMALLER) {
// The final part of the interval is taken from e1. // The final part of the interval is taken from e1.
Vertex_handle new_v; Vertex_handle new_v;
@ -947,25 +947,25 @@ _merge_two_intervals(Edge_const_handle e1, bool is_leftmost1,
if (origin_of_v == EQUAL) { if (origin_of_v == EQUAL) {
new_v = _append_vertex(out_d, v->point(), e1); new_v = _append_vertex(out_d, v->point(), e1);
new_v->add_curves(v->curves_begin(), v->curves_end()); new_v->add_curves(v->curves_begin(), v->curves_end());
// adding the curves of the vertex of the first diagram (vertices are // adding the curves of the vertex of the first diagram (vertices are
// equal...) // equal...)
new_v->add_curves(e1->right()->curves_begin(), new_v->add_curves(e1->right()->curves_begin(),
e1->right()->curves_end()); e1->right()->curves_end());
} }
else { else {
// If v is from e2, check if it below (or above, in case of an upper // If v is from e2, check if it below (or above, in case of an upper
// envelope) cv1 to insert it. // envelope) cv1 to insert it.
const Comparison_result res = const Comparison_result res =
traits->compare_y_at_x_2_object()(v->point(), e1->curve()); traits->compare_y_at_x_2_object()(v->point(), e1->curve());
if (res == EQUAL || if (res == EQUAL ||
((env_type == LOWER) && (res == SMALLER)) || ((env_type == LOWER) && (res == SMALLER)) ||
((env_type == UPPER) && (res == LARGER))) ((env_type == UPPER) && (res == LARGER)))
{ {
new_v = _append_vertex(out_d, v->point(), e1); new_v = _append_vertex(out_d, v->point(), e1);
new_v->add_curves(v->curves_begin(), v->curves_end()); new_v->add_curves(v->curves_begin(), v->curves_end());
if (res == EQUAL) if (res == EQUAL)
new_v->add_curves(e1->curves_begin(), e1->curves_end()); new_v->add_curves(e1->curves_begin(), e1->curves_end());
} }
@ -980,7 +980,7 @@ _merge_two_intervals(Edge_const_handle e1, bool is_leftmost1,
// In case v is also from e2, append it to the merged diagram. // In case v is also from e2, append it to the merged diagram.
new_v = _append_vertex(out_d, v->point(), e2); new_v = _append_vertex(out_d, v->point(), e2);
new_v->add_curves(v->curves_begin(), v->curves_end()); new_v->add_curves(v->curves_begin(), v->curves_end());
// if origin_of_v is EQUAL then the two diagram have a vertex at // if origin_of_v is EQUAL then the two diagram have a vertex at
// exact same place. // exact same place.
if (origin_of_v == EQUAL) { if (origin_of_v == EQUAL) {
@ -993,16 +993,16 @@ _merge_two_intervals(Edge_const_handle e1, bool is_leftmost1,
else { else {
// If v is from e1, check if it below (or above, in case of an upper // If v is from e1, check if it below (or above, in case of an upper
// envelope) cv2 to insert it. // envelope) cv2 to insert it.
const Comparison_result res = const Comparison_result res =
traits->compare_y_at_x_2_object()(v->point(), e2->curve()); traits->compare_y_at_x_2_object()(v->point(), e2->curve());
if (res == EQUAL || if (res == EQUAL ||
((env_type == LOWER) && (res == SMALLER)) || ((env_type == LOWER) && (res == SMALLER)) ||
((env_type == UPPER) && (res == LARGER))) ((env_type == UPPER) && (res == LARGER)))
{ {
new_v = _append_vertex(out_d, v->point(), e2); new_v = _append_vertex(out_d, v->point(), e2);
new_v->add_curves(v->curves_begin(), v->curves_end()); new_v->add_curves(v->curves_begin(), v->curves_end());
if (res == EQUAL) if (res == EQUAL)
new_v->add_curves(e2->curves_begin(), e2->curves_end()); new_v->add_curves(e2->curves_begin(), e2->curves_end());
} }
@ -1024,14 +1024,14 @@ _append_vertex(Envelope_diagram_1& diag,
// Create the new vertex and the new edge. // Create the new vertex and the new edge.
Vertex_handle new_v = diag.new_vertex(p); Vertex_handle new_v = diag.new_vertex(p);
Edge_handle new_e = diag.new_edge(); Edge_handle new_e = diag.new_edge();
if (! e->is_empty()) if (! e->is_empty())
new_e->add_curves(e->curves_begin(), e->curves_end()); new_e->add_curves(e->curves_begin(), e->curves_end());
// Connect the new vertex. // Connect the new vertex.
new_v->set_left(new_e); new_v->set_left(new_e);
new_v->set_right(diag.rightmost()); new_v->set_right(diag.rightmost());
if (diag.leftmost() != diag.rightmost()) { if (diag.leftmost() != diag.rightmost()) {
// The diagram is not empty. Connect the new edge to the left of the // The diagram is not empty. Connect the new edge to the left of the
// rightmost edge of the diagram. // rightmost edge of the diagram.
@ -1044,18 +1044,18 @@ _append_vertex(Envelope_diagram_1& diag,
// The diagram is empty: Make the new edge the leftmost. // The diagram is empty: Make the new edge the leftmost.
new_e->set_right(new_v); new_e->set_right(new_v);
diag.set_leftmost(new_e); diag.set_leftmost(new_e);
diag.rightmost()->set_left(new_v); diag.rightmost()->set_left(new_v);
} }
return (new_v); return (new_v);
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Merge the vertical segments into the envelope given as a minimization // Merge the vertical segments into the envelope given as a minimization
// (or maximization) diagram. // (or maximization) diagram.
// //
template <class Traits, class Diagram> template <class Traits, class Diagram>
void Envelope_divide_and_conquer_2<Traits,Diagram>:: void Envelope_divide_and_conquer_2<Traits, Diagram>::
_merge_vertical_segments(Curve_pointer_vector& vert_vec, _merge_vertical_segments(Curve_pointer_vector& vert_vec,
Envelope_diagram_1& out_d) Envelope_diagram_1& out_d)
{ {
@ -1104,7 +1104,7 @@ _merge_vertical_segments(Curve_pointer_vector& vert_vec,
in_e_range = true; in_e_range = true;
on_v = false; on_v = false;
} }
// If the current vertical segment is not in the x-range of the current // If the current vertical segment is not in the x-range of the current
// edge, we proceed to the next edge. // edge, we proceed to the next edge.
if (! in_e_range) { if (! in_e_range) {
@ -1114,7 +1114,7 @@ _merge_vertical_segments(Curve_pointer_vector& vert_vec,
// Go over all vertical segments that share the same x-coordinate and // Go over all vertical segments that share the same x-coordinate and
// find the one(s) with the smallest endpoint (or largest endpoint, if // find the one(s) with the smallest endpoint (or largest endpoint, if
// we construct an upper envelope). // we construct an upper envelope).
std::list<X_monotone_curve_2> env_cvs; std::list<X_monotone_curve_2> env_cvs;
env_cvs.push_back(**iter); env_cvs.push_back(**iter);
@ -1189,7 +1189,7 @@ _merge_vertical_segments(Curve_pointer_vector& vert_vec,
else { else {
// Compare p with the current curve. // Compare p with the current curve.
res = comp_y_at_x(p, e->curve()); res = comp_y_at_x(p, e->curve());
if (((env_type == LOWER) && (res != LARGER)) || if (((env_type == LOWER) && (res != LARGER)) ||
((env_type == UPPER) && (res != SMALLER))) ((env_type == UPPER) && (res != SMALLER)))
{ {
@ -1220,15 +1220,15 @@ _split_edge(Envelope_diagram_1& diag, const Point_2& p, Edge_handle e)
// Create the new vertex and the new edge. // Create the new vertex and the new edge.
Vertex_handle new_v = diag.new_vertex(p); Vertex_handle new_v = diag.new_vertex(p);
Edge_handle new_e = diag.new_edge(); Edge_handle new_e = diag.new_edge();
// Duplicate the curves container associated with e. // Duplicate the curves container associated with e.
if (! e->is_empty()) if (! e->is_empty())
new_e->add_curves(e->curves_begin(), e->curves_end()); new_e->add_curves(e->curves_begin(), e->curves_end());
// Connect the new vertex between e and new_e. // Connect the new vertex between e and new_e.
new_v->set_left(e); new_v->set_left(e);
new_v->set_right(new_e); new_v->set_right(new_e);
new_e->set_left(new_v); new_e->set_left(new_v);
if (e != diag.rightmost()) if (e != diag.rightmost())
new_e->set_right(e->right()); new_e->set_right(e->right());