review by guy

This commit is contained in:
Ophir Setter 2009-05-11 16:07:34 +00:00
parent 9087e9b14b
commit f5d6872d01
1 changed files with 47 additions and 48 deletions

View File

@ -649,14 +649,13 @@ _merge_two_intervals (Edge_const_handle e1, bool is_leftmost1,
Comparison_result origin_of_v, Comparison_result origin_of_v,
Envelope_diagram_1& out_d) Envelope_diagram_1& out_d)
{ {
// Get the relative position of two curves associated with e1 and e2 typedef std::pair<Point_2, typename Traits::Multiplicity> Intersection_point;
// at the rightmost of the left endpoints of e1 and e2.
Comparison_result current_res; Comparison_result current_res;
bool equal_at_v = false; bool equal_at_v = false;
boost::optional<Point_2> last_ip; // last observed intersetion point.
// Get the relative position of two curves associated with e1 and e2
// This function needs a review. // 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);
// 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)
@ -693,8 +692,8 @@ _merge_two_intervals (Edge_const_handle e1, bool is_leftmost1,
// \todo Use the faster object_cast. // \todo Use the faster object_cast.
std::list<CGAL::Object> objects; std::list<CGAL::Object> objects;
CGAL::Object obj; CGAL::Object obj;
X_monotone_curve_2 intersection_curve; const X_monotone_curve_2* intersection_curve;
std::pair<Point_2, typename Traits::Multiplicity> 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));
@ -705,14 +704,15 @@ _merge_two_intervals (Edge_const_handle e1, bool is_leftmost1,
obj = objects.front(); obj = objects.front();
objects.pop_front(); objects.pop_front();
if (CGAL::assign(intersection_point, obj)) if ((intersection_point = CGAL::object_cast<Intersection_point>(&obj))
!= 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,
@ -726,7 +726,7 @@ _merge_two_intervals (Edge_const_handle e1, bool is_leftmost1,
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)
@ -734,9 +734,7 @@ _merge_two_intervals (Edge_const_handle e1, bool is_leftmost1,
// 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
@ -745,10 +743,12 @@ _merge_two_intervals (Edge_const_handle e1, bool is_leftmost1,
{ {
Vertex_handle new_v; Vertex_handle new_v;
CGAL_assertion(current_res != EQUAL);
if (current_res == SMALLER) if (current_res == SMALLER)
new_v = _append_vertex (out_d, intersection_point.first, e1); new_v = _append_vertex (out_d, intersection_point->first, e1);
else else
new_v = _append_vertex (out_d, intersection_point.first, e2); new_v = _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.
@ -765,17 +765,18 @@ _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 last_ip. // 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.
if (current_res != EQUAL && intersection_point.second % 2 == 1) if (current_res != EQUAL && intersection_point->second % 2 == 1)
{ {
// Odd multiplicity: flip the current comparison result. // Odd multiplicity: flip the current comparison result.
current_res = CGAL::opposite (current_res); current_res = CGAL::opposite (current_res);
} }
else if ((intersection_point.second == 0 || current_res == EQUAL) // if we are at v, then we may not be able to call compare_y_at_x_right_2.
else if ((intersection_point->second == 0 || current_res == EQUAL)
&& equal_at_v == false) && equal_at_v == false)
{ {
// The multiplicity is unknown, so we have to compare the curves to // The multiplicity is unknown, so we have to compare the curves to
@ -783,44 +784,35 @@ _merge_two_intervals (Edge_const_handle e1, bool is_leftmost1,
current_res = traits->compare_y_at_x_right_2_object() current_res = traits->compare_y_at_x_right_2_object()
(e1->curve(), (e1->curve(),
e2->curve(), e2->curve(),
intersection_point.first); intersection_point->first);
// 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);
} }
last_ip = intersection_point.first;
} }
else else
{ {
// 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.
bool assign_success = CGAL::assign (intersection_curve, obj); intersection_curve = CGAL::object_cast<X_monotone_curve_2>(&obj);
if (! assign_success) 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);
if (has_right)
{
last_ip = p_right;
}
else if (has_left)
last_ip = p_left;
bool is_in_x_range = true; bool is_in_x_range = true;
// Check if the overlapping curve is not relevant to our range. // Check if the overlapping curve is not relevant to our range.
@ -844,14 +836,11 @@ _merge_two_intervals (Edge_const_handle e1, bool is_leftmost1,
if (res == EQUAL) if (res == EQUAL)
{ {
equal_at_v = true; equal_at_v = true;
last_ip = p_left;
} }
// 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.
@ -864,6 +853,8 @@ _merge_two_intervals (Edge_const_handle e1, bool is_leftmost1,
// left of the overlapping curve. // left of the overlapping curve.
Vertex_handle new_v; Vertex_handle new_v;
CGAL_assertion (current_res != EQUAL);
if (current_res == SMALLER) if (current_res == SMALLER)
new_v = _append_vertex (out_d, p_left, e1); new_v = _append_vertex (out_d, p_left, e1);
else else
@ -894,13 +885,15 @@ _merge_two_intervals (Edge_const_handle e1, bool is_leftmost1,
new_v = _append_vertex (out_d, p_right, e1); 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());
// 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. // We are not at v becuase p_right is smaller than v.
if (equal_at_v == false) // The special case that we are at v is handled in the next
{ // condition.
new_v->add_curves (e1->curves_begin(), e1->curves_end()); // If we were at v, then this was a special case that is handled
new_v->add_curves (e2->curves_begin(), e2->curves_end()); // later.
} CGAL_assertion (equal_at_v == false);
new_v->add_curves (e1->curves_begin(), e1->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;
@ -916,7 +909,6 @@ _merge_two_intervals (Edge_const_handle e1, bool is_leftmost1,
Vertex_handle new_v; Vertex_handle new_v;
new_v = _append_vertex (out_d, v->point(), e1); 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());
last_ip = v->point();
} }
equal_at_v = true; equal_at_v = true;
@ -924,10 +916,12 @@ _merge_two_intervals (Edge_const_handle e1, bool is_leftmost1,
break; break;
} }
// We arrive here only if we are not at v and the overlap has a right
// endpoint.
// Compare the curves to the right of p_right. // Compare the curves to the right of p_right.
current_res = traits->compare_y_at_x_right_2_object() (e1->curve(), current_res = traits->compare_y_at_x_right_2_object() (e1->curve(),
e2->curve(), e2->curve(),
*last_ip); p_right);
// 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);
@ -961,8 +955,6 @@ _merge_two_intervals (Edge_const_handle e1, bool is_leftmost1,
{ {
// We add the curves from the original vertex and from the edge of the // We add the curves from the original vertex and from the edge of the
// other diagram. // other diagram.
Vertex_const_handle v = (origin_of_v == SMALLER) ? e1->right() :
e2->right();
Edge_const_handle e = (origin_of_v == SMALLER) ? e2 : e1; Edge_const_handle e = (origin_of_v == SMALLER) ? e2 : e1;
v_to_be_updated->add_curves (v->curves_begin(), v->curves_end()); v_to_be_updated->add_curves (v->curves_begin(), v->curves_end());
@ -994,8 +986,15 @@ _merge_two_intervals (Edge_const_handle e1, bool is_leftmost1,
} }
} }
// Check if we need to insert v into the diagram. // origin_of_v could be EQUAL but the curves do not intersect.
// This is because of the fact that v could be the endpoint of the NEXT
// curve (which is lower than the currrent curve. The second diagram, however,
// has a curve that ends at v.
// For example:
// First diagram is the segment: [(0, -1), (1, 0)]
// Second diagram of the two segments: [(0, 0), (1, 1)], [(1, 0), (2, 1)]
// 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.