From d805e4b4d08103ab17f84556937e71c01da1aae1 Mon Sep 17 00:00:00 2001 From: Ron Wein Date: Tue, 1 Aug 2006 07:08:47 +0000 Subject: [PATCH] Fixed the code so it compiles. --- .../Envelope_2/ex_envelope_segments.cpp | 11 ++- .../include/CGAL/Env_default_diagram_1.h | 24 ++++-- .../Envelope_2/Env_divide_and_conquer_2.h | 56 +++++++------ .../Env_divide_and_conquer_2_impl.h | 84 ++++++++++++------- Envelope_2/include/CGAL/envelope_2.h | 50 +++++------ 5 files changed, 130 insertions(+), 95 deletions(-) diff --git a/Envelope_2/examples/Envelope_2/ex_envelope_segments.cpp b/Envelope_2/examples/Envelope_2/ex_envelope_segments.cpp index 43c5389c6f0..e8d09402a55 100644 --- a/Envelope_2/examples/Envelope_2/ex_envelope_segments.cpp +++ b/Envelope_2/examples/Envelope_2/ex_envelope_segments.cpp @@ -8,6 +8,7 @@ #include typedef CGAL::Gmpq NT; +typedef CGAL::Cartesian Kernel; typedef CGAL::Arr_segment_traits_2 Traits_2; typedef Traits_2::Point_2 Point_2; typedef Traits_2::Curve_2 Segment_2; @@ -15,19 +16,21 @@ typedef CGAL::Env_default_diagram_1 Diagram_1; int main () { - Traits_2 traits; + // Consrtuct the input segments. std::list segments; - Diagram_1 diag; segments.push_back (Segment_2 (Point_2 (1, 1), Point_2 (6, 3))); segments.push_back (Segment_2 (Point_2 (5, 3), Point_2 (9, 1))); segments.push_back (Segment_2 (Point_2 (2, 2), Point_2 (5, 2))); segments.push_back (Segment_2 (Point_2 (6, 1), Point_2 (8, 4))); + + // Compute their lower envelope. + Diagram_1 diag; - lower_envelope_2 (traits, - segments.begin(), segments.end(). + lower_envelope_2 (segments.begin(), segments.end(), diag); + // Print the minimization diagram. Diagram_1::Edge_const_handle e = diag.leftmost(); Diagram_1::Vertex_const_handle v; diff --git a/Envelope_2/include/CGAL/Env_default_diagram_1.h b/Envelope_2/include/CGAL/Env_default_diagram_1.h index 716804c45f5..a99dc5fa46f 100644 --- a/Envelope_2/include/CGAL/Env_default_diagram_1.h +++ b/Envelope_2/include/CGAL/Env_default_diagram_1.h @@ -139,6 +139,16 @@ public: return; } + /*! Associate a range of new curves with the vertex. */ + void add_curves (Curve_const_iterator begin, Curve_const_iterator end) + { + Curve_const_iterator iter; + + for (iter = begin; iter != end; ++iter) + _cvs.push_back (*iter); + return; + } + /*! Set the left edge. */ void set_left (Edge* e) { @@ -383,7 +393,7 @@ public: } /*! Create a new vertex. */ - Vertex* new_vertex (const Point_2& p) + Vertex_handle new_vertex (const Point_2& p) { Vertex *v = vertex_alloc.allocate (1); @@ -392,16 +402,16 @@ public: } /*! Create a new edge. */ - Vertex* new_edge () + Edge_handle new_edge () { - Vertex *e = edge_alloc.allocate (1); + Edge *e = edge_alloc.allocate (1); edge_alloc.construct (e, Edge()); return (e); } /*! Delete an existing vertex. */ - void delete_vertex (Vertex * v) + void delete_vertex (Vertex_handle v) { vertex_alloc.destroy (v); vertex_alloc.deallocate (v, 1); @@ -410,7 +420,7 @@ public: } /*! Delete an existing edge. */ - void delete_edge (Edge * e) + void delete_edge (Edge_handle e) { edge_alloc.destroy (e); edge_alloc.deallocate (e, 1); @@ -425,8 +435,8 @@ private: */ void _free () { - Vertex *v = _leftmostP; - Edge *e; + Vertex *v; + Edge *e = _leftmostP; while (e != NULL) { diff --git a/Envelope_2/include/CGAL/Envelope_2/Env_divide_and_conquer_2.h b/Envelope_2/include/CGAL/Envelope_2/Env_divide_and_conquer_2.h index 535d95e14c7..5acdd242288 100644 --- a/Envelope_2/include/CGAL/Envelope_2/Env_divide_and_conquer_2.h +++ b/Envelope_2/include/CGAL/Envelope_2/Env_divide_and_conquer_2.h @@ -20,7 +20,8 @@ #ifndef CGAL_ENVELOPE_DIVIDE_AND_CONQUER_2_H #define CGAL_ENVELOPE_DIVIDE_AND_CONQUER_2_H -#include +#include +#include CGAL_BEGIN_NAMESPACE @@ -28,8 +29,7 @@ CGAL_BEGIN_NAMESPACE * A class implementing the divide-and-conquer algorithm for computing the * lower (or upper) envelope of a set of curves. */ -template > +template class Envelope_divide_and_conquer_2 { public: @@ -40,6 +40,8 @@ public: typedef typename Traits_2::Curve_2 Curve_2; typedef Diagram_ Envelope_diagram_1; + +protected: typedef Envelope_divide_and_conquer_2 Self; @@ -49,8 +51,6 @@ public: UPPER }; -protected: - typedef typename Envelope_diagram_1::Vertex_const_handle Vertex_const_handle; typedef typename Envelope_diagram_1::Vertex_handle Vertex_handle; typedef typename Envelope_diagram_1::Edge_const_handle Edge_const_handle; @@ -59,10 +59,12 @@ protected: typedef std::list Curve_pointer_list; typedef typename Curve_pointer_list::iterator Curve_pointer_iterator; + typedef Arr_traits_adaptor_2 Traits_adaptor_2; + // Data members: - Traits_2 *traits; // The traits object. - bool own_traits; // Whether we own the traits object. - Envelope_type env_type; // Either LOWER or UPPER. + Traits_adaptor_2 *traits; // The traits object. + bool own_traits; // Whether we own the traits object. + Envelope_type env_type; // Either LOWER or UPPER. // Copy constructor and assignment operator - not supported. Envelope_divide_and_conquer_2 (const Self& ); @@ -77,7 +79,7 @@ public: own_traits(true), env_type(LOWER) { - traits = new Traits_2; + traits = new Traits_adaptor_2; } /*! @@ -85,10 +87,11 @@ public: * \param _traits The traits object. */ Envelope_divide_and_conquer_2 (const Traits_2* _traits) : - traits (_traits), own_traits(false), env_type(LOWER) - {} + { + traits = static_cast (_traits); + } /*! * Destructor. @@ -103,13 +106,12 @@ public: * Construct the lower (or upper) envelope to the given range of curves. * \param begin An iterator pointing at the beginning of the curves range. * \param end A past-the-end iterator for the curves range. - * \param type The envelope type (LOWER or UPPER). + * \param type The envelope type (true for lower, false of upper). * \param diagram Output: The minimization (or maximization) diagram. */ template - void insert_curves (const CurvesIterator& begin, - const CurvesIterator& end, - const Envelope_type& type, + void insert_curves (CurvesIterator begin, CurvesIterator end, + bool type, Envelope_diagram_1& diagram) { // Subdivide the curves into x-monotone subcurves. @@ -127,7 +129,7 @@ public: for (obj_it = objects.begin(); obj_it != objects.end(); ++obj_it) { - if(CGAL::assign (xcv, *obj_itr)) + if(CGAL::assign (xcv, *obj_it)) x_curves.push_back (xcv); } } @@ -144,17 +146,16 @@ public: * x-monotone curves. * \param begin An iterator pointing at the beginning of the curves range. * \param end A past-the-end iterator for the curves range. - * \param type The envelope type (LOWER or UPPER). + * \param type The envelope type (true for lower, false for upper). * \param diagram Output: The minimization (or maximization) diagram. */ template - void insert_x_monotone_curves (const XCurvesIterator& begin, - const XCurvesIterator& end, - const Envelope_type& type, + void insert_x_monotone_curves (XCurvesIterator begin, XCurvesIterator end, + bool type, Envelope_diagram_1& diagram) { // Set the envelope type. - env_type = type; + env_type = (type ? LOWER : UPPER); // Separate the regular curves from the vertical ones. typename Traits_2::Is_vertical_2 is_vertical = @@ -286,7 +287,7 @@ protected: * \return A handle for the vertex. */ Vertex_handle _append_vertex (Envelope_diagram_1& diag, - const Point_2& p, Edge_handle e); + const Point_2& p, Edge_const_handle e); /*! \struct * A functor used to sort vertical segments by their x-coordinate. @@ -301,12 +302,13 @@ protected: traits(_traits) {} - bool operator() (const M_curve_2 *mcv1, const M_curve_2 *mcv2) const + bool operator() (const X_monotone_curve_2& cv1, + const X_monotone_curve_2& cv2) const { - /* RWRW! - return (traits->compare_x_2_object() (traits->construct_min_vertex_2_object()(mcv1->xcv), - traits->construct_min_vertex_2_object()(mcv1->xcv)) == SMALLER); - */ + return (traits->compare_x_2_object() + (traits->construct_min_vertex_2_object()(cv1), + traits->construct_min_vertex_2_object()(cv2)) == SMALLER); + return (true); } }; diff --git a/Envelope_2/include/CGAL/Envelope_2/Env_divide_and_conquer_2_impl.h b/Envelope_2/include/CGAL/Envelope_2/Env_divide_and_conquer_2_impl.h index e2ba191d16b..0fc7549305b 100644 --- a/Envelope_2/include/CGAL/Envelope_2/Env_divide_and_conquer_2_impl.h +++ b/Envelope_2/include/CGAL/Envelope_2/Env_divide_and_conquer_2_impl.h @@ -49,7 +49,7 @@ _construct_envelope_non_vertical (Curve_pointer_iterator begin, if (iter == end) { // Construct a singleton diagram, which matches a single curve. - _construct_singleton_digram (*begin, out_d); + _construct_singleton_diagram (*(*begin), out_d); } else { @@ -112,7 +112,7 @@ _construct_singleton_diagram (const X_monotone_curve_2& cv, Vertex_handle v = out_d.new_vertex (traits->construct_max_vertex_2_object() (cv)); - Edge_hanfle e_right = out_d.new_edge(); + Edge_handle e_right = out_d.new_edge(); v->add_curve (cv); v->set_left (out_d.leftmost()); @@ -137,7 +137,7 @@ _construct_singleton_diagram (const X_monotone_curve_2& cv, Vertex_handle v = out_d.new_vertex (traits->construct_min_vertex_2_object() (cv)); - Edge_hanfle e_left = out_d.new_edge(); + Edge_handle e_left = out_d.new_edge(); v->add_curve (cv); v->set_left (e_left); @@ -203,8 +203,10 @@ _merge_envelopes (const Envelope_diagram_1& d1, Envelope_diagram_1& out_d) { Edge_const_handle e1 = d1.leftmost(); + bool is_leftmost1 = true; Vertex_const_handle v1; Edge_const_handle e2 = d2.leftmost(); + bool is_leftmost2 = true; Vertex_const_handle v2; Vertex_const_handle next_v; bool next_exists = true; @@ -252,7 +254,8 @@ _merge_envelopes (const Envelope_diagram_1& d1, if (! e1->is_empty() && ! e2->is_empty()) { // Both edges are not empty, and there are curves defined on them. - _merge_two_intervals (e1, e2, + _merge_two_intervals (e1, is_leftmost1, + e2, is_leftmost2, next_v, next_exists, (res_v == SMALLER) ? 1 : 2, out_d); @@ -262,7 +265,7 @@ _merge_envelopes (const Envelope_diagram_1& d1, // e1 is not empty but e2 is empty: _merge_single_interval (e1, next_v, next_exists, - (res == SMALLER), + (res_v == SMALLER), out_d); } else if (e1->is_empty() && ! e2->is_empty()) @@ -270,14 +273,17 @@ _merge_envelopes (const Envelope_diagram_1& d1, // e1 is empty and e2 is not empty: _merge_single_interval (e2, next_v, next_exists, - (res != SMALLER), + (res_v != SMALLER), out_d); } else { // Both edges are empty: append an empty edge to out_d: if (next_exists) - _append_vertex (out_d, next_v, e1); + { + Vertex_handle new_v = _append_vertex (out_d, next_v->point(), e1); + new_v->add_curves (next_v->curves_begin(), next_v->curves_end()); + } } // Proceed to the next diagram edge(s), if possible. @@ -287,19 +293,32 @@ _merge_envelopes (const Envelope_diagram_1& d1, if (res_v == SMALLER) { e1 = v1->right(); + is_leftmost1 = false; + if (same_x) + { e2 = v2->right(); + is_leftmost2 = false; + } } else if (res_v == LARGER) { e2 = v2->right(); + is_leftmost2 = false; + if (same_x) + { e1 = v1->right(); + is_leftmost1 = false; + } } else { e1 = v1->right(); + is_leftmost1 = false; + e2 = v2->right(); + is_leftmost2 = false; } } @@ -360,7 +379,7 @@ _merge_single_interval (Edge_const_handle e, { // The non-empty edge e is unbounded from the right, so we simply have // to update the rightmost edge in out_d. - out_d->rightmost()->add_curves (e->curves_begin(), e->curves_end()); + out_d.rightmost()->add_curves (e->curves_begin(), e->curves_end()); return; } @@ -419,8 +438,8 @@ _merge_two_intervals (Edge_const_handle e1, bool is_leftmost1, if (is_leftmost2) { // Both curves are defined at -oo: compare them there: - u_res = traits->compare_y_at_x_2_object() (e1->curve(), MIN_END, - e2->curve(), MIN_END); + u_res = traits->compare_y_at_x_2_object() (e1->curve(), e2->curve(), + MIN_END); } else { @@ -439,10 +458,9 @@ _merge_two_intervals (Edge_const_handle e1, bool is_leftmost1, else { // Find the rightmost of the two left endpoints and compare there. - const Comparison_result res; - - res = traits->compare_xy_2_object() (e1->left()->point(), - e2->left()->point()); + const Comparison_result res = + traits->compare_xy_2_object() (e1->left()->point(), + e2->left()->point()); if (res == SMALLER) { @@ -486,10 +504,10 @@ _merge_two_intervals (Edge_const_handle e1, bool is_leftmost1, u_res = CGAL::opposite (u_res); // Use the current rightmost of the diagram as a reference point. - const bool v_rm_exist = (out_d.leftmost() != out_d.rightmost()); + bool v_rm_exists = (out_d.leftmost() != out_d.rightmost()); Vertex_handle v_rm; - if (v_rm_exist) + if (v_rm_exists) v_rm = out_d.rightmost()->left(); // Find the next intersection of the envelopes to the right of the current @@ -499,12 +517,14 @@ _merge_two_intervals (Edge_const_handle e1, bool is_leftmost1, X_monotone_curve_2 icv; std::pair ipt; - traits->intersect_2_object()(cv1, cv2, std::back_inserter(objects)); + traits->intersect_2_object() (e1->curve(), e2->curve(), + std::back_inserter(objects)); while (! objects.empty()) { // Pop the xy-lexicographically smallest intersection object. - obj = objects.pop_first(); + obj = objects.front(); + objects.pop_front(); if (CGAL::assign(ipt, obj)) { @@ -707,16 +727,16 @@ _merge_two_intervals (Edge_const_handle e1, bool is_leftmost1, return; } - if (! v_exist) + if (! v_exists) { // Both edges are unbounded from the right, so we simply have // to update the rightmost edge in out_d. CGAL_assertion (u_res != EQUAL); if (u_res == SMALLER) - out_d->rightmost()->add_curves (e1->curves_begin(), e1->curves_end()); + out_d.rightmost()->add_curves (e1->curves_begin(), e1->curves_end()); else - out_d->rightmost()->add_curves (e2->curves_begin(), e2->curves_end()); + out_d.rightmost()->add_curves (e2->curves_begin(), e2->curves_end()); return; } @@ -725,10 +745,10 @@ _merge_two_intervals (Edge_const_handle e1, bool is_leftmost1, CGAL_assertion (u_res != EQUAL); if (u_res == SMALLER) - { - Vertex_handle new_v; - + { // The final part of the interval is taken from e1. + Vertex_handle new_v; + if (org_v == 1) { // In case v is also from e1, append it to the merged diagram. @@ -739,8 +759,9 @@ _merge_two_intervals (Edge_const_handle e1, bool is_leftmost1, { // If v is from e2, check if it below (or above, in case of an upper // envelope) cv1 to insert it. - res = traits->compare_y_at_x_2_object() (v->point(), - e1->curve()); + const Comparison_result res = + traits->compare_y_at_x_2_object() (v->point(), + e1->curve()); if (res == EQUAL || (env_type == LOWER && res == SMALLER) || @@ -757,6 +778,8 @@ _merge_two_intervals (Edge_const_handle e1, bool is_leftmost1, else { // The final part of the interval is taken from e2. + Vertex_handle new_v; + if (org_v == 2) { // In case v is also from e2, append it to the merged diagram. @@ -767,8 +790,9 @@ _merge_two_intervals (Edge_const_handle e1, bool is_leftmost1, { // If v is from e1, check if it below (or above, in case of an upper // envelope) cv2 to insert it. - res = traits->compare_y_at_x_2_object() (v->point(), - e2->curve()); + const Comparison_result res = + traits->compare_y_at_x_2_object() (v->point(), + e2->curve()); if (res == EQUAL || (env_type == LOWER && res == SMALLER) || @@ -793,7 +817,7 @@ template typename Envelope_divide_and_conquer_2::Vertex_handle Envelope_divide_and_conquer_2::_append_vertex (Envelope_diagram_1& diag, - const Point_2& p, Edge_handle e) + const Point_2& p, Edge_const_handle e) { // Create the new vertex and the new edge. Vertex_handle new_v = diag.new_vertex (p); @@ -819,7 +843,7 @@ Envelope_divide_and_conquer_2::_append_vertex { // The diagram is empty: Make the new edge the leftmost. new_e->set_right (new_v); - diag->set_leftmost (new_e); + diag.set_leftmost (new_e); diag.rightmost()->set_left (new_v); } diff --git a/Envelope_2/include/CGAL/envelope_2.h b/Envelope_2/include/CGAL/envelope_2.h index 5a95b7b5d07..e6ac97c1c1b 100644 --- a/Envelope_2/include/CGAL/envelope_2.h +++ b/Envelope_2/include/CGAL/envelope_2.h @@ -31,23 +31,22 @@ CGAL_BEGIN_NAMESPACE /*! * Compute the lower envelope of a range of curves. - * \param traits A traits class instance. * \param begin An iterator for the first curve. * \param end A past-the-end iterator for the curves. * \param diag Output: The minimization diagram. * \pre The value-type of the iterator is Traits::Curve_2. */ -template -void lower_envelope_2 (Traits& traits, - InputIterator begin, InputIterator end, +template +void lower_envelope_2 (InputIterator begin, InputIterator end, EnvelopeDiagram& diag) { - typedef Envelope_divide_and_conquer_2 Envelope_2; + typedef typename EnvelopeDiagram::Traits_2 Traits_2; + typedef Envelope_divide_and_conquer_2 Envelope_2; - Envelope_2 env (&traits); + Envelope_2 env; env.insert_curves (begin, end, - typename Envelope_2::LOWER, + true, // Lower envelope. diag); return; @@ -55,23 +54,22 @@ void lower_envelope_2 (Traits& traits, /*! * Compute the upper envelope of a range of curves. - * \param traits A traits class instance. * \param begin An iterator for the first curve. * \param end A past-the-end iterator for the curves. * \param diag Output: The maximization diagram. * \pre The value-type of the iterator is Traits::Curve_2. */ template -void upper_envelope_2 (Traits& traits, - InputIterator begin, InputIterator end, +void upper_envelope_2 (InputIterator begin, InputIterator end, EnvelopeDiagram& diag) { - typedef Envelope_divide_and_conquer_2 Envelope_2; + typedef typename EnvelopeDiagram::Traits_2 Traits_2; + typedef Envelope_divide_and_conquer_2 Envelope_2; - Envelope_2 env (&traits); + Envelope_2 env; env.insert_curves (begin, end, - typename Envelope_2::UPPER, + false, // Upper envelope. diag); return; @@ -79,23 +77,22 @@ void upper_envelope_2 (Traits& traits, /*! * Compute the lower envelope of a range of x-monotone curves. - * \param traits A traits class instance. * \param begin An iterator for the first x-monotone curve. * \param end A past-the-end iterator for the x-monotone curves. * \param diag Output: The minimization diagram. * \pre The value-type of the iterator is Traits::X_monotone_curve_2. */ -template -void lower_envelope_x_monotone_2 (Traits& traits, - InputIterator begin, InputIterator end, +template +void lower_envelope_x_monotone_2 (InputIterator begin, InputIterator end, EnvelopeDiagram& diag) { - typedef Envelope_divide_and_conquer_2 Envelope_2; + typedef typename EnvelopeDiagram::Traits_2 Traits_2; + typedef Envelope_divide_and_conquer_2 Envelope_2; - Envelope_2 env (&traits); + Envelope_2 env; env.insert_x_monotone_curves (begin, end, - typename Envelope_2::LOWER, + true, // Lower envelope. diag); return; @@ -103,23 +100,22 @@ void lower_envelope_x_monotone_2 (Traits& traits, /*! * Compute the upper envelope of a range of x-monotone curves. - * \param traits A traits class instance. * \param begin An iterator for the first x-monotone curve. * \param end A past-the-end iterator for the x-monotone curves. * \param diag Output: The maximization diagram. * \pre The value-type of the iterator is Traits::X_monotone_curve_2. */ -template -void upper_envelope_x_monotone_2 (Traits& traits, - InputIterator begin, InputIterator end, +template +void upper_envelope_x_monotone_2 (InputIterator begin, InputIterator end, EnvelopeDiagram& diag) { - typedef Envelope_divide_and_conquer_2 Envelope_2; + typedef typename EnvelopeDiagram::Traits_2 Traits_2; + typedef Envelope_divide_and_conquer_2 Envelope_2; - Envelope_2 env (&traits); + Envelope_2 env; env.insert_x_monotone_curves (begin, end, - typename Envelope_2::UPPER, + false, // Upper envelope. diag); return;