diff --git a/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/AABB_2d_traits.h b/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/AABB_2d_traits.h index 606e4bb680e..90761d67313 100644 --- a/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/AABB_2d_traits.h +++ b/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/AABB_2d_traits.h @@ -10,531 +10,535 @@ namespace CGAL { -double eps(double x) -{ - //return nextafter(x, DBL_MAX) - x; - return CGAL::abs(CGAL::nextafter(x, DBL_MAX) - x); - //CGAL::nextafter( +double eps(double x) { + //return nextafter(x, DBL_MAX) - x; + return CGAL::abs(CGAL::nextafter(x, DBL_MAX) - x); + //CGAL::nextafter( } - template -class AABB_traits_2 -{ - public: - typedef AABB_traits_2 AT; - /// AABBTraits concept types - typedef typename CGAL::Bbox_2 Bounding_box; - typedef typename CGAL::Object Object; - - typedef AABB_primitive Primitive; - typedef typename AABB_primitive::Id Id; - typedef typename AABB_primitive::Datum Datum; - typedef typename AABB_primitive::Container Container; - - typedef typename GeomTraits::Point_2 Point; - typedef typename GeomTraits::Vector_2 Vector_2; - - typedef typename std::pair Object_and_primitive_id; - typedef typename std::pair Point_and_primitive_id; - - // types for search tree - typedef typename GeomTraits::FT FT; - typedef typename GeomTraits::Point_2 Point_3; - typedef typename GeomTraits::Circle_2 Sphere_3; - typedef typename GeomTraits::Iso_rectangle_2 Iso_cuboid_3; - typedef typename GeomTraits::Construct_center_2 Construct_center_3; - typedef typename GeomTraits::Construct_iso_rectangle_2 Construct_iso_cuboid_3; - typedef typename GeomTraits::Construct_min_vertex_2 Construct_min_vertex_3; - typedef typename GeomTraits::Construct_max_vertex_2 Construct_max_vertex_3; - typedef typename GeomTraits::Compute_squared_radius_2 Compute_squared_radius_3; - typedef typename GeomTraits::Compute_squared_distance_2 Compute_squared_distance_3; - typedef typename GeomTraits::Cartesian_const_iterator_2 Cartesian_const_iterator_3; - typedef typename GeomTraits::Construct_cartesian_const_iterator_2 - Construct_cartesian_const_iterator_3; - - /// Constructor - AABB_traits_2(const Point& point,const Container& p,const Container& q):m_t_point(point),m_p(p),m_q(q) - { - //GeomTraits::ComputeX_2 c_x_o; - //GeomTraits::ComputeY_2 c_y_o; - m_x_interval = Interval_nt(CGAL::to_interval(point.x())); - m_y_interval = Interval_nt( CGAL::to_interval(point.y())); - m_px = CGAL::to_double(point.x()); - m_py = CGAL::to_double(point.y()); - }; - - AABB_traits_2():m_p(Container()),m_q(Container()) - { - - }; - - /// Non-virtual Destructor - ~AABB_traits_2() { }; - - Interval_nt getIntX() const{return m_x_interval;} - Interval_nt getIntY() const{return m_y_interval;} - - Point getTPoint() const{return m_t_point;} - const Container& get_p() const{return m_p;} - const Container& get_q() const{return m_q;} - /// - /** - * @brief Sorts [first,beyond[ - * @param first iterator on first element - * @param beyond iterator on beyond element - * @param bbox the bounding box of [first,beyond[ - * - * Sorts the range defined by [first,beyond[. Sort is achieved on bbox longuest - * axis, using the comparison function _less_than (dim in {x,y,z}) - */ - -class Sort_primitives -{ +template +class AABB_traits_2 { public: -template -void operator()(PrimitiveIterator first, - PrimitiveIterator beyond, - const typename AT::Bounding_box& bbox) const - { - PrimitiveIterator middle = first + (beyond - first)/2; - switch(longest_axis(bbox)) - { - case AT::CGAL_AXIS_X: // sort along x - std::nth_element(first, middle, beyond, less_x); - break; - case AT::CGAL_AXIS_Y: // sort along y - std::nth_element(first, middle, beyond, less_y); - break; - case AT::CGAL_AXIS_Z: // sort along z - CGAL_error(); - //std::nth_element(first, middle, beyond, less_z); - break; - default: - CGAL_error(); + typedef AABB_traits_2 AT; + /// AABBTraits concept types + typedef typename CGAL::Bbox_2 Bounding_box; + typedef typename CGAL::Object Object; + + typedef AABB_primitive Primitive; + typedef typename AABB_primitive::Id Id; + typedef typename AABB_primitive::Datum Datum; + typedef typename AABB_primitive::Container Container; + + typedef typename GeomTraits::Point_2 Point; + typedef typename GeomTraits::Vector_2 Vector_2; + + typedef typename std::pair Object_and_primitive_id; + typedef typename std::pair Point_and_primitive_id; + + // types for search tree + typedef typename GeomTraits::FT FT; + typedef typename GeomTraits::Point_2 Point_3; + typedef typename GeomTraits::Circle_2 Sphere_3; + typedef typename GeomTraits::Iso_rectangle_2 Iso_cuboid_3; + typedef typename GeomTraits::Construct_center_2 Construct_center_3; + typedef typename GeomTraits::Construct_iso_rectangle_2 Construct_iso_cuboid_3; + typedef typename GeomTraits::Construct_min_vertex_2 Construct_min_vertex_3; + typedef typename GeomTraits::Construct_max_vertex_2 Construct_max_vertex_3; + typedef typename GeomTraits::Compute_squared_radius_2 Compute_squared_radius_3; + typedef typename GeomTraits::Compute_squared_distance_2 Compute_squared_distance_3; + typedef typename GeomTraits::Cartesian_const_iterator_2 Cartesian_const_iterator_3; + typedef typename GeomTraits::Construct_cartesian_const_iterator_2 + Construct_cartesian_const_iterator_3; + + /// Constructor + AABB_traits_2(const Point &point, const Container &p, const Container &q): m_t_point(point), m_p(p), m_q(q) { + //GeomTraits::ComputeX_2 c_x_o; + //GeomTraits::ComputeY_2 c_y_o; + m_x_interval = Interval_nt(CGAL::to_interval(point.x())); + m_y_interval = Interval_nt(CGAL::to_interval(point.y())); + m_px = CGAL::to_double(point.x()); + m_py = CGAL::to_double(point.y()); + }; + + AABB_traits_2(): m_p(Container()), m_q(Container()) { + + }; + + /// Non-virtual Destructor + ~AABB_traits_2() { }; + + Interval_nt getIntX() const { + return m_x_interval; } - } -}; - -Sort_primitives sort_primitives_object() {return Sort_primitives();} - - - /** - * Computes the bounding box of a set of primitives - * @param first an iterator on the first primitive - * @param beyond an iterator on the past-the-end primitive - * @return the bounding box of the primitives of the iterator range - */ - - class Compute_bbox { -public: -template -typename AT::Bounding_box operator()(ConstPrimitiveIterator first, - ConstPrimitiveIterator beyond) const - { - typename AT::Bounding_box bbox = compute_bbox(*first); - for(++first; first != beyond; ++first) - { - bbox = bbox + compute_bbox(*first); + Interval_nt getIntY() const { + return m_y_interval; } - return bbox; - } -}; -Compute_bbox compute_bbox_object() {return Compute_bbox();} + Point getTPoint() const { + return m_t_point; + } + const Container &get_p() const { + return m_p; + } + const Container &get_q() const { + return m_q; + } + /// + /** + * @brief Sorts [first,beyond[ + * @param first iterator on first element + * @param beyond iterator on beyond element + * @param bbox the bounding box of [first,beyond[ + * + * Sorts the range defined by [first,beyond[. Sort is achieved on bbox longuest + * axis, using the comparison function _less_than (dim in {x,y,z}) + */ + + class Sort_primitives { + public: + template + void operator()(PrimitiveIterator first, + PrimitiveIterator beyond, + const typename AT::Bounding_box &bbox) const { + PrimitiveIterator middle = first + (beyond - first) / 2; + + switch (longest_axis(bbox)) { + case AT::CGAL_AXIS_X: // sort along x + std::nth_element(first, middle, beyond, less_x); + break; + + case AT::CGAL_AXIS_Y: // sort along y + std::nth_element(first, middle, beyond, less_y); + break; + + case AT::CGAL_AXIS_Z: // sort along z + CGAL_error(); + //std::nth_element(first, middle, beyond, less_z); + break; + + default: + CGAL_error(); + } + } + }; + + Sort_primitives sort_primitives_object() { + return Sort_primitives(); + } -class Do_intersect { -private: - AABB_traits_2* m_traits; - typedef typename Primitive::Datum Datum; -public: - Do_intersect(AABB_traits_2* _traits):m_traits(_traits){} - + /** + * Computes the bounding box of a set of primitives + * @param first an iterator on the first primitive + * @param beyond an iterator on the past-the-end primitive + * @return the bounding box of the primitives of the iterator range + */ - bool operator()(const Bounding_box& q, const Bounding_box& bbox) const - { - - /* Code for faster bbox, needs to be tested - // Get x max error. - double x_epsilon = CGAL::max(CGAL::max(eps(m_traits->m_px),eps(bbox.xmin())),eps(bbox.xmax()))*2; - // Get y max error. - double y_epsilon = CGAL::max(CGAL::max(eps(m_traits->m_py),eps(bbox.ymin())),eps(bbox.ymax()))*2; - double t_left = (m_traits->m_px + bbox.xmin())-x_epsilon; - double t_right = (m_traits->m_px + bbox.xmax())+x_epsilon; - double t_bottom = (m_traits->m_py + bbox.ymin())-y_epsilon; - double t_top = (m_traits->m_py + bbox.ymax())+y_epsilon; - Bounding_box t_box(t_left,t_bottom,t_right,t_top); - */ + class Compute_bbox { + public: + template + typename AT::Bounding_box operator()(ConstPrimitiveIterator first, + ConstPrimitiveIterator beyond) const { + typename AT::Bounding_box bbox = compute_bbox(*first); - double t_left = (m_traits->getIntX() + bbox.xmin()).inf(); - double t_right = (m_traits->getIntX() + bbox.xmax()).sup(); - double t_bottom = (m_traits->getIntY() + bbox.ymin()).inf(); - double t_top = (m_traits->getIntY() + bbox.ymax()).sup(); - Bounding_box t_box(t_left,t_bottom,t_right,t_top); - //double x_max = m_traits->getIntX().inf(); + for (++first; first != beyond; ++first) { + bbox = bbox + compute_bbox(*first); + } + + return bbox; + } + }; + + Compute_bbox compute_bbox_object() { + return Compute_bbox(); + } - return CGAL::do_overlap(q, t_box); - } - - - bool operator()(const Primitive& q, const Bounding_box& bbox) const - { - /* Code for faster bbox, needs to be tested - // Get x max error. - double x_epsilon = CGAL::max(CGAL::max(eps(m_traits->m_px),eps(bbox.xmin())),eps(bbox.xmax()))*2; - // Get y max error. - double y_epsilon = CGAL::max(CGAL::max(eps(m_traits->m_py),eps(bbox.ymin())),eps(bbox.ymax()))*2; - double t_left = (m_traits->m_px + bbox.xmin())-x_epsilon; - double t_right = (m_traits->m_px + bbox.xmax())+x_epsilon; - double t_bottom = (m_traits->m_py + bbox.ymin())-y_epsilon; - double t_top = (m_traits->m_py + bbox.ymax())+y_epsilon; - Bounding_box t_box(t_left,t_bottom,t_right,t_top); - */ + class Do_intersect { + private: + AABB_traits_2 *m_traits; + typedef typename Primitive::Datum Datum; + public: + Do_intersect(AABB_traits_2 *_traits): m_traits(_traits) {} - double t_left = (m_traits->getIntX() + bbox.xmin()).inf(); - double t_right = (m_traits->getIntX() + bbox.xmax()).sup(); - double t_bottom = (m_traits->getIntY() + bbox.ymin()).inf(); - double t_top = (m_traits->getIntY() + bbox.ymax()).sup(); - Bounding_box t_box(t_left,t_bottom,t_right,t_top); - ////double x_max = m_traits->getIntX().inf(); + bool operator()(const Bounding_box &q, const Bounding_box &bbox) const { + + /* Code for faster bbox, needs to be tested + // Get x max error. + double x_epsilon = CGAL::max(CGAL::max(eps(m_traits->m_px),eps(bbox.xmin())),eps(bbox.xmax()))*2; + // Get y max error. + double y_epsilon = CGAL::max(CGAL::max(eps(m_traits->m_py),eps(bbox.ymin())),eps(bbox.ymax()))*2; + double t_left = (m_traits->m_px + bbox.xmin())-x_epsilon; + double t_right = (m_traits->m_px + bbox.xmax())+x_epsilon; + double t_bottom = (m_traits->m_py + bbox.ymin())-y_epsilon; + double t_top = (m_traits->m_py + bbox.ymax())+y_epsilon; + Bounding_box t_box(t_left,t_bottom,t_right,t_top); + */ + + double t_left = (m_traits->getIntX() + bbox.xmin()).inf(); + double t_right = (m_traits->getIntX() + bbox.xmax()).sup(); + double t_bottom = (m_traits->getIntY() + bbox.ymin()).inf(); + double t_top = (m_traits->getIntY() + bbox.ymax()).sup(); + Bounding_box t_box(t_left, t_bottom, t_right, t_top); + //double x_max = m_traits->getIntX().inf(); - return CGAL::do_overlap(q.datum().bbox(), t_box); - } - - bool operator()(const Bounding_box& q, const Primitive& pr) const - { - - typename Primitive::Datum tr_pr = pr.datum().transform(typename GeomTraits::Aff_transformation_2(CGAL::Translation(), Vector_2(CGAL::ORIGIN,m_traits->getTPoint()))); - return CGAL::do_overlap(q, tr_pr.bbox()); - } - - - bool operator()(const Primitive& q, const Primitive& pr) const - { - - typename Primitive::Datum tr_pr = pr.datum().transform(typename GeomTraits::Aff_transformation_2(CGAL::Translation(), Vector_2(CGAL::ORIGIN,m_traits->getTPoint()))); - if (!CGAL::do_overlap(q.datum().bbox(),tr_pr.bbox())) - return false; - CGAL::Object intersection_object = GeomTraits().intersect_2_object()(q.datum(), tr_pr); - if (const CGAL::Point_2 *ipoint = CGAL::object_cast >(&intersection_object)) - { // handle weak intersections - bool has_weak_intersection = false; - bool p_intersect = false; - bool p_intersect_start = false; - bool q_intersect = false; - bool q_intersect_start = false; - - if (*ipoint == tr_pr.source ()) - { - has_weak_intersection = true; - p_intersect = true; - p_intersect_start = true; - } - else - { - if (*ipoint == tr_pr.target()) - { - has_weak_intersection = true; - p_intersect = true; - } - - } - - if (*ipoint == q.datum().source () ) - { - has_weak_intersection = true; - q_intersect = true; - q_intersect_start = true; - } - else - { - if (*ipoint == q.datum().target()) - { - q_intersect = true; - has_weak_intersection = true; - } - - } + return CGAL::do_overlap(q, t_box); + } - if (has_weak_intersection) - { - - bool val = handleWeakIntersections(p_intersect,q_intersect,p_intersect_start,q_intersect_start,pr,q,tr_pr); - if (val == false) - { - int k=4; - k = k+4; - k++; - - } - - return val; - - } - else - return true; - } - if (const CGAL::Segment_2 *iseg = CGAL::object_cast >(&intersection_object)) // we have overlapping segments - { - //GeomTraits::CompareXY_2 t_compare_endpoints_xy_2_obj = GeomTraits().CompareXY_2(); - //CGAL::Comparison_result c1 =t_compare_endpoints_xy_2_obj(tr_pr); - //CGAL::Comparison_result c2 = t_compare_endpoints_xy_2_obj(q.datum()); - //double x1 = CGAL::to_double(tr_pr.source().x()); - //double y1 = CGAL::to_double(tr_pr.source().y()); - //double x2 = CGAL::to_double(tr_pr.target().x()); - //double y2 = CGAL::to_double(tr_pr.target().y()); - //double x3 = CGAL::to_double(q.datum().source().x()); - //double y3 = CGAL::to_double(q.datum().source().y()); - //double x4 = CGAL::to_double(q.datum().target().x()); - //double y4 = CGAL::to_double(q.datum().target().y()); - CGAL::Comparison_result c1 =CGAL::compare_xy(tr_pr.source(),tr_pr.target()); - CGAL::Comparison_result c2 = CGAL::compare_xy(q.datum().source(),q.datum().target()); - - bool same_dir = (c1==c2); - return same_dir; - } - else - return false; // no intersection - } - - private: - - bool handleWeakIntersections(bool p_intersect,bool q_intersect,bool p_intersect_start,bool q_intersect_start,const Primitive& p,const Primitive& q,const Datum& tr_pr_datum) const - { - Id itr_p = p.id(); - Id itr_q = q.id(); - Id p_other = getOtherSegment(p_intersect_start,itr_p, m_traits->get_p()); - Id q_other = getOtherSegment(q_intersect_start,itr_q, m_traits->get_q()); - Datum p_other_translated = (*p_other).transform(typename GeomTraits::Aff_transformation_2(CGAL::Translation(), Vector_2(CGAL::ORIGIN,m_traits->getTPoint()))); - if (p_intersect && !q_intersect){ - if (p_intersect_start) - return handle_one_weak_int(p_other_translated,tr_pr_datum,*itr_q); - else - return handle_one_weak_int(tr_pr_datum,p_other_translated,*itr_q); - - } - else{ - if (!p_intersect && q_intersect){ - if (q_intersect_start) - return handle_one_weak_int(*q_other,*itr_q,tr_pr_datum); - else - return handle_one_weak_int(*itr_q,*q_other,tr_pr_datum); - } - else - { - Datum first_p,second_p; - Datum first_q,second_q; - if (p_intersect_start){ - first_p = p_other_translated; - second_p = tr_pr_datum; - } - else{ - first_p = tr_pr_datum; - second_p = p_other_translated; - } - - if (q_intersect_start){ - first_q = *q_other; - second_q = *itr_q; - } - else{ - first_q = *itr_q; - second_q = *q_other; - } - - return check_overlapping(first_p,second_p,first_q,second_q); - } - } - - } - - bool handle_one_weak_int(const Datum& incoming,const Datum& outgoing,const Datum& other_segment) const - { - // There is an overlap in polygon regions if the outgoing of p is ccw-between outgoing q and -incoming q or vice versa. - //return (other_segment.direction()).counterclockwise_in_between(outgoing.direction(),incoming.opposite().direction()); - return (other_segment.direction()).counterclockwise_in_between(outgoing.direction(),incoming.opposite().direction()) || - outgoing.direction().counterclockwise_in_between(other_segment.direction(),other_segment.opposite().direction()); - - } - - bool check_overlapping(const Datum& incoming_p,const Datum& outgoing_p,const Datum& incoming_q,const Datum& outgoing_q) const - { - // There is an overlap in polygon regions if the outgoing of p is ccw-between outgoing q and -incoming q or vice versa. - return ((outgoing_q.direction()).counterclockwise_in_between(outgoing_p.direction(),incoming_p.opposite().direction()) || - (outgoing_p.direction()).counterclockwise_in_between(outgoing_q.direction(),incoming_q.opposite().direction())); - } - - Id getOtherSegment(bool start,const Id& itr_p,const Container& cont) const - { - Id p_other; - if (start) - { - p_other = cont.edges_begin(); - if (p_other == itr_p) - { - p_other = cont.edges_end(); - --p_other; - } - else - { - while (p_other != itr_p) - ++p_other; - - --p_other; - } - - } - else - { - p_other = cont.edges_end(); - --p_other; - if (p_other == itr_p) - { - p_other = cont.edges_begin(); - // ++p_other; - } - else - { - while (p_other != itr_p) - --p_other; - - ++p_other; - } - } - return p_other; - } + bool operator()(const Primitive &q, const Bounding_box &bbox) const { + /* Code for faster bbox, needs to be tested + // Get x max error. + double x_epsilon = CGAL::max(CGAL::max(eps(m_traits->m_px),eps(bbox.xmin())),eps(bbox.xmax()))*2; + // Get y max error. + double y_epsilon = CGAL::max(CGAL::max(eps(m_traits->m_py),eps(bbox.ymin())),eps(bbox.ymax()))*2; + double t_left = (m_traits->m_px + bbox.xmin())-x_epsilon; + double t_right = (m_traits->m_px + bbox.xmax())+x_epsilon; + double t_bottom = (m_traits->m_py + bbox.ymin())-y_epsilon; + double t_top = (m_traits->m_py + bbox.ymax())+y_epsilon; + Bounding_box t_box(t_left,t_bottom,t_right,t_top); + */ -}; + double t_left = (m_traits->getIntX() + bbox.xmin()).inf(); + double t_right = (m_traits->getIntX() + bbox.xmax()).sup(); + double t_bottom = (m_traits->getIntY() + bbox.ymin()).inf(); + double t_top = (m_traits->getIntY() + bbox.ymax()).sup(); + Bounding_box t_box(t_left, t_bottom, t_right, t_top); + ////double x_max = m_traits->getIntX().inf(); -Do_intersect do_intersect_object() {return Do_intersect(this);} -class Intersection { -public: -template -boost::optional -operator()(const Query& query, const typename AT::Primitive& primitive) const -{ - typedef boost::optional Intersection; + return CGAL::do_overlap(q.datum().bbox(), t_box); + } - CGAL::Object object = GeomTraits().intersect_2_object()(primitive.datum(),query); - if ( object.empty() ) - return Intersection(); - else - return Intersection(Object_and_primitive_id(object,primitive.id())); -} -}; + bool operator()(const Bounding_box &q, const Primitive &pr) const { + + typename Primitive::Datum tr_pr = pr.datum().transform(typename GeomTraits::Aff_transformation_2(CGAL::Translation(), Vector_2(CGAL::ORIGIN, m_traits->getTPoint()))); + return CGAL::do_overlap(q, tr_pr.bbox()); + } + + + bool operator()(const Primitive &q, const Primitive &pr) const { + + typename Primitive::Datum tr_pr = pr.datum().transform(typename GeomTraits::Aff_transformation_2(CGAL::Translation(), Vector_2(CGAL::ORIGIN, m_traits->getTPoint()))); + + if (!CGAL::do_overlap(q.datum().bbox(), tr_pr.bbox())) { + return false; + } + + CGAL::Object intersection_object = GeomTraits().intersect_2_object()(q.datum(), tr_pr); + + if (const CGAL::Point_2 *ipoint = CGAL::object_cast >(&intersection_object)) { + // handle weak intersections + bool has_weak_intersection = false; + bool p_intersect = false; + bool p_intersect_start = false; + bool q_intersect = false; + bool q_intersect_start = false; + + if (*ipoint == tr_pr.source()) { + has_weak_intersection = true; + p_intersect = true; + p_intersect_start = true; + } else { + if (*ipoint == tr_pr.target()) { + has_weak_intersection = true; + p_intersect = true; + } + + } + + if (*ipoint == q.datum().source()) { + has_weak_intersection = true; + q_intersect = true; + q_intersect_start = true; + } else { + if (*ipoint == q.datum().target()) { + q_intersect = true; + has_weak_intersection = true; + } + + } + + + if (has_weak_intersection) { + + bool val = handleWeakIntersections(p_intersect, q_intersect, p_intersect_start, q_intersect_start, pr, q, tr_pr); + + if (val == false) { + int k = 4; + k = k + 4; + k++; + + } + + return val; + + } else { + return true; + } + } + + if (const CGAL::Segment_2 *iseg = CGAL::object_cast >(&intersection_object)) { // we have overlapping segments + //GeomTraits::CompareXY_2 t_compare_endpoints_xy_2_obj = GeomTraits().CompareXY_2(); + //CGAL::Comparison_result c1 =t_compare_endpoints_xy_2_obj(tr_pr); + //CGAL::Comparison_result c2 = t_compare_endpoints_xy_2_obj(q.datum()); + //double x1 = CGAL::to_double(tr_pr.source().x()); + //double y1 = CGAL::to_double(tr_pr.source().y()); + //double x2 = CGAL::to_double(tr_pr.target().x()); + //double y2 = CGAL::to_double(tr_pr.target().y()); + //double x3 = CGAL::to_double(q.datum().source().x()); + //double y3 = CGAL::to_double(q.datum().source().y()); + //double x4 = CGAL::to_double(q.datum().target().x()); + //double y4 = CGAL::to_double(q.datum().target().y()); + CGAL::Comparison_result c1 = CGAL::compare_xy(tr_pr.source(), tr_pr.target()); + CGAL::Comparison_result c2 = CGAL::compare_xy(q.datum().source(), q.datum().target()); + + bool same_dir = (c1 == c2); + return same_dir; + } else { + return false; // no intersection + } + } + + private: + + bool handleWeakIntersections(bool p_intersect, bool q_intersect, bool p_intersect_start, bool q_intersect_start, const Primitive &p, const Primitive &q, const Datum &tr_pr_datum) const { + Id itr_p = p.id(); + Id itr_q = q.id(); + Id p_other = getOtherSegment(p_intersect_start, itr_p, m_traits->get_p()); + Id q_other = getOtherSegment(q_intersect_start, itr_q, m_traits->get_q()); + Datum p_other_translated = (*p_other).transform(typename GeomTraits::Aff_transformation_2(CGAL::Translation(), Vector_2(CGAL::ORIGIN, m_traits->getTPoint()))); + + if (p_intersect && !q_intersect) { + if (p_intersect_start) { + return handle_one_weak_int(p_other_translated, tr_pr_datum, *itr_q); + } else { + return handle_one_weak_int(tr_pr_datum, p_other_translated, *itr_q); + } + + } else { + if (!p_intersect && q_intersect) { + if (q_intersect_start) { + return handle_one_weak_int(*q_other, *itr_q, tr_pr_datum); + } else { + return handle_one_weak_int(*itr_q, *q_other, tr_pr_datum); + } + } else { + Datum first_p, second_p; + Datum first_q, second_q; + + if (p_intersect_start) { + first_p = p_other_translated; + second_p = tr_pr_datum; + } else { + first_p = tr_pr_datum; + second_p = p_other_translated; + } + + if (q_intersect_start) { + first_q = *q_other; + second_q = *itr_q; + } else { + first_q = *itr_q; + second_q = *q_other; + } + + return check_overlapping(first_p, second_p, first_q, second_q); + } + } + + } + + bool handle_one_weak_int(const Datum &incoming, const Datum &outgoing, const Datum &other_segment) const { + // There is an overlap in polygon regions if the outgoing of p is ccw-between outgoing q and -incoming q or vice versa. + //return (other_segment.direction()).counterclockwise_in_between(outgoing.direction(),incoming.opposite().direction()); + return (other_segment.direction()).counterclockwise_in_between(outgoing.direction(), incoming.opposite().direction()) || + outgoing.direction().counterclockwise_in_between(other_segment.direction(), other_segment.opposite().direction()); + + } + + bool check_overlapping(const Datum &incoming_p, const Datum &outgoing_p, const Datum &incoming_q, const Datum &outgoing_q) const { + // There is an overlap in polygon regions if the outgoing of p is ccw-between outgoing q and -incoming q or vice versa. + return ((outgoing_q.direction()).counterclockwise_in_between(outgoing_p.direction(), incoming_p.opposite().direction()) || + (outgoing_p.direction()).counterclockwise_in_between(outgoing_q.direction(), incoming_q.opposite().direction())); + } + + Id getOtherSegment(bool start, const Id &itr_p, const Container &cont) const { + Id p_other; + + if (start) { + p_other = cont.edges_begin(); + + if (p_other == itr_p) { + p_other = cont.edges_end(); + --p_other; + } else { + while (p_other != itr_p) { + ++p_other; + } + + --p_other; + } + + } else { + p_other = cont.edges_end(); + --p_other; + + if (p_other == itr_p) { + p_other = cont.edges_begin(); + // ++p_other; + } else { + while (p_other != itr_p) { + --p_other; + } + + ++p_other; + } + } + + return p_other; + } + + + }; + + Do_intersect do_intersect_object() { + return Do_intersect(this); + } + + class Intersection { + public: + template + boost::optional + operator()(const Query &query, const typename AT::Primitive &primitive) const { + typedef boost::optional Intersection; + + CGAL::Object object = GeomTraits().intersect_2_object()(primitive.datum(), query); + + if (object.empty()) { + return Intersection(); + } else { + return Intersection(Object_and_primitive_id(object, primitive.id())); + } + } + }; //Intersection intersection_object() {return Intersection();} -Intersection intersection_object() {return Do_intersect(this);} + Intersection intersection_object() { + return Do_intersect(this); + } - // This should go down to the GeomTraits, i.e. the kernel - class Closest_point { - typedef typename AT::Point Point; - typedef typename AT::Primitive Primitive; - public: - Point operator()(const Point& p, const Primitive& pr, const Point& bound) const - { - // seems to be unused: - //return CGAL::nearest_point_2(p, pr.datum(), bound); - return p; - } - }; + // This should go down to the GeomTraits, i.e. the kernel + class Closest_point { + typedef typename AT::Point Point; + typedef typename AT::Primitive Primitive; + public: + Point operator()(const Point &p, const Primitive &pr, const Point &bound) const { + // seems to be unused: + //return CGAL::nearest_point_2(p, pr.datum(), bound); + return p; + } + }; - // This should go down to the GeomTraits, i.e. the kernel - // and the internal implementation should change its name from - // do_intersect to something like does_contain (this is what we compute, - // this is not the same do_intersect as the spherical kernel) - class Compare_distance { - typedef typename AT::Point Point; - typedef typename AT::Primitive Primitive; - public: - template - CGAL::Comparison_result operator()(const Point& p, const Solid& pr, const Point& bound) const - { - return GeomTraits().do_intersect_2_object() - (GeomTraits().construct_sphere_2_object() - (p, GeomTraits().compute_squared_distance_2_object()(p, bound)), pr)? - CGAL::SMALLER : CGAL::LARGER; - } - }; + // This should go down to the GeomTraits, i.e. the kernel + // and the internal implementation should change its name from + // do_intersect to something like does_contain (this is what we compute, + // this is not the same do_intersect as the spherical kernel) + class Compare_distance { + typedef typename AT::Point Point; + typedef typename AT::Primitive Primitive; + public: + template + CGAL::Comparison_result operator()(const Point &p, const Solid &pr, const Point &bound) const { + return GeomTraits().do_intersect_2_object() + (GeomTraits().construct_sphere_2_object() + (p, GeomTraits().compute_squared_distance_2_object()(p, bound)), pr) ? + CGAL::SMALLER : CGAL::LARGER; + } + }; - Closest_point closest_point_object() {return Closest_point();} - Compare_distance compare_distance_object() {return Compare_distance();} + Closest_point closest_point_object() { + return Closest_point(); + } + Compare_distance compare_distance_object() { + return Compare_distance(); + } private: - Point m_t_point; - double m_px,m_py; - Interval_nt m_x_interval; - Interval_nt m_y_interval; - const Container& m_p; - const Container& m_q; - /** - * @brief Computes bounding box of one primitive - * @param pr the primitive - * @return the bounding box of the primitive \c pr - */ - static Bounding_box compute_bbox(const Primitive& pr) - { - return pr.datum().bbox(); - } + Point m_t_point; + double m_px, m_py; + Interval_nt m_x_interval; + Interval_nt m_y_interval; + const Container &m_p; + const Container &m_q; + /** + * @brief Computes bounding box of one primitive + * @param pr the primitive + * @return the bounding box of the primitive \c pr + */ + static Bounding_box compute_bbox(const Primitive &pr) { + return pr.datum().bbox(); + } - typedef enum { CGAL_AXIS_X = 0, - CGAL_AXIS_Y = 1, - CGAL_AXIS_Z = 2} Axis; + typedef enum { CGAL_AXIS_X = 0, + CGAL_AXIS_Y = 1, + CGAL_AXIS_Z = 2 + } Axis; - static Axis longest_axis(const Bounding_box& bbox); - /// Comparison functions - static bool less_x(const Primitive& pr1, const Primitive& pr2) - { return pr1.reference_point().x() < pr2.reference_point().x(); } - static bool less_y(const Primitive& pr1, const Primitive& pr2) - { return pr1.reference_point().y() < pr2.reference_point().y(); } - /* static bool less_z(const Primitive& pr1, const Primitive& pr2) - { return pr1.reference_point().z() < pr2.reference_point().z(); }*/ + static Axis longest_axis(const Bounding_box &bbox); + /// Comparison functions + static bool less_x(const Primitive &pr1, const Primitive &pr2) { + return pr1.reference_point().x() < pr2.reference_point().x(); + } + static bool less_y(const Primitive &pr1, const Primitive &pr2) { + return pr1.reference_point().y() < pr2.reference_point().y(); + } + /* static bool less_z(const Primitive& pr1, const Primitive& pr2) + { return pr1.reference_point().z() < pr2.reference_point().z(); }*/ }; template -typename AABB_traits_2::Axis -AABB_traits_2::longest_axis(const Bounding_box& bbox) -{ - const double dx = bbox.xmax() - bbox.xmin(); - const double dy = bbox.ymax() - bbox.ymin(); -// const double dz = bbox.zmax() - bbox.zmin(); - if (dx>=dy) - return CGAL_AXIS_X; - else - return CGAL_AXIS_Y; +typename AABB_traits_2::Axis +AABB_traits_2::longest_axis(const Bounding_box &bbox) { + const double dx = bbox.xmax() - bbox.xmin(); + const double dy = bbox.ymax() - bbox.ymin(); - //if(dx>=dy) - //{ - // if(dx>=dz) - // { - // return CGAL_AXIS_X; - // } - // else // dz>dx and dx>=dy - // { - // return CGAL_AXIS_Z; - // } - //} - //else // dy>dx - //{ - // if(dy>=dz) - // { - // return CGAL_AXIS_Y; - // } - // else // dz>dy and dy>dx - // { - // return CGAL_AXIS_Z; - // } - //} +// const double dz = bbox.zmax() - bbox.zmin(); + if (dx >= dy) { + return CGAL_AXIS_X; + } else { + return CGAL_AXIS_Y; + } + + //if(dx>=dy) + //{ + // if(dx>=dz) + // { + // return CGAL_AXIS_X; + // } + // else // dz>dx and dx>=dy + // { + // return CGAL_AXIS_Z; + // } + //} + //else // dy>dx + //{ + // if(dy>=dz) + // { + // return CGAL_AXIS_Y; + // } + // else // dz>dy and dy>dx + // { + // return CGAL_AXIS_Z; + // } + //} } diff --git a/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/AABB_Collision_detector.h b/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/AABB_Collision_detector.h index 1a412b1005a..a2e40693c47 100644 --- a/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/AABB_Collision_detector.h +++ b/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/AABB_Collision_detector.h @@ -3,61 +3,59 @@ #include "ICollisionDetector.h" #include #include -#include +#include #include "AABB_tree_mod.h" #include "AABB_2d_traits.h" #include "AABB_segment_2_primitive.h" -namespace CGAL{ -template class AABBCollisionDetector : public ICollisionDetector< Kernel_, Container_> -{ +namespace CGAL { +template class AABBCollisionDetector : public ICollisionDetector< Kernel_, Container_> { public: - typedef typename Kernel_::Point_2 Point; - typedef typename CGAL::Polygon_2 Polygon_2; - //typedef typename Polygon_2::Edge_const_iterator Edge_iterator ; - typedef typename Polygon_2::Traits::Segment_2 Segment_2 ; - typedef typename Polygon_2::Edge_const_iterator Edge_iterator; - typedef typename Polygon_2::Edge_const_circulator Edge_circulator; - typedef AABB_segment_2_primitive Tree_Segment_2; - typedef AABB_traits_2 Tree_Traits; - typedef AABB_tree AABB_Tree; - typedef CGAL::Arr_segment_traits_2 Traits_2; + typedef typename Kernel_::Point_2 Point; + typedef typename CGAL::Polygon_2 Polygon_2; + //typedef typename Polygon_2::Edge_const_iterator Edge_iterator ; + typedef typename Polygon_2::Traits::Segment_2 Segment_2 ; + typedef typename Polygon_2::Edge_const_iterator Edge_iterator; + typedef typename Polygon_2::Edge_const_circulator Edge_circulator; + typedef AABB_segment_2_primitive Tree_Segment_2; + typedef AABB_traits_2 Tree_Traits; + typedef AABB_tree AABB_Tree; + typedef CGAL::Arr_segment_traits_2 Traits_2; protected: - Traits_2 m_traits; + Traits_2 m_traits; public: - AABBCollisionDetector( Polygon_2&p, Polygon_2& q)//:m_stationary_tree((q.edges_begin()),(q.edges_end())),m_translating_tree((p.edges_begin()),(p.edges_end())),m_p(p),m_q(q) - :m_stationary_tree((p.edges_begin()),(p.edges_end())),m_translating_tree((q.edges_begin()),(q.edges_end())),m_p(q),m_q(p) - { - - } - //typedef typename Polygon_2::Vertex_circulator Vertex_circulator; - //typedef typename - virtual bool checkCollision(const Polygon_2& p,const Polygon_2& q) - { - //Traits_2::Compare_endpoints_xy_2 cmp_obj = m_traits.compare_endpoints_xy_2_object(); - - if (m_stationary_tree.do_intersect_join(m_translating_tree,m_translation_point,m_p,m_q)) - return true; - - return (p.has_on_bounded_side(*(q.vertices_begin())) || q.has_on_bounded_side(*(p.vertices_begin()))); - //return true; + AABBCollisionDetector(Polygon_2 &p, Polygon_2 &q)//:m_stationary_tree((q.edges_begin()),(q.edges_end())),m_translating_tree((p.edges_begin()),(p.edges_end())),m_p(p),m_q(q) + : m_stationary_tree((p.edges_begin()), (p.edges_end())), m_translating_tree((q.edges_begin()), (q.edges_end())), m_p(q), m_q(p) { - } + } + //typedef typename Polygon_2::Vertex_circulator Vertex_circulator; + //typedef typename + virtual bool checkCollision(const Polygon_2 &p, const Polygon_2 &q) { + //Traits_2::Compare_endpoints_xy_2 cmp_obj = m_traits.compare_endpoints_xy_2_object(); - void setTranslationPoint(const Point& t){ - m_translation_point = t; - } + if (m_stationary_tree.do_intersect_join(m_translating_tree, m_translation_point, m_p, m_q)) { + return true; + } + + return (p.has_on_bounded_side(*(q.vertices_begin())) || q.has_on_bounded_side(*(p.vertices_begin()))); + //return true; + + } + + void setTranslationPoint(const Point &t) { + m_translation_point = t; + } private: - AABB_Tree m_stationary_tree; - AABB_Tree m_translating_tree; - Point m_translation_point; - Polygon_2& m_p; - Polygon_2& m_q; + AABB_Tree m_stationary_tree; + AABB_Tree m_translating_tree; + Point m_translation_point; + Polygon_2 &m_p; + Polygon_2 &m_q; }; } diff --git a/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/AABB_node_mod.h b/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/AABB_node_mod.h index 82e4f254ce1..dfa780dced4 100644 --- a/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/AABB_node_mod.h +++ b/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/AABB_node_mod.h @@ -34,91 +34,104 @@ namespace CGAL { * */ template -class AABB_node -{ +class AABB_node { public: - typedef typename AABBTraits::Bounding_box Bounding_box; + typedef typename AABBTraits::Bounding_box Bounding_box; - /// Constructor - AABB_node() - : m_bbox() - , m_p_left_child(NULL) - , m_p_right_child(NULL) { }; + /// Constructor + AABB_node() + : m_bbox() + , m_p_left_child(NULL) + , m_p_right_child(NULL) { }; - /// Non virtual Destructor - /// Do not delete children because the tree hosts and delete them - ~AABB_node() { }; + /// Non virtual Destructor + /// Do not delete children because the tree hosts and delete them + ~AABB_node() { }; - /// Returns the bounding box of the node - Bounding_box bbox() const { return m_bbox; } + /// Returns the bounding box of the node + Bounding_box bbox() const { + return m_bbox; + } - /** - * @brief Builds the tree by recursive expansion. - * @param first the first primitive to insert - * @param last the last primitive to insert - * @param range the number of primitive of the range - * - * [first,last[ is the range of primitives to be added to the tree. - */ - template - void expand(ConstPrimitiveIterator first, - ConstPrimitiveIterator beyond, - const std::size_t range); + /** + * @brief Builds the tree by recursive expansion. + * @param first the first primitive to insert + * @param last the last primitive to insert + * @param range the number of primitive of the range + * + * [first,last[ is the range of primitives to be added to the tree. + */ + template + void expand(ConstPrimitiveIterator first, + ConstPrimitiveIterator beyond, + const std::size_t range); - /** - * @brief General traversal query - * @param query the query - * @param traits the traversal traits that define the traversal behaviour - * @param nb_primitives the number of primitive - * - * General traversal query. The traits class allows using it for the various - * traversal methods we need: listing, counting, detecting intersections, - * drawing the boxes. - */ - template - void traversal(const Query& query, - Traversal_traits& traits, - const std::size_t nb_primitives) const; - - template - void join_traversal(const AABB_node& other_node, - Traversal_traits& traits, - const std::size_t nb_primitives_this,const std::size_t nb_primitives_other, bool first_stationary) const; + /** + * @brief General traversal query + * @param query the query + * @param traits the traversal traits that define the traversal behaviour + * @param nb_primitives the number of primitive + * + * General traversal query. The traits class allows using it for the various + * traversal methods we need: listing, counting, detecting intersections, + * drawing the boxes. + */ + template + void traversal(const Query &query, + Traversal_traits &traits, + const std::size_t nb_primitives) const; + + template + void join_traversal(const AABB_node &other_node, + Traversal_traits &traits, + const std::size_t nb_primitives_this, const std::size_t nb_primitives_other, bool first_stationary) const; private: - typedef AABBTraits AABB_traits; - typedef AABB_node Node; - typedef typename AABB_traits::Primitive Primitive; + typedef AABBTraits AABB_traits; + typedef AABB_node Node; + typedef typename AABB_traits::Primitive Primitive; - /// Helper functions - const Node& left_child() const - { return *static_cast(m_p_left_child); } - const Node& right_child() const - { return *static_cast(m_p_right_child); } - const Primitive& left_data() const - { return *static_cast(m_p_left_child); } - const Primitive& right_data() const - { return *static_cast(m_p_right_child); } + /// Helper functions + const Node &left_child() const { + return *static_cast(m_p_left_child); + } + const Node &right_child() const { + return *static_cast(m_p_right_child); + } + const Primitive &left_data() const { + return *static_cast(m_p_left_child); + } + const Primitive &right_data() const { + return *static_cast(m_p_right_child); + } - Node& left_child() { return *static_cast(m_p_left_child); } - Node& right_child() { return *static_cast(m_p_right_child); } - Primitive& left_data() { return *static_cast(m_p_left_child); } - Primitive& right_data() { return *static_cast(m_p_right_child); } + Node &left_child() { + return *static_cast(m_p_left_child); + } + Node &right_child() { + return *static_cast(m_p_right_child); + } + Primitive &left_data() { + return *static_cast(m_p_left_child); + } + Primitive &right_data() { + return *static_cast(m_p_right_child); + } private: - /// node bounding box - Bounding_box m_bbox; + /// node bounding box + Bounding_box m_bbox; - /// children nodes, either pointing towards children (if children are not leaves), - /// or pointing toward input primitives (if children are leaves). - void *m_p_left_child; - void *m_p_right_child; + /// children nodes, either pointing towards children (if children are not leaves), + /// or pointing toward input primitives (if children are leaves). + void *m_p_left_child; + void *m_p_right_child; private: - // Disabled copy constructor & assignment operator - typedef AABB_node Self; - AABB_node(const Self& src); - Self& operator=(const Self& src); + // Disabled copy constructor & assignment operator + typedef AABB_node Self; + AABB_node(const Self &src); + Self &operator=(const Self &src); }; // end class AABB_node @@ -128,199 +141,190 @@ template void AABB_node::expand(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond, - const std::size_t range) -{ - m_bbox = AABB_traits().compute_bbox_object()(first, beyond); + const std::size_t range) { + m_bbox = AABB_traits().compute_bbox_object()(first, beyond); - // sort primitives along longest axis aabb - AABB_traits().sort_primitives_object()(first, beyond, m_bbox); + // sort primitives along longest axis aabb + AABB_traits().sort_primitives_object()(first, beyond, m_bbox); - switch(range) - { - case 2: - m_p_left_child = &(*first); - m_p_right_child = &(*(++first)); - break; - case 3: - m_p_left_child = &(*first); - m_p_right_child = static_cast(this)+1; - right_child().expand(first+1, beyond, 2); - break; - default: - const std::size_t new_range = range/2; - m_p_left_child = static_cast(this) + 1; - m_p_right_child = static_cast(this) + new_range; - left_child().expand(first, first + new_range, new_range); - right_child().expand(first + new_range, beyond, range - new_range); - } + switch (range) { + case 2: + m_p_left_child = &(*first); + m_p_right_child = &(*(++first)); + break; + + case 3: + m_p_left_child = &(*first); + m_p_right_child = static_cast(this) + 1; + right_child().expand(first + 1, beyond, 2); + break; + + default: + const std::size_t new_range = range / 2; + m_p_left_child = static_cast(this) + 1; + m_p_right_child = static_cast(this) + new_range; + left_child().expand(first, first + new_range, new_range); + right_child().expand(first + new_range, beyond, range - new_range); + } } template template void -AABB_node::traversal(const Query& query, - Traversal_traits& traits, - const std::size_t nb_primitives) const -{ - // Recursive traversal - switch(nb_primitives) - { - case 2: - traits.intersection(query, left_data()); - if( traits.go_further() ) - { - traits.intersection(query, right_data()); +AABB_node::traversal(const Query &query, + Traversal_traits &traits, + const std::size_t nb_primitives) const { + // Recursive traversal + switch (nb_primitives) { + case 2: + traits.intersection(query, left_data()); + + if (traits.go_further()) { + traits.intersection(query, right_data()); + } + + break; + + case 3: + traits.intersection(query, left_data()); + + if (traits.go_further() && traits.do_intersect(query, right_child())) { + right_child().traversal(query, traits, 2); + } + + break; + + default: + if (traits.do_intersect(query, left_child())) { + left_child().traversal(query, traits, nb_primitives / 2); + + if (traits.go_further() && traits.do_intersect(query, right_child())) { + right_child().traversal(query, traits, nb_primitives - nb_primitives / 2); + } + } else if (traits.do_intersect(query, right_child())) { + right_child().traversal(query, traits, nb_primitives - nb_primitives / 2); + } } - break; - case 3: - traits.intersection(query, left_data()); - if( traits.go_further() && traits.do_intersect(query, right_child()) ) - { - right_child().traversal(query, traits, 2); - } - break; - default: - if( traits.do_intersect(query, left_child()) ) - { - left_child().traversal(query, traits, nb_primitives/2); - if( traits.go_further() && traits.do_intersect(query, right_child()) ) - { - right_child().traversal(query, traits, nb_primitives-nb_primitives/2); - } - } - else if( traits.do_intersect(query, right_child()) ) - { - right_child().traversal(query, traits, nb_primitives-nb_primitives/2); - } - } } template template void -AABB_node::join_traversal(const AABB_node& other_node, - Traversal_traits& traits, - const std::size_t nb_primitives_this,const std::size_t nb_primitives_other, bool first_stationary) const -{ - // Recursive traversal - bool first_tree_small = nb_primitives_this <= 3; - bool second_tree_small = nb_primitives_other <= 3; - bool first_tree_even = nb_primitives_this == 2; - bool second_tree_even = nb_primitives_other == 2; +AABB_node::join_traversal(const AABB_node &other_node, + Traversal_traits &traits, + const std::size_t nb_primitives_this, const std::size_t nb_primitives_other, bool first_stationary) const { + // Recursive traversal + bool first_tree_small = nb_primitives_this <= 3; + bool second_tree_small = nb_primitives_other <= 3; + bool first_tree_even = nb_primitives_this == 2; + bool second_tree_even = nb_primitives_other == 2; - if (first_tree_small && second_tree_small) - { - traits.intersection(left_data(),other_node.left_data(),!first_stationary); - if (traits.go_further() ) - { // 4 cases - if (first_tree_even){ - if (second_tree_even){ // 2 and 2 - traits.intersection( right_data(),other_node.right_data(),!first_stationary); - if (traits.go_further()) - traits.intersection(right_data(),other_node.left_data(),!first_stationary); - if (traits.go_further()) - traits.intersection( left_data(),other_node.right_data(),!first_stationary); - } - else{ // 2 and 3 - if (traits.do_intersect(right_data(),other_node.right_child(),!first_stationary) || traits.do_intersect(left_data(),other_node.right_child(),!first_stationary) ){ - other_node.right_child().join_traversal(*this,traits,2,2,!first_stationary); - } - /*if (traits.go_further() && traits.do_intersect(other_node.right_child(), left_data(),!first_stationary)) - { - other_node.right_child().join_traversal(left_data(),traits,2,1,!first_stationary); - }*/ - } - } - else { + if (first_tree_small && second_tree_small) { + traits.intersection(left_data(), other_node.left_data(), !first_stationary); - if (second_tree_even){ // 3 and 2 - if (traits.do_intersect(right_child(), other_node.right_data(),!first_stationary) || traits.do_intersect(right_child(), other_node.left_data(),!first_stationary)){ - right_child().join_traversal(other_node,traits,2,2,first_stationary); - } - /*if (traits.go_further() && traits.do_intersect(right_child(), other_node.left_data(),first_stationary)) - { - right_child().join_traversal(other_node.left_data(),traits,2,1,first_stationary); - }*/ - }else{ //3 and 3 - if (traits.do_intersect(right_child(), other_node.right_child(),!first_stationary)){ - right_child().join_traversal(other_node.right_child(),traits,2,2,first_stationary); - } - if (traits.go_further() && traits.do_intersect(right_child(), other_node.left_data(),!first_stationary)) - { - right_child().join_traversal(other_node,traits,2,3,first_stationary); - } - if (traits.go_further() && traits.do_intersect(left_data(),other_node.right_child(),!first_stationary)) - { - other_node.right_child().join_traversal(*this,traits,2,3,!first_stationary); - } - } + if (traits.go_further()) { + // 4 cases + if (first_tree_even) { + if (second_tree_even) { // 2 and 2 + traits.intersection(right_data(), other_node.right_data(), !first_stationary); - } - - } - } + if (traits.go_further()) { + traits.intersection(right_data(), other_node.left_data(), !first_stationary); + } - // first tree is 3 or smaller and second tree is larger - if (first_tree_small && !second_tree_small) - { - if (traits.do_intersect(*this,other_node.left_child(),!first_stationary)) - { - other_node.left_child().join_traversal(*this, traits, nb_primitives_other/2,nb_primitives_this,!first_stationary); - if( traits.go_further() && traits.do_intersect(*this, other_node.right_child(),!first_stationary) ){ - other_node.right_child().join_traversal(*this, traits, nb_primitives_other-nb_primitives_other/2,nb_primitives_this,!first_stationary); - } - } - else if (traits.do_intersect(*this,other_node.right_child(),!first_stationary)) - { - other_node.right_child().join_traversal(*this, traits, nb_primitives_other-nb_primitives_other/2,nb_primitives_this,!first_stationary); - } - } + if (traits.go_further()) { + traits.intersection(left_data(), other_node.right_data(), !first_stationary); + } + } else { // 2 and 3 + if (traits.do_intersect(right_data(), other_node.right_child(), !first_stationary) || traits.do_intersect(left_data(), other_node.right_child(), !first_stationary)) { + other_node.right_child().join_traversal(*this, traits, 2, 2, !first_stationary); + } - // symetrical to previous case. - if (!first_tree_small && second_tree_small) - { - if (traits.do_intersect(left_child(),other_node,!first_stationary)) - { - left_child().join_traversal(other_node, traits, nb_primitives_this/2,nb_primitives_other,first_stationary); - if( traits.go_further() && traits.do_intersect( right_child(),other_node,!first_stationary) ){ - right_child().join_traversal(other_node, traits, nb_primitives_this-nb_primitives_this/2,nb_primitives_other,first_stationary); - } - } - else if (traits.do_intersect(right_child(),other_node,!first_stationary)) - { - right_child().join_traversal(other_node, traits, nb_primitives_this-nb_primitives_this/2,nb_primitives_other,first_stationary); - } - } + /*if (traits.go_further() && traits.do_intersect(other_node.right_child(), left_data(),!first_stationary)) + { + other_node.right_child().join_traversal(left_data(),traits,2,1,!first_stationary); + }*/ + } + } else { - // both trees as larger then 3 - if (!first_tree_small && !second_tree_small) - { - if (traits.do_intersect(left_child(),other_node.left_child(),!first_stationary)) - { - left_child().join_traversal(other_node.left_child(), traits, nb_primitives_this/2,nb_primitives_other/2,first_stationary); - } + if (second_tree_even) { // 3 and 2 + if (traits.do_intersect(right_child(), other_node.right_data(), !first_stationary) || traits.do_intersect(right_child(), other_node.left_data(), !first_stationary)) { + right_child().join_traversal(other_node, traits, 2, 2, first_stationary); + } - if (traits.go_further() && traits.do_intersect(left_child(), other_node.right_child(),!first_stationary)) - { - left_child().join_traversal(other_node.right_child(), traits, nb_primitives_this/2,nb_primitives_other - nb_primitives_other/2,first_stationary); - } + /*if (traits.go_further() && traits.do_intersect(right_child(), other_node.left_data(),first_stationary)) + { + right_child().join_traversal(other_node.left_data(),traits,2,1,first_stationary); + }*/ + } else { //3 and 3 + if (traits.do_intersect(right_child(), other_node.right_child(), !first_stationary)) { + right_child().join_traversal(other_node.right_child(), traits, 2, 2, first_stationary); + } - if (traits.go_further() && traits.do_intersect(right_child(), other_node.left_child(),!first_stationary)) - { - right_child().join_traversal(other_node.left_child(), traits, nb_primitives_this-nb_primitives_this/2,nb_primitives_other/2,first_stationary); - } + if (traits.go_further() && traits.do_intersect(right_child(), other_node.left_data(), !first_stationary)) { + right_child().join_traversal(other_node, traits, 2, 3, first_stationary); + } + + if (traits.go_further() && traits.do_intersect(left_data(), other_node.right_child(), !first_stationary)) { + other_node.right_child().join_traversal(*this, traits, 2, 3, !first_stationary); + } + } + + } + + } + } + + // first tree is 3 or smaller and second tree is larger + if (first_tree_small && !second_tree_small) { + if (traits.do_intersect(*this, other_node.left_child(), !first_stationary)) { + other_node.left_child().join_traversal(*this, traits, nb_primitives_other / 2, nb_primitives_this, !first_stationary); + + if (traits.go_further() && traits.do_intersect(*this, other_node.right_child(), !first_stationary)) { + other_node.right_child().join_traversal(*this, traits, nb_primitives_other - nb_primitives_other / 2, nb_primitives_this, !first_stationary); + } + } else if (traits.do_intersect(*this, other_node.right_child(), !first_stationary)) { + other_node.right_child().join_traversal(*this, traits, nb_primitives_other - nb_primitives_other / 2, nb_primitives_this, !first_stationary); + } + } + + // symetrical to previous case. + if (!first_tree_small && second_tree_small) { + if (traits.do_intersect(left_child(), other_node, !first_stationary)) { + left_child().join_traversal(other_node, traits, nb_primitives_this / 2, nb_primitives_other, first_stationary); + + if (traits.go_further() && traits.do_intersect(right_child(), other_node, !first_stationary)) { + right_child().join_traversal(other_node, traits, nb_primitives_this - nb_primitives_this / 2, nb_primitives_other, first_stationary); + } + } else if (traits.do_intersect(right_child(), other_node, !first_stationary)) { + right_child().join_traversal(other_node, traits, nb_primitives_this - nb_primitives_this / 2, nb_primitives_other, first_stationary); + } + } + + // both trees as larger then 3 + if (!first_tree_small && !second_tree_small) { + if (traits.do_intersect(left_child(), other_node.left_child(), !first_stationary)) { + left_child().join_traversal(other_node.left_child(), traits, nb_primitives_this / 2, nb_primitives_other / 2, first_stationary); + } + + if (traits.go_further() && traits.do_intersect(left_child(), other_node.right_child(), !first_stationary)) { + left_child().join_traversal(other_node.right_child(), traits, nb_primitives_this / 2, nb_primitives_other - nb_primitives_other / 2, first_stationary); + } + + if (traits.go_further() && traits.do_intersect(right_child(), other_node.left_child(), !first_stationary)) { + right_child().join_traversal(other_node.left_child(), traits, nb_primitives_this - nb_primitives_this / 2, nb_primitives_other / 2, first_stationary); + } + + if (traits.go_further() && traits.do_intersect(right_child(), other_node.right_child(), !first_stationary)) { + right_child().join_traversal(other_node.right_child(), traits, nb_primitives_this - nb_primitives_this / 2, nb_primitives_other - nb_primitives_other / 2, first_stationary); + } + + } - if (traits.go_further() && traits.do_intersect(right_child(), other_node.right_child(),!first_stationary)) - { - right_child().join_traversal(other_node.right_child(), traits, nb_primitives_this-nb_primitives_this/2,nb_primitives_other - nb_primitives_other/2,first_stationary); - } - - } - } } // end namespace CGAL diff --git a/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/AABB_segment_2_primitive.h b/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/AABB_segment_2_primitive.h index dfaeff3c66f..591a087d1c1 100644 --- a/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/AABB_segment_2_primitive.h +++ b/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/AABB_segment_2_primitive.h @@ -27,42 +27,49 @@ namespace CGAL { -template -class AABB_segment_2_primitive -{ - // types +template +class AABB_segment_2_primitive { + // types public: - typedef typename GeomTraits::Point_2 Point; // point type - typedef typename GeomTraits::Segment_2 Datum; // datum type - typedef Container_type Container; - typedef Iterator Id; // Id type + typedef typename GeomTraits::Point_2 Point; // point type + typedef typename GeomTraits::Segment_2 Datum; // datum type + typedef Container_type Container; + typedef Iterator Id; // Id type - // member data + // member data private: - Id m_it; - Datum m_datum; + Id m_it; + Datum m_datum; public: - // constructors - AABB_segment_2_primitive() {} - AABB_segment_2_primitive(Id it) - : m_it(it) - { - m_datum = *it; // copy segment - } - AABB_segment_2_primitive(const AABB_segment_2_primitive& primitive) - { - m_it = primitive.id(); - m_datum = primitive.datum(); - } + // constructors + AABB_segment_2_primitive() {} + AABB_segment_2_primitive(Id it) + : m_it(it) { + m_datum = *it; // copy segment + } + AABB_segment_2_primitive(const AABB_segment_2_primitive &primitive) { + m_it = primitive.id(); + m_datum = primitive.datum(); + } public: - Id& id() { return m_it; } - const Id& id() const { return m_it; } - Datum& datum() { return m_datum; } - const Datum& datum() const { return m_datum; } + Id &id() { + return m_it; + } + const Id &id() const { + return m_it; + } + Datum &datum() { + return m_datum; + } + const Datum &datum() const { + return m_datum; + } - /// Returns a point on the primitive - Point reference_point() const { return m_datum.source(); } + /// Returns a point on the primitive + Point reference_point() const { + return m_datum.source(); + } }; } // end namespace CGAL diff --git a/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/AABB_tree_mod.h b/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/AABB_tree_mod.h index d8a7d7c3f9d..3aa9ae1d7a1 100644 --- a/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/AABB_tree_mod.h +++ b/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/AABB_tree_mod.h @@ -28,737 +28,722 @@ namespace CGAL { - /** - * @class AABB_tree - * - * - */ - template - class AABB_tree - { - public: - /// types - typedef typename AABBTraits::FT FT; - typedef typename AABBTraits::Point Point; - typedef typename AABBTraits::Primitive Primitive; - typedef typename AABBTraits::Bounding_box Bounding_box; - typedef typename AABBTraits::Primitive::Id Primitive_id; - typedef typename AABBTraits::Point_and_primitive_id Point_and_primitive_id; - typedef typename AABBTraits::Object_and_primitive_id Object_and_primitive_id; +/** +* @class AABB_tree +* +* +*/ +template +class AABB_tree { +public: + /// types + typedef typename AABBTraits::FT FT; + typedef typename AABBTraits::Point Point; + typedef typename AABBTraits::Primitive Primitive; + typedef typename AABBTraits::Bounding_box Bounding_box; + typedef typename AABBTraits::Primitive::Id Primitive_id; + typedef typename AABBTraits::Point_and_primitive_id Point_and_primitive_id; + typedef typename AABBTraits::Object_and_primitive_id Object_and_primitive_id; - private: - // internal KD-tree used to accelerate the distance queries - //typedef AABB_search_tree Search_tree; +private: + // internal KD-tree used to accelerate the distance queries + //typedef AABB_search_tree Search_tree; - // type of the primitives container - typedef std::vector Primitives; + // type of the primitives container + typedef std::vector Primitives; - typedef AABB_node Node; + typedef AABB_node Node; - public: - // size type is the size_type of the primitive container - typedef typename Primitives::size_type size_type; +public: + // size type is the size_type of the primitive container + typedef typename Primitives::size_type size_type; - public: +public: /** * @brief Default Constructor * - * Builds an empty tree datastructure. + * Builds an empty tree datastructure. */ AABB_tree(); - /** - * @brief Constructor - * @param first iterator over first primitive to insert - * @param beyond past-the-end iterator - * - * Builds the datastructure. Type ConstPrimitiveIterator can be any const - * iterator on a container of Primitive::id_type such that Primitive has - * a constructor taking a ConstPrimitiveIterator as argument. - */ - template - AABB_tree(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond); - - /// Clears the current tree and rebuilds the datastructure. - /// Type ConstPrimitiveIterator can be any const iterator on - /// a container of Primitive::id_type such that Primitive has - /// a constructor taking a ConstPrimitiveIterator as argument. - /// Returns true if the memory allocation was successful. - template - void rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond); - - /// Non virtual destructor - ~AABB_tree() - { - clear(); - } - - /// Clears the tree - void clear() - { - // clear AABB tree - m_primitives.clear(); - delete [] m_p_root_node; - m_p_root_node = NULL; - - //clear_search_tree(); - } - - // bbox and size - Bounding_box bbox() const { return m_p_root_node->bbox(); } - size_type size() const { return m_primitives.size(); } - bool empty() const { return m_primitives.empty(); } - - /// Construct internal search tree with a given point set - // returns true iff successful memory allocation - template - bool accelerate_distance_queries(ConstPointIterator first, ConstPointIterator beyond); - - /// Construct internal search tree from - /// a point set taken on the internal primitives - // returns true iff successful memory allocation - bool accelerate_distance_queries(); - - // intersection tests - template - bool do_intersect(const Query& query) const; - - template - bool do_intersect_join(const AABB_tree& other,const Point& Translation_point,const Primitive_type& p,const Primitive_type& q) const; - - // #intersections - template - size_type number_of_intersected_primitives(const Query& query) const; - - // all intersections - template - OutputIterator all_intersected_primitives(const Query& query, OutputIterator out) const; - template - OutputIterator all_intersections(const Query& query, OutputIterator out) const; - - // any intersection - template - boost::optional any_intersected_primitive(const Query& query) const; - template - boost::optional any_intersection(const Query& query) const; - - // distance queries - FT squared_distance(const Point& query) const; - FT squared_distance(const Point& query, const Point& hint) const; - Point closest_point(const Point& query) const; - Point closest_point(const Point& query, const Point& hint) const; - Point_and_primitive_id closest_point_and_primitive(const Point& query) const; - Point_and_primitive_id closest_point_and_primitive(const Point& query, const Point_and_primitive_id& hint) const; - - private: - - // clears internal KD tree - void clear_search_tree() - { - /* delete m_p_search_tree; - m_p_search_tree = NULL; - m_search_tree_constructed = false;*/ - } - - public: - // made public for advanced use by the polyhedron demo - - /// generic traversal of the tree - template - void traversal(const Query& query, Traversal_traits& traits) const - { - if(!empty()) - m_p_root_node->template traversal(query, traits, m_primitives.size()); - else - std::cerr << "AABB tree traversal with empty tree" << std::endl; - } - - template void join_traversal(const AABB_tree& other_tree, Traversal_traits& traits) const - { - if (!empty() && !other_tree.empty()) - { - m_p_root_node->template join_traversal(*(other_tree.m_p_root_node), traits, m_primitives.size(),other_tree.m_primitives.size(),true); - } - else - std::cerr << "AABB tree joint traversal with empty tree" << std::endl; - } - - private: - - - //------------------------------------------------------- - // Traits classes for traversal computation - //------------------------------------------------------- - /** - * @class First_intersection_traits - */ - template - class First_intersection_traits - { - public: - typedef typename boost::optional Result; - public: - First_intersection_traits() - : m_result() - {} - - bool go_further() const { return !m_result; } - - void intersection(const Query& query, const Primitive& primitive) - { - m_result = AABBTraits().intersection_object()(query, primitive); - } - - bool do_intersect(const Query& query, const Node& node) const - { - return AABBTraits().do_intersect_object()(query, node.bbox()); - } - - Result result() const { return m_result; } - bool is_intersection_found() const { return m_result; } - - private: - Result m_result; - }; - - - /** - * @class Counting_traits - */ - template - class Counting_traits - { - public: - Counting_traits() - : m_nb_intersections(0) - {} - - bool go_further() const { return true; } - - void intersection(const Query& query, const Primitive& primitive) - { - if( AABBTraits().do_intersect_object()(query, primitive) ) - { - ++m_nb_intersections; - } - } - - bool do_intersect(const Query& query, const Node& node) const - { - return AABBTraits().do_intersect_object()(query, node.bbox()); - } - - size_type number_of_intersections() const { return m_nb_intersections; } - - private: - size_type m_nb_intersections; - }; - - - /** - * @class Listing_intersection_traits - */ - template - class Listing_intersection_traits - { - public: - Listing_intersection_traits(Output_iterator out_it) - : m_out_it(out_it) {} - - bool go_further() const { return true; } - - void intersection(const Query& query, const Primitive& primitive) - { - boost::optional intersection; - intersection = AABBTraits().intersection_object()(query, primitive); - if(intersection) - { - *m_out_it++ = *intersection; - } - } - - bool do_intersect(const Query& query, const Node& node) const - { - return AABBTraits().do_intersect_object()(query, node.bbox()); - } - - private: - Output_iterator m_out_it; - }; - - - /** - * @class Listing_primitive_traits - */ - template - class Listing_primitive_traits - { - public: - Listing_primitive_traits(Output_iterator out_it) - : m_out_it(out_it) {} - - bool go_further() const { return true; } - - void intersection(const Query& query, const Primitive& primitive) - { - if( AABBTraits().do_intersect_object()(query, primitive) ) - { - *m_out_it++ = primitive.id(); - } - } - - bool do_intersect(const Query& query, const Node& node) const - { - return AABBTraits().do_intersect_object()(query, node.bbox()); - } - - private: - Output_iterator m_out_it; - }; - - - /** - * @class First_primitive_traits - */ - template - class First_primitive_traits - { - public: - First_primitive_traits() - : m_is_found(false) - , m_result() {} - - bool go_further() const { return !m_is_found; } - - void intersection(const Query& query, const Primitive& primitive) - { - if( AABBTraits().do_intersect_object()(query, primitive) ) - { - m_result = boost::optional(primitive.id()); - m_is_found = true; - } - } - - bool do_intersect(const Query& query, const Node& node) const - { - return AABBTraits().do_intersect_object()(query, node.bbox()); - } - - boost::optional result() const { return m_result; } - bool is_intersection_found() const { return m_is_found; } - - private: - bool m_is_found; - boost::optional m_result; - }; - - /** - * @class Do_intersect_traits - */ - template - class Do_intersect_traits - { - public: - Do_intersect_traits() - : m_is_found(false) - {} - - bool go_further() const { return !m_is_found; } - - void intersection(const Query& query, const Primitive& primitive) - { - if( AABBTraits().do_intersect_object()(query, primitive) ) - m_is_found = true; - } - - bool do_intersect(const Query& query, const Node& node) const - { - return AABBTraits().do_intersect_object()(query, node.bbox()); - } - - bool is_intersection_found() const { return m_is_found; } - - private: - bool m_is_found; - }; - - friend class Do_intersect_joined_traits; - template - class Do_intersect_joined_traits - { - public: - Do_intersect_joined_traits(const Point& point,const Primitive_type& p,const Primitive_type& q) - : m_is_found(false) , m_point(point)//, m_p(p),m_q(q) - { - m_traits_ptr = new AABBTraits(point,p,q); - } - - bool go_further() const { return !m_is_found; } - - void intersection(const Primitive& primitive1, const Primitive& primitive2,bool toSwitch) - { - if (!toSwitch) - { - if( m_traits_ptr->do_intersect_object()(primitive1, primitive2) ) - m_is_found = true; - }else - { - if( m_traits_ptr->do_intersect_object()(primitive2, primitive1) ) - m_is_found = true; - } - } - - bool do_intersect(const Node& node_1, const Node& node_2,bool toSwitch) const - { - if (!toSwitch) - return m_traits_ptr->do_intersect_object()(node_1.bbox(), node_2.bbox()); - else - return m_traits_ptr->do_intersect_object()(node_2.bbox(), node_1.bbox()); - } - - bool do_intersect(const Node& node_1, const Primitive& primitive2,bool toSwitch) const - { - if (!toSwitch) - return m_traits_ptr->do_intersect_object()(node_1.bbox(), primitive2); - else - return m_traits_ptr->do_intersect_object()(primitive2, node_1.bbox()); - } - - bool do_intersect(const Primitive& primitive1,const Node& node_2,bool toSwitch) const - { - if (!toSwitch) - return m_traits_ptr->do_intersect_object()(primitive1,node_2.bbox()); - else - return m_traits_ptr->do_intersect_object()(node_2.bbox(),primitive1); - } - - bool is_intersection_found() const { return m_is_found; } - - ~Do_intersect_joined_traits() - { - delete m_traits_ptr; - } - - private: - bool m_is_found; - Point m_point; - //Primitive_type& m_p,m_q; - AABBTraits* m_traits_ptr; - }; - - - - /** - * @class Distance_traits - */ - class Distance_traits - { - public: - Distance_traits(const Point& hint, - const typename Primitive::Id& hint_primitive) - : m_closest_point(hint), - m_closest_primitive(hint_primitive) - {} - - bool go_further() const { return true; } - - void intersection(const Point& query, const Primitive& primitive) - { - Point new_closest_point = AABBTraits().closest_point_object() - (query, primitive, m_closest_point); - if(new_closest_point != m_closest_point) - { - m_closest_primitive = primitive.id(); - m_closest_point = new_closest_point; // this effectively shrinks the sphere - } - } - - bool do_intersect(const Point& query, const Node& node) const - { - return AABBTraits().compare_distance_object() - (query, node.bbox(), m_closest_point) == CGAL::SMALLER; - } - - Point closest_point() const { return m_closest_point; } - Point_and_primitive_id closest_point_and_primitive() const - { - return Point_and_primitive_id(m_closest_point, m_closest_primitive); - } - - private: - Point m_closest_point; - typename Primitive::Id m_closest_primitive; - }; - - public: - // returns a point which must be on one primitive - Point_and_primitive_id any_reference_point_and_id() const - { - CGAL_assertion(!empty()); - return Point_and_primitive_id(m_primitives[0].reference_point(), m_primitives[0].id()); - } - - public: - Point_and_primitive_id best_hint(const Point& query) const - { - /* if(m_search_tree_constructed) - return m_p_search_tree->closest_point(query); - else - return this->any_reference_point_and_id();*/ - } - - private: - // set of input primitives - Primitives m_primitives; - // single root node - Node* m_p_root_node; - // search KD-tree - //Search_tree* m_p_search_tree; - bool m_search_tree_constructed; - - private: - // Disabled copy constructor & assignment operator - typedef AABB_tree Self; - AABB_tree(const Self& src); - Self& operator=(const Self& src); - - }; // end class AABB_tree - - template - AABB_tree::AABB_tree() + /** + * @brief Constructor + * @param first iterator over first primitive to insert + * @param beyond past-the-end iterator + * + * Builds the datastructure. Type ConstPrimitiveIterator can be any const + * iterator on a container of Primitive::id_type such that Primitive has + * a constructor taking a ConstPrimitiveIterator as argument. + */ + template + AABB_tree(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond); + + /// Clears the current tree and rebuilds the datastructure. + /// Type ConstPrimitiveIterator can be any const iterator on + /// a container of Primitive::id_type such that Primitive has + /// a constructor taking a ConstPrimitiveIterator as argument. + /// Returns true if the memory allocation was successful. + template + void rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond); + + /// Non virtual destructor + ~AABB_tree() { + clear(); + } + + /// Clears the tree + void clear() { + // clear AABB tree + m_primitives.clear(); + delete [] m_p_root_node; + m_p_root_node = NULL; + + //clear_search_tree(); + } + + // bbox and size + Bounding_box bbox() const { + return m_p_root_node->bbox(); + } + size_type size() const { + return m_primitives.size(); + } + bool empty() const { + return m_primitives.empty(); + } + + /// Construct internal search tree with a given point set + // returns true iff successful memory allocation + template + bool accelerate_distance_queries(ConstPointIterator first, ConstPointIterator beyond); + + /// Construct internal search tree from + /// a point set taken on the internal primitives + // returns true iff successful memory allocation + bool accelerate_distance_queries(); + + // intersection tests + template + bool do_intersect(const Query &query) const; + + template + bool do_intersect_join(const AABB_tree &other, const Point &Translation_point, const Primitive_type &p, const Primitive_type &q) const; + + // #intersections + template + size_type number_of_intersected_primitives(const Query &query) const; + + // all intersections + template + OutputIterator all_intersected_primitives(const Query &query, OutputIterator out) const; + template + OutputIterator all_intersections(const Query &query, OutputIterator out) const; + + // any intersection + template + boost::optional any_intersected_primitive(const Query &query) const; + template + boost::optional any_intersection(const Query &query) const; + + // distance queries + FT squared_distance(const Point &query) const; + FT squared_distance(const Point &query, const Point &hint) const; + Point closest_point(const Point &query) const; + Point closest_point(const Point &query, const Point &hint) const; + Point_and_primitive_id closest_point_and_primitive(const Point &query) const; + Point_and_primitive_id closest_point_and_primitive(const Point &query, const Point_and_primitive_id &hint) const; + +private: + + // clears internal KD tree + void clear_search_tree() { + /* delete m_p_search_tree; + m_p_search_tree = NULL; + m_search_tree_constructed = false;*/ + } + +public: + // made public for advanced use by the polyhedron demo + + /// generic traversal of the tree + template + void traversal(const Query &query, Traversal_traits &traits) const { + if (!empty()) { + m_p_root_node->template traversal(query, traits, m_primitives.size()); + } else { + std::cerr << "AABB tree traversal with empty tree" << std::endl; + } + } + + template void join_traversal(const AABB_tree &other_tree, Traversal_traits &traits) const { + if (!empty() && !other_tree.empty()) { + m_p_root_node->template join_traversal(*(other_tree.m_p_root_node), traits, m_primitives.size(), other_tree.m_primitives.size(), true); + } else { + std::cerr << "AABB tree joint traversal with empty tree" << std::endl; + } + } + +private: + + + //------------------------------------------------------- + // Traits classes for traversal computation + //------------------------------------------------------- + /** + * @class First_intersection_traits + */ + template + class First_intersection_traits { + public: + typedef typename boost::optional Result; + public: + First_intersection_traits() + : m_result() { + } + + bool go_further() const { + return !m_result; + } + + void intersection(const Query &query, const Primitive &primitive) { + m_result = AABBTraits().intersection_object()(query, primitive); + } + + bool do_intersect(const Query &query, const Node &node) const { + return AABBTraits().do_intersect_object()(query, node.bbox()); + } + + Result result() const { + return m_result; + } + bool is_intersection_found() const { + return m_result; + } + + private: + Result m_result; + }; + + + /** + * @class Counting_traits + */ + template + class Counting_traits { + public: + Counting_traits() + : m_nb_intersections(0) { + } + + bool go_further() const { + return true; + } + + void intersection(const Query &query, const Primitive &primitive) { + if (AABBTraits().do_intersect_object()(query, primitive)) { + ++m_nb_intersections; + } + } + + bool do_intersect(const Query &query, const Node &node) const { + return AABBTraits().do_intersect_object()(query, node.bbox()); + } + + size_type number_of_intersections() const { + return m_nb_intersections; + } + + private: + size_type m_nb_intersections; + }; + + + /** + * @class Listing_intersection_traits + */ + template + class Listing_intersection_traits { + public: + Listing_intersection_traits(Output_iterator out_it) + : m_out_it(out_it) {} + + bool go_further() const { + return true; + } + + void intersection(const Query &query, const Primitive &primitive) { + boost::optional intersection; + intersection = AABBTraits().intersection_object()(query, primitive); + + if (intersection) { + *m_out_it++ = *intersection; + } + } + + bool do_intersect(const Query &query, const Node &node) const { + return AABBTraits().do_intersect_object()(query, node.bbox()); + } + + private: + Output_iterator m_out_it; + }; + + + /** + * @class Listing_primitive_traits + */ + template + class Listing_primitive_traits { + public: + Listing_primitive_traits(Output_iterator out_it) + : m_out_it(out_it) {} + + bool go_further() const { + return true; + } + + void intersection(const Query &query, const Primitive &primitive) { + if (AABBTraits().do_intersect_object()(query, primitive)) { + *m_out_it++ = primitive.id(); + } + } + + bool do_intersect(const Query &query, const Node &node) const { + return AABBTraits().do_intersect_object()(query, node.bbox()); + } + + private: + Output_iterator m_out_it; + }; + + + /** + * @class First_primitive_traits + */ + template + class First_primitive_traits { + public: + First_primitive_traits() + : m_is_found(false) + , m_result() {} + + bool go_further() const { + return !m_is_found; + } + + void intersection(const Query &query, const Primitive &primitive) { + if (AABBTraits().do_intersect_object()(query, primitive)) { + m_result = boost::optional(primitive.id()); + m_is_found = true; + } + } + + bool do_intersect(const Query &query, const Node &node) const { + return AABBTraits().do_intersect_object()(query, node.bbox()); + } + + boost::optional result() const { + return m_result; + } + bool is_intersection_found() const { + return m_is_found; + } + + private: + bool m_is_found; + boost::optional m_result; + }; + + /** + * @class Do_intersect_traits + */ + template + class Do_intersect_traits { + public: + Do_intersect_traits() + : m_is_found(false) { + } + + bool go_further() const { + return !m_is_found; + } + + void intersection(const Query &query, const Primitive &primitive) { + if (AABBTraits().do_intersect_object()(query, primitive)) { + m_is_found = true; + } + } + + bool do_intersect(const Query &query, const Node &node) const { + return AABBTraits().do_intersect_object()(query, node.bbox()); + } + + bool is_intersection_found() const { + return m_is_found; + } + + private: + bool m_is_found; + }; + + friend class Do_intersect_joined_traits; + template + class Do_intersect_joined_traits { + public: + Do_intersect_joined_traits(const Point &point, const Primitive_type &p, const Primitive_type &q) + : m_is_found(false) , m_point(point) { //, m_p(p),m_q(q) + m_traits_ptr = new AABBTraits(point, p, q); + } + + bool go_further() const { + return !m_is_found; + } + + void intersection(const Primitive &primitive1, const Primitive &primitive2, bool toSwitch) { + if (!toSwitch) { + if (m_traits_ptr->do_intersect_object()(primitive1, primitive2)) { + m_is_found = true; + } + } else { + if (m_traits_ptr->do_intersect_object()(primitive2, primitive1)) { + m_is_found = true; + } + } + } + + bool do_intersect(const Node &node_1, const Node &node_2, bool toSwitch) const { + if (!toSwitch) { + return m_traits_ptr->do_intersect_object()(node_1.bbox(), node_2.bbox()); + } else { + return m_traits_ptr->do_intersect_object()(node_2.bbox(), node_1.bbox()); + } + } + + bool do_intersect(const Node &node_1, const Primitive &primitive2, bool toSwitch) const { + if (!toSwitch) { + return m_traits_ptr->do_intersect_object()(node_1.bbox(), primitive2); + } else { + return m_traits_ptr->do_intersect_object()(primitive2, node_1.bbox()); + } + } + + bool do_intersect(const Primitive &primitive1, const Node &node_2, bool toSwitch) const { + if (!toSwitch) { + return m_traits_ptr->do_intersect_object()(primitive1, node_2.bbox()); + } else { + return m_traits_ptr->do_intersect_object()(node_2.bbox(), primitive1); + } + } + + bool is_intersection_found() const { + return m_is_found; + } + + ~Do_intersect_joined_traits() { + delete m_traits_ptr; + } + + private: + bool m_is_found; + Point m_point; + //Primitive_type& m_p,m_q; + AABBTraits *m_traits_ptr; + }; + + + + /** + * @class Distance_traits + */ + class Distance_traits { + public: + Distance_traits(const Point &hint, + const typename Primitive::Id &hint_primitive) + : m_closest_point(hint), + m_closest_primitive(hint_primitive) { + } + + bool go_further() const { + return true; + } + + void intersection(const Point &query, const Primitive &primitive) { + Point new_closest_point = AABBTraits().closest_point_object() + (query, primitive, m_closest_point); + + if (new_closest_point != m_closest_point) { + m_closest_primitive = primitive.id(); + m_closest_point = new_closest_point; // this effectively shrinks the sphere + } + } + + bool do_intersect(const Point &query, const Node &node) const { + return AABBTraits().compare_distance_object() + (query, node.bbox(), m_closest_point) == CGAL::SMALLER; + } + + Point closest_point() const { + return m_closest_point; + } + Point_and_primitive_id closest_point_and_primitive() const { + return Point_and_primitive_id(m_closest_point, m_closest_primitive); + } + + private: + Point m_closest_point; + typename Primitive::Id m_closest_primitive; + }; + +public: + // returns a point which must be on one primitive + Point_and_primitive_id any_reference_point_and_id() const { + CGAL_assertion(!empty()); + return Point_and_primitive_id(m_primitives[0].reference_point(), m_primitives[0].id()); + } + +public: + Point_and_primitive_id best_hint(const Point &query) const { + /* if(m_search_tree_constructed) + return m_p_search_tree->closest_point(query); + else + return this->any_reference_point_and_id();*/ + } + +private: + // set of input primitives + Primitives m_primitives; + // single root node + Node *m_p_root_node; + // search KD-tree + //Search_tree* m_p_search_tree; + bool m_search_tree_constructed; + +private: + // Disabled copy constructor & assignment operator + typedef AABB_tree Self; + AABB_tree(const Self &src); + Self &operator=(const Self &src); + +}; // end class AABB_tree + +template +AABB_tree::AABB_tree() : m_primitives() , m_p_root_node(NULL) //, m_p_search_tree(NULL) - , m_search_tree_constructed(false) - { } + , m_search_tree_constructed(false) { +} - template - template - AABB_tree::AABB_tree(ConstPrimitiveIterator first, - ConstPrimitiveIterator beyond) - : m_primitives() - , m_p_root_node(NULL) - // , m_p_search_tree(NULL) - , m_search_tree_constructed(false) - { - // Insert each primitive into tree - while ( first != beyond ) - { - m_primitives.push_back(Primitive(first)); - ++first; - } +template +template +AABB_tree::AABB_tree(ConstPrimitiveIterator first, + ConstPrimitiveIterator beyond) + : m_primitives() + , m_p_root_node(NULL) + // , m_p_search_tree(NULL) + , m_search_tree_constructed(false) { + // Insert each primitive into tree + while (first != beyond) { + m_primitives.push_back(Primitive(first)); + ++first; + } - CGAL_assertion(m_primitives.size() > 1); - m_p_root_node = new Node[m_primitives.size()-1](); - if(m_p_root_node == NULL) - { - std::cerr << "Unable to allocate memory for AABB tree" << std::endl; - CGAL_assertion(m_p_root_node != NULL); - m_primitives.clear(); - } - else - m_p_root_node->expand(m_primitives.begin(), m_primitives.end(), m_primitives.size()); - } + CGAL_assertion(m_primitives.size() > 1); + m_p_root_node = new Node[m_primitives.size() - 1](); - // Clears tree and insert a set of primitives - template - template - void AABB_tree::rebuild(ConstPrimitiveIterator first, - ConstPrimitiveIterator beyond) - { - // cleanup current tree and internal KD tree - clear(); + if (m_p_root_node == NULL) { + std::cerr << "Unable to allocate memory for AABB tree" << std::endl; + CGAL_assertion(m_p_root_node != NULL); + m_primitives.clear(); + } else { + m_p_root_node->expand(m_primitives.begin(), m_primitives.end(), m_primitives.size()); + } +} - // inserts primitives - while(first != beyond) - { - m_primitives.push_back(Primitive(first)); - first++; - } +// Clears tree and insert a set of primitives +template +template +void AABB_tree::rebuild(ConstPrimitiveIterator first, + ConstPrimitiveIterator beyond) { + // cleanup current tree and internal KD tree + clear(); - // allocates tree nodes - m_p_root_node = new Node[m_primitives.size()-1](); - if(m_p_root_node == NULL) - { - std::cerr << "Unable to allocate memory for AABB tree" << std::endl; - m_primitives.clear(); - clear(); - } + // inserts primitives + while (first != beyond) { + m_primitives.push_back(Primitive(first)); + first++; + } - // constructs the tree - m_p_root_node->expand(m_primitives.begin(), m_primitives.end(), m_primitives.size()); - } + // allocates tree nodes + m_p_root_node = new Node[m_primitives.size() - 1](); + + if (m_p_root_node == NULL) { + std::cerr << "Unable to allocate memory for AABB tree" << std::endl; + m_primitives.clear(); + clear(); + } + + // constructs the tree + m_p_root_node->expand(m_primitives.begin(), m_primitives.end(), m_primitives.size()); +} - // constructs the search KD tree from given points - // to accelerate the distance queries - template - template - bool AABB_tree::accelerate_distance_queries(ConstPointIterator first, - ConstPointIterator beyond) - { - // clears current KD tree - //clear_search_tree(); +// constructs the search KD tree from given points +// to accelerate the distance queries +template +template +bool AABB_tree::accelerate_distance_queries(ConstPointIterator first, + ConstPointIterator beyond) { + // clears current KD tree + //clear_search_tree(); - /* m_p_search_tree = new Search_tree(first, beyond); - if(m_p_search_tree != NULL) - { - m_search_tree_constructed = true; - return true; - } - else + /* m_p_search_tree = new Search_tree(first, beyond); + if(m_p_search_tree != NULL) + { + m_search_tree_constructed = true; + return true; + } + else { - std::cerr << "Unable to allocate memory for accelerating distance queries" << std::endl; - return false; + std::cerr << "Unable to allocate memory for accelerating distance queries" << std::endl; + return false; }*/ - } +} - // constructs the search KD tree from internal primitives - template - bool AABB_tree::accelerate_distance_queries() - { - CGAL_assertion(!m_primitives.empty()); +// constructs the search KD tree from internal primitives +template +bool AABB_tree::accelerate_distance_queries() { + CGAL_assertion(!m_primitives.empty()); - // iterate over primitives to get reference points on them - std::vector points; - typename Primitives::const_iterator it; - for(it = m_primitives.begin(); it != m_primitives.end(); ++it) - points.push_back(Point_and_primitive_id(it->reference_point(), it->id())); + // iterate over primitives to get reference points on them + std::vector points; + typename Primitives::const_iterator it; - return accelerate_distance_queries(points.begin(), points.end()); - } + for (it = m_primitives.begin(); it != m_primitives.end(); ++it) { + points.push_back(Point_and_primitive_id(it->reference_point(), it->id())); + } - template - template - bool - AABB_tree::do_intersect(const Query& query) const - { - Do_intersect_traits traversal_traits; - this->traversal(query, traversal_traits); - return traversal_traits.is_intersection_found(); - } - + return accelerate_distance_queries(points.begin(), points.end()); +} - template - template - bool AABB_tree::do_intersect_join(const AABB_tree& other,const Point& Translation_point,const Primitive_type& p,const Primitive_type& q) const - { - Do_intersect_joined_traits traversal_traits(Translation_point,p,q); - this->join_traversal(other, traversal_traits); - return traversal_traits.is_intersection_found(); - } +template +template +bool +AABB_tree::do_intersect(const Query &query) const { + Do_intersect_traits traversal_traits; + this->traversal(query, traversal_traits); + return traversal_traits.is_intersection_found(); +} - template - template - typename AABB_tree::size_type - AABB_tree::number_of_intersected_primitives(const Query& query) const - { - Counting_traits traversal_traits; - this->traversal(query, traversal_traits); - return traversal_traits.number_of_intersections(); - } - template - template - OutputIterator - AABB_tree::all_intersected_primitives(const Query& query, - OutputIterator out) const - { - Listing_primitive_traits traversal_traits(out); - this->traversal(query, traversal_traits); - return out; - } +template +template +bool AABB_tree::do_intersect_join(const AABB_tree &other, const Point &Translation_point, const Primitive_type &p, const Primitive_type &q) const { + Do_intersect_joined_traits traversal_traits(Translation_point, p, q); + this->join_traversal(other, traversal_traits); + return traversal_traits.is_intersection_found(); +} - template - template - OutputIterator - AABB_tree::all_intersections(const Query& query, - OutputIterator out) const - { - Listing_intersection_traits traversal_traits(out); - this->traversal(query, traversal_traits); - return out; - } +template +template +typename AABB_tree::size_type +AABB_tree::number_of_intersected_primitives(const Query &query) const { + Counting_traits traversal_traits; + this->traversal(query, traversal_traits); + return traversal_traits.number_of_intersections(); +} - template - template - boost::optional::Object_and_primitive_id> - AABB_tree::any_intersection(const Query& query) const - { - First_intersection_traits traversal_traits; - this->traversal(query, traversal_traits); - return traversal_traits.result(); - } +template +template +OutputIterator +AABB_tree::all_intersected_primitives(const Query &query, + OutputIterator out) const { + Listing_primitive_traits traversal_traits(out); + this->traversal(query, traversal_traits); + return out; +} - template - template - boost::optional::Primitive_id> - AABB_tree::any_intersected_primitive(const Query& query) const - { - First_primitive_traits traversal_traits; - this->traversal(query, traversal_traits); - return traversal_traits.result(); - } +template +template +OutputIterator +AABB_tree::all_intersections(const Query &query, + OutputIterator out) const { + Listing_intersection_traits traversal_traits(out); + this->traversal(query, traversal_traits); + return out; +} - // closest point with user-specified hint - template - typename AABB_tree::Point - AABB_tree::closest_point(const Point& query, - const Point& hint) const - { - typename Primitive::Id hint_primitive = m_primitives[0].id(); - Distance_traits distance_traits(hint,hint_primitive); - this->traversal(query, distance_traits); - return distance_traits.closest_point(); - } +template +template +boost::optional::Object_and_primitive_id> +AABB_tree::any_intersection(const Query &query) const { + First_intersection_traits traversal_traits; + this->traversal(query, traversal_traits); + return traversal_traits.result(); +} - // closest point without hint, the search KD-tree is queried for the - // first closest neighbor point to get a hint - template - typename AABB_tree::Point - AABB_tree::closest_point(const Point& query) const - { - const Point_and_primitive_id hint = best_hint(query); - return closest_point(query,hint.first); - } +template +template +boost::optional::Primitive_id> +AABB_tree::any_intersected_primitive(const Query &query) const { + First_primitive_traits traversal_traits; + this->traversal(query, traversal_traits); + return traversal_traits.result(); +} - // squared distance with user-specified hint - template - typename AABB_tree::FT - AABB_tree::squared_distance(const Point& query, - const Point& hint) const - { - const Point closest = this->closest_point(query, hint); - return typename Tr::Compute_squared_distance_3()(query, closest); - } +// closest point with user-specified hint +template +typename AABB_tree::Point +AABB_tree::closest_point(const Point &query, + const Point &hint) const { + typename Primitive::Id hint_primitive = m_primitives[0].id(); + Distance_traits distance_traits(hint, hint_primitive); + this->traversal(query, distance_traits); + return distance_traits.closest_point(); +} - // squared distance without user-specified hint - template - typename AABB_tree::FT - AABB_tree::squared_distance(const Point& query) const - { - const Point closest = this->closest_point(query); - return typename Tr::Compute_squared_distance_3()(query, closest); - } +// closest point without hint, the search KD-tree is queried for the +// first closest neighbor point to get a hint +template +typename AABB_tree::Point +AABB_tree::closest_point(const Point &query) const { + const Point_and_primitive_id hint = best_hint(query); + return closest_point(query, hint.first); +} - // closest point with user-specified hint - template - typename AABB_tree::Point_and_primitive_id - AABB_tree::closest_point_and_primitive(const Point& query) const - { - return closest_point_and_primitive(query,best_hint(query)); - } +// squared distance with user-specified hint +template +typename AABB_tree::FT +AABB_tree::squared_distance(const Point &query, + const Point &hint) const { + const Point closest = this->closest_point(query, hint); + return typename Tr::Compute_squared_distance_3()(query, closest); +} - // closest point with user-specified hint - template - typename AABB_tree::Point_and_primitive_id - AABB_tree::closest_point_and_primitive(const Point& query, - const Point_and_primitive_id& hint) const - { - Distance_traits distance_traits(hint.first,hint.second); - this->traversal(query, distance_traits); - return distance_traits.closest_point_and_primitive(); - } +// squared distance without user-specified hint +template +typename AABB_tree::FT +AABB_tree::squared_distance(const Point &query) const { + const Point closest = this->closest_point(query); + return typename Tr::Compute_squared_distance_3()(query, closest); +} + +// closest point with user-specified hint +template +typename AABB_tree::Point_and_primitive_id +AABB_tree::closest_point_and_primitive(const Point &query) const { + return closest_point_and_primitive(query, best_hint(query)); +} + +// closest point with user-specified hint +template +typename AABB_tree::Point_and_primitive_id +AABB_tree::closest_point_and_primitive(const Point &query, + const Point_and_primitive_id &hint) const { + Distance_traits distance_traits(hint.first, hint.second); + this->traversal(query, distance_traits); + return distance_traits.closest_point_and_primitive(); +} } // end namespace CGAL diff --git a/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/Arr_SegmentData_traits.h b/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/Arr_SegmentData_traits.h index 485c584a79a..f495fcd10b8 100644 --- a/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/Arr_SegmentData_traits.h +++ b/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/Arr_SegmentData_traits.h @@ -5,647 +5,627 @@ #include #include -namespace CGAL{ - typedef std::pair state; - //enum Segment_color {MY_RED,MY_BLUE}; - struct Segment_Data_Label{ - Segment_Data_Label(state min_id,state max_id,CGAL::Comparison_result orientation,int origin):_min_id(min_id),_max_id(max_id),_orientation(orientation),_origin(origin){} - Segment_Data_Label() - { - _min_id = state(-1,-1); - _max_id = state(-1,-1); - _orientation = CGAL::SMALLER; - _origin = -1; - } +namespace CGAL { +typedef std::pair state; +//enum Segment_color {MY_RED,MY_BLUE}; +struct Segment_Data_Label { + Segment_Data_Label(state min_id, state max_id, CGAL::Comparison_result orientation, int origin): _min_id(min_id), _max_id(max_id), _orientation(orientation), _origin(origin) {} + Segment_Data_Label() { + _min_id = state(-1, -1); + _max_id = state(-1, -1); + _orientation = CGAL::SMALLER; + _origin = -1; + } - /*Segment_Data_Label(const Segment_Data_Label& other) - { - min_id = -1; - max_id = -1; - _orientation = CGAL::SMALLER; - }*/ - //Segment_color _color; - state _min_id,_max_id; - CGAL::Comparison_result _orientation; - int _origin; - bool operator==(const Segment_Data_Label& rhs) const - { - //return _color == rhs._color; - return (this == &rhs); - } - }; + /*Segment_Data_Label(const Segment_Data_Label& other) + { + min_id = -1; + max_id = -1; + _orientation = CGAL::SMALLER; + }*/ + //Segment_color _color; + state _min_id, _max_id; + CGAL::Comparison_result _orientation; + int _origin; + bool operator==(const Segment_Data_Label &rhs) const { + //return _color == rhs._color; + return (this == &rhs); + } +}; -template class Arr_SegmentData_traits : public Traits_//protected Arr_curve_data_traits_2 -{ - +template class Arr_SegmentData_traits : public Traits_ { //protected Arr_curve_data_traits_2 + public: - //typedef Arr_curve_data_traits_2 Base; - typedef Traits_ Base; - typedef typename Base::Intersect_2 Base_intersect_2; - typedef typename Base::Split_2 Base_split_2; - //typedef CGAL::Arr_consolidated_curve_data_traits_2 Data_traits_2; - //typedef typename Arr_SegmentData_traits::Curve_2 Colored_segment_2; - //typedef typename Arr_SegmentData_traits::X_monotone_curve_2 X_monotone_colored_segment_2; - typedef typename Base::Compare_xy_2 Base_compare_xy_2; - typedef typename Base::Construct_min_vertex_2 Base_construct_min_vertex_2; - typedef typename Base::Construct_max_vertex_2 Base_construct_max_vertex_2; - typedef typename Base::Point_2 Base_point_2; + //typedef Arr_curve_data_traits_2 Base; + typedef Traits_ Base; + typedef typename Base::Intersect_2 Base_intersect_2; + typedef typename Base::Split_2 Base_split_2; + //typedef CGAL::Arr_consolidated_curve_data_traits_2 Data_traits_2; + //typedef typename Arr_SegmentData_traits::Curve_2 Colored_segment_2; + //typedef typename Arr_SegmentData_traits::X_monotone_curve_2 X_monotone_colored_segment_2; + typedef typename Base::Compare_xy_2 Base_compare_xy_2; + typedef typename Base::Construct_min_vertex_2 Base_construct_min_vertex_2; + typedef typename Base::Construct_max_vertex_2 Base_construct_max_vertex_2; + typedef typename Base::Point_2 Base_point_2; - typedef typename Base::Curve_2 Base_Curve_2; - typedef typename Base::X_monotone_curve_2 Base_x_monotone_curve_2; - typedef typename Base::Compare_y_at_x_2 Compare_y_at_x_2; - typedef typename Base::Compare_x_2 Compare_x_2; - typedef typename Base::Compare_endpoints_xy_2 Compare_endpoints_xy_2; - typedef typename Base::Compare_y_at_x_right_2 Compare_y_at_x_right_2; -// typedef typename Base::compare_y_at_x_2_object compare_y_at_x_2_object; -// typedef typename Base::compare_x_2_object compare_x_2_object; -// typedef typename Base::compare_endpoints_xy_2_object compare_endpoints_xy_2_object; + typedef typename Base::Curve_2 Base_Curve_2; + typedef typename Base::X_monotone_curve_2 Base_x_monotone_curve_2; + typedef typename Base::Compare_y_at_x_2 Compare_y_at_x_2; + typedef typename Base::Compare_x_2 Compare_x_2; + typedef typename Base::Compare_endpoints_xy_2 Compare_endpoints_xy_2; + typedef typename Base::Compare_y_at_x_right_2 Compare_y_at_x_right_2; +// typedef typename Base::compare_y_at_x_2_object compare_y_at_x_2_object; +// typedef typename Base::compare_x_2_object compare_x_2_object; +// typedef typename Base::compare_endpoints_xy_2_object compare_endpoints_xy_2_object; - //typedef typename Base::Arr_top_side_category Arr_top_side_category; - //typedef typename Base::Arr_right_side_category Arr_right_side_category; - //typedef typename Base::Arr_left_side_category Arr_left_side_category; - //typedef typename Base::Arr_bottom_side_category Arr_bottom_side_category; + //typedef typename Base::Arr_top_side_category Arr_top_side_category; + //typedef typename Base::Arr_right_side_category Arr_right_side_category; + //typedef typename Base::Arr_left_side_category Arr_left_side_category; + //typedef typename Base::Arr_bottom_side_category Arr_bottom_side_category; - typedef typename Base::Has_left_category Has_left_category; - typedef Tag_false Has_merge_category; -// static int count; - - class Ex_point_2 - { - public: + typedef typename Base::Has_left_category Has_left_category; + typedef Tag_false Has_merge_category; +// static int count; - typedef Base_point_2 Base_p; + class Ex_point_2 { + public: - protected: + typedef Base_point_2 Base_p; - Base_p m_base_pt; // The base point. + protected: - public: - state id; - /*! Default constructor. */ - Ex_point_2() : - m_base_pt(),id(state(-1,-1)) + Base_p m_base_pt; // The base point. - {} + public: + state id; + /*! Default constructor. */ + Ex_point_2() : + m_base_pt(), id(state(-1, -1)) - /*! Constructor from a base point. */ - Ex_point_2 (const Base_p& pt) : - m_base_pt (pt),id(state(-1,-1)) + {} - {} + /*! Constructor from a base point. */ + Ex_point_2(const Base_p &pt) : + m_base_pt(pt), id(state(-1, -1)) + + {} - /*! Get the base point (const version). */ - const Base_p& base () const - { - return (m_base_pt); - } - - /*! Get the base point (non-const version). */ - Base_p& base () - { - return (m_base_pt); - } - - /*! Casting to a base point (const version). */ - operator const Base_p& () const - { - return (m_base_pt); - } - - /*! Casting to a base point (non-const version). */ - operator Base_p& () - { - return (m_base_pt); - } - - - }; - - typedef Ex_point_2 Point_2; - - class X_monotone_curve_2 : public Base_x_monotone_curve_2 - { - private: - - Segment_Data_Label _label; - - public: - - /*! Default constructor. */ - X_monotone_curve_2 () - {} - - /*! Constructor from a base x-monotone curve. */ - X_monotone_curve_2 (const Base_x_monotone_curve_2& p) : - Base_x_monotone_curve_2 (p), - _label() - {} - - /*! Constructor from an x-monotone curve an a label. */ - X_monotone_curve_2 (const Base_x_monotone_curve_2& p, - const Segment_Data_Label& label) : - Base_x_monotone_curve_2 (p), - _label (label) - {} - - /*! Get the label (const version). */ - const Segment_Data_Label& label () const - { - return (_label); - } - - const Segment_Data_Label& data () const - { - return (_label); - } - - /*! Get the label (non-const version). */ - Segment_Data_Label& label () - { - return (_label); - } - - Segment_Data_Label& data () - { - return (_label); - } - - /*! Set the label. */ - void set_label (const Segment_Data_Label& label) - { - _label = label; - return; - } - }; - - typedef X_monotone_curve_2 Curve_2; - - class Make_x_monotone_2 - { - public: - /*! - * Cut the given curve into x-monotone subcurves and insert them into the - * given output iterator. As segments are always x_monotone, only one - * object will be contained in the iterator. - * \param cv The curve. - * \param oi The output iterator, whose value-type is Object. - * \return The past-the-end iterator. - */ - template - OutputIterator operator() (const Curve_2& cv, OutputIterator oi) const - { - // Wrap the segment with an object. - *oi = make_object (cv); - ++oi; - return (oi); - } - }; - - /*! Get a Make_x_monotone_2 functor object. */ - Make_x_monotone_2 make_x_monotone_2_object () const - { - return Make_x_monotone_2(); - } - - class Split_2 - { - private: - - const Traits_* m_traits; - - public: - - /*! Constructor. */ - Split_2 (const Base* _base) : - m_traits (_base) - {} - - /*! - * Split a given x-monotone curve at a given point into two sub-curves. - */ - void operator() (const X_monotone_curve_2& cv, const Point_2& p, - X_monotone_curve_2& c1, X_monotone_curve_2& c2) const - { - // Split the base curve into two. - m_traits->split_2_object() (cv, p, c1, c2); - if (cv.data()._orientation == CGAL::SMALLER) - { - c1.data()._min_id = cv.data()._min_id; - c2.data()._max_id = cv.data()._max_id; - } - else - { - c1.data()._min_id = cv.data()._max_id; - c2.data()._max_id = cv.data()._min_id; - } - c1.data()._orientation = cv.data()._orientation; - c2.data()._orientation = cv.data()._orientation; - // Duplicate the label to both subcurves. - // c1.set_label (cv.label()); - //c2.set_label (cv.label()); - - return; - } - }; - - /*! Get a Split_2 functor object. */ - Split_2 split_2_object () const - { - return (Split_2 (this)); - } - - - class Intersect_2 { - protected: - //! The base traits. - const Traits_* m_traits; - - /*! Constructor. - * The constructor is declared protected to allow only the functor - * obtaining function, which is a member of the nesting class, - * constructing it. - */ - Intersect_2(const Traits_* traits) : m_traits(traits) {} - - //! Allow its functor obtaining function calling the protected constructor. - friend class Arr_SegmentData_traits; - - public: - template - OutputIterator operator() (const X_monotone_curve_2 & xcv1, - const X_monotone_curve_2 & xcv2, - OutputIterator oi) - { - state no_state = state(-1,-1); - // In case the curves originate from the same arrangement, they are - // obviously interior-disjoint. - //if (xcv1.data().front() == xcv2.data().front()) - // if (xcv1.data().front()._color == xcv2.data().front()._color) - // return (oi); - //Arr_SegmentData_traits::count++; - - // Ignore edges which originates from the same polygon and are added to the same vertex. - if (xcv1.data()._origin == xcv2.data()._origin ) - { - if ((xcv1.data()._origin == 0 && ((xcv1.data()._min_id.second == xcv2.data()._min_id.second)) || - (xcv1.data()._origin == 1 && ((xcv1.data()._min_id.first == xcv2.data()._min_id.first) )))) - return oi; - } - - Construct_min_vertex_2 min_vertex_obj = m_traits->construct_min_vertex_2_object(); - Construct_max_vertex_2 max_vertex_obj = m_traits->construct_max_vertex_2_object(); - //++_my_global_counter; - int endp_coll =0; - - if ((xcv1.data()._min_id == xcv2.data()._min_id) && (xcv2.data()._min_id != no_state)){ - return oi; - if (xcv1.data()._orientation == CGAL::SMALLER) - *oi = CGAL::make_object(std::make_pair (min_vertex_obj (xcv1),1)); - else - *oi = CGAL::make_object(std::make_pair (max_vertex_obj (xcv1),1)); - ++oi; - return oi; - //++endp_coll; - } - if ((xcv1.data()._min_id == xcv2.data()._max_id) && (xcv2.data()._max_id != no_state)) - { - return oi; - if (xcv1.data()._orientation == CGAL::SMALLER) - *oi = CGAL::make_object(std::make_pair (min_vertex_obj (xcv1),1)); - else - *oi = CGAL::make_object(std::make_pair (max_vertex_obj (xcv1),1)); - ++oi; - return oi; - // ++endp_coll; - } - if ((xcv1.data()._max_id == xcv2.data()._min_id) && (xcv2.data()._min_id != no_state)) - { - return oi; - if (xcv1.data()._orientation == CGAL::SMALLER) - *oi = CGAL::make_object(std::make_pair (max_vertex_obj (xcv1),1)); - else - *oi = CGAL::make_object(std::make_pair (min_vertex_obj (xcv1),1)); - - ++oi; - return oi; - // ++endp_coll; - } - - if ((xcv1.data()._max_id == xcv2.data()._max_id) && (xcv2.data()._max_id != no_state)) - { - return oi; - if (xcv1.data()._orientation == CGAL::SMALLER) - *oi = CGAL::make_object(std::make_pair (max_vertex_obj (xcv1),1)); - else - *oi = CGAL::make_object(std::make_pair (min_vertex_obj (xcv1),1)); - - ++oi; - return oi; - // ++endp_coll; - } - - - if (endp_coll == 1) - return oi; - - // state temp = xcv1.data()._min_id; - - // Base::Intersect_2 int_obj = Base::Intersect_2(m_traits); - // std::vector temp_container; - //const std::pair - - //OutputIterator oi_temp; - - //OutputIterator oi_end = - // code ONLY FOR SEGMENTS !!!!!!!! - - std::list base_objs; - - m_traits->intersect_2_object() (xcv1, xcv2, std::back_inserter (base_objs)); - - if (base_objs.empty()) - return (oi); - - // Attach labels to the intersection objects. - std::list::iterator obj_it; - const std::pair *base_pt; - const Base_x_monotone_curve_2 *base_xcv; - - for (obj_it = base_objs.begin(); obj_it != base_objs.end(); ++obj_it) - { - base_pt = - object_cast > (&(*obj_it)); - - if (base_pt != NULL) - { - // Attach an invalid label to an itersection point. - *oi = CGAL::make_object - (std::make_pair (Point_2 (base_pt->first), base_pt->second)); - ++oi; + /*! Get the base point (const version). */ + const Base_p &base() const { + return (m_base_pt); } - else - { - base_xcv = object_cast (&(*obj_it)); - CGAL_assertion (base_xcv != NULL); - // Attach a merged label to the overlapping curve. - *oi = CGAL::make_object (X_monotone_curve_2 (*base_xcv,Segment_Data_Label(no_state,no_state,xcv1.data()._orientation,-1))); - ++oi; + /*! Get the base point (non-const version). */ + Base_p &base() { + return (m_base_pt); + } + + /*! Casting to a base point (const version). */ + operator const Base_p &() const { + return (m_base_pt); + } + + /*! Casting to a base point (non-const version). */ + operator Base_p &() { + return (m_base_pt); } - } + }; - // CGAL::Object temp_obj; - // CGAL::Object* output = &temp_obj; - // int_obj(xcv1,xcv2,output); - // const std::pair *xp_point; - // const Base_x_monotone_curve_2 *base_xcv; + typedef Ex_point_2 Point_2; - // xp_point = object_cast > (output); - // if (xp_point!=NULL) - // { - // *oi = CGAL::make_object(std::make_pair (Point_2(xp_point->first), - // xp_point->second)); - // ++oi; - //} - // else{ - // base_xcv = object_cast (output); - // if (base_xcv!=NULL) - // { - // *oi = CGAL::make_object (X_monotone_curve_2 (*base_xcv,Segment_Data_Label(no_state,no_state,xcv1.data()._orientation))); - // ++oi; - // } - // } - /*else - { - *oi = *output; - ++oi; - }*/ - //if (oi == oi_end) - // return oi_end; -/* if (temp_container.size() == 0) - return oi; - const std::pair *xp_point; - for (std::vector::iterator itr = temp_container.begin();itr != temp_container.end();++itr) - { - xp_point = object_cast > (&(*itr)); - if (xp_point!=NULL) - { - *oi = CGAL::make_object(std::make_pair (Point_2(xp_point->first), - xp_point->second)); - ++oi; - } - } - */ - /* - for (;oi!=oi_end;++oi) - { - xp_point = object_cast > (&(*oi)); - if (xp_point!=NULL) - { - *oi = CGAL::make_object(std::make_pair (Point_2(xp_point->first), - xp_point->second)); - } - } + class X_monotone_curve_2 : public Base_x_monotone_curve_2 { + private: - */ - //if (xcv1.color() == RB_OVERLAP || xcv2.color() == RB_OVERLAP) - return (oi); + Segment_Data_Label _label; + + public: + + /*! Default constructor. */ + X_monotone_curve_2() { + } + + /*! Constructor from a base x-monotone curve. */ + X_monotone_curve_2(const Base_x_monotone_curve_2 &p) : + Base_x_monotone_curve_2(p), + _label() { + } + + /*! Constructor from an x-monotone curve an a label. */ + X_monotone_curve_2(const Base_x_monotone_curve_2 &p, + const Segment_Data_Label &label) : + Base_x_monotone_curve_2(p), + _label(label) { + } + + /*! Get the label (const version). */ + const Segment_Data_Label &label() const { + return (_label); + } + + const Segment_Data_Label &data() const { + return (_label); + } + + /*! Get the label (non-const version). */ + Segment_Data_Label &label() { + return (_label); + } + + Segment_Data_Label &data() { + return (_label); + } + + /*! Set the label. */ + void set_label(const Segment_Data_Label &label) { + _label = label; + return; + } + }; + + typedef X_monotone_curve_2 Curve_2; + + class Make_x_monotone_2 { + public: + /*! + * Cut the given curve into x-monotone subcurves and insert them into the + * given output iterator. As segments are always x_monotone, only one + * object will be contained in the iterator. + * \param cv The curve. + * \param oi The output iterator, whose value-type is Object. + * \return The past-the-end iterator. + */ + template + OutputIterator operator()(const Curve_2 &cv, OutputIterator oi) const { + // Wrap the segment with an object. + *oi = make_object(cv); + ++oi; + return (oi); + } + }; + + /*! Get a Make_x_monotone_2 functor object. */ + Make_x_monotone_2 make_x_monotone_2_object() const { + return Make_x_monotone_2(); } - - }; - /*! Obtain an Intersect_2 functor object. */ - Intersect_2 intersect_2_object () const - { - return Intersect_2(this); - } + class Split_2 { + private: - - //class Ex_point_2 : public Point_2 - //{ - //public: - // Ex_point_2(Point_2& p) - // { + const Traits_ *m_traits; - // } - // int id; - //}; + public: - class Compare_xy_2 { - protected: - //! The base operator. - Base_compare_xy_2 m_base_cmp_xy; + /*! Constructor. */ + Split_2(const Base *_base) : + m_traits(_base) { + } - /*! Constructor. - * The constructor is declared protected to allow only the functor - * obtaining function, which is a member of the nesting class, - * constructing it. - */ - Compare_xy_2(const Base_compare_xy_2& base) : - m_base_cmp_xy(base) - {} + /*! + * Split a given x-monotone curve at a given point into two sub-curves. + */ + void operator()(const X_monotone_curve_2 &cv, const Point_2 &p, + X_monotone_curve_2 &c1, X_monotone_curve_2 &c2) const { + // Split the base curve into two. + m_traits->split_2_object()(cv, p, c1, c2); - //! Allow its functor obtaining function calling the protected constructor. - friend class Arr_SegmentData_traits; - - public: - Comparison_result operator() (const Point_2& p1, const Point_2& p2) const - { -// if (&p1 == &p2) - //Ex_point_2 p1_e,p2_e; - //p1_e = *dynamic_cast(&p1); - //p2_e = *dynamic_cast(&p2); - if ((p1.id == p2.id) && (p1.id != state(-1,-1))) - return EQUAL; + if (cv.data()._orientation == CGAL::SMALLER) { + c1.data()._min_id = cv.data()._min_id; + c2.data()._max_id = cv.data()._max_id; + } else { + c1.data()._min_id = cv.data()._max_id; + c2.data()._max_id = cv.data()._min_id; + } - return m_base_cmp_xy(p1,p2); - } - }; + c1.data()._orientation = cv.data()._orientation; + c2.data()._orientation = cv.data()._orientation; + // Duplicate the label to both subcurves. + // c1.set_label (cv.label()); + //c2.set_label (cv.label()); - /*! Obtain a Construct_min_vertex_2 functor object. */ - Compare_xy_2 compare_xy_2_object () const - { - //Base::Compare_xy_2 obj(); - return (Compare_xy_2(((Base*)this)->compare_xy_2_object())); - } + return; + } + }; - - - /*! A functor that obtains the left endpoint of an x-monotone curve. */ - class Construct_min_vertex_2 { - protected: - //! The base operators. - Base_construct_min_vertex_2 m_base_min_v; - //Base_equal_2 m_base_equal; - - /*! Constructor. - * The constructor is declared protected to allow only the functor - * obtaining function, which is a member of the nesting class, - * constructing it. - */ - Construct_min_vertex_2 (const Base_construct_min_vertex_2& base_min_v - ) : - m_base_min_v (base_min_v) - {} - - //! Allow its functor obtaining function calling the protected constructor. - friend class Arr_SegmentData_traits; - - public: - Point_2 operator() (const X_monotone_curve_2& xcv) - { - Point_2 min_p = m_base_min_v (xcv); - /* if (xcv.data().size()>1) - min_p.id = -1; - else*/ - if (xcv.label()._orientation == CGAL::SMALLER) - min_p.id = xcv.data()._min_id; - else - min_p.id = xcv.data()._max_id; - return (min_p); + /*! Get a Split_2 functor object. */ + Split_2 split_2_object() const { + return (Split_2(this)); } - }; - /*! Obtain a Construct_min_vertex_2 functor object. */ - Construct_min_vertex_2 construct_min_vertex_2_object () const - { - return - (Construct_min_vertex_2 (((Base*)this)->construct_min_vertex_2_object())); - } - - /*! A functor that obtains the right endpoint of an x-monotone curve. */ - class Construct_max_vertex_2 { - protected: - //! The base operators. - Base_construct_max_vertex_2 m_base_max_v; - - /*! Constructor. - * The constructor is declared protected to allow only the functor - * obtaining function, which is a member of the nesting class, - * constructing it. - */ - Construct_max_vertex_2 (const Base_construct_max_vertex_2& base_max_v) : - m_base_max_v (base_max_v) - - {} + class Intersect_2 { + protected: + //! The base traits. + const Traits_ *m_traits; - //! Allow its functor obtaining function calling the protected constructor. - friend class Arr_SegmentData_traits; - - public: - Point_2 operator() (const X_monotone_curve_2 & xcv) const - { - Point_2 max_p = m_base_max_v (xcv); - /* if (xcv.data().size()>1) - max_p.id = -1; - else*/ - if (xcv.label()._orientation == CGAL::SMALLER) - max_p.id = xcv.data()._max_id; - else - max_p.id = xcv.data()._min_id; - - //max_p.id = xcv.data()._max_id; - return (max_p); + /*! Constructor. + * The constructor is declared protected to allow only the functor + * obtaining function, which is a member of the nesting class, + * constructing it. + */ + Intersect_2(const Traits_* traits) : m_traits(traits) {} + + //! Allow its functor obtaining function calling the protected constructor. + friend class Arr_SegmentData_traits; + + public: + template + OutputIterator operator()(const X_monotone_curve_2 &xcv1, + const X_monotone_curve_2 &xcv2, + OutputIterator oi) { + state no_state = state(-1, -1); + // In case the curves originate from the same arrangement, they are + // obviously interior-disjoint. + //if (xcv1.data().front() == xcv2.data().front()) + // if (xcv1.data().front()._color == xcv2.data().front()._color) + // return (oi); + //Arr_SegmentData_traits::count++; + + // Ignore edges which originates from the same polygon and are added to the same vertex. + if (xcv1.data()._origin == xcv2.data()._origin) { + if ((xcv1.data()._origin == 0 && ((xcv1.data()._min_id.second == xcv2.data()._min_id.second)) || + (xcv1.data()._origin == 1 && ((xcv1.data()._min_id.first == xcv2.data()._min_id.first))))) { + return oi; + } + } + + Construct_min_vertex_2 min_vertex_obj = m_traits->construct_min_vertex_2_object(); + Construct_max_vertex_2 max_vertex_obj = m_traits->construct_max_vertex_2_object(); + //++_my_global_counter; + int endp_coll = 0; + + if ((xcv1.data()._min_id == xcv2.data()._min_id) && (xcv2.data()._min_id != no_state)) { + return oi; + + if (xcv1.data()._orientation == CGAL::SMALLER) { + *oi = CGAL::make_object(std::make_pair(min_vertex_obj(xcv1), 1)); + } else { + *oi = CGAL::make_object(std::make_pair(max_vertex_obj(xcv1), 1)); + } + + ++oi; + return oi; + //++endp_coll; + } + + if ((xcv1.data()._min_id == xcv2.data()._max_id) && (xcv2.data()._max_id != no_state)) { + return oi; + + if (xcv1.data()._orientation == CGAL::SMALLER) { + *oi = CGAL::make_object(std::make_pair(min_vertex_obj(xcv1), 1)); + } else { + *oi = CGAL::make_object(std::make_pair(max_vertex_obj(xcv1), 1)); + } + + ++oi; + return oi; + // ++endp_coll; + } + + if ((xcv1.data()._max_id == xcv2.data()._min_id) && (xcv2.data()._min_id != no_state)) { + return oi; + + if (xcv1.data()._orientation == CGAL::SMALLER) { + *oi = CGAL::make_object(std::make_pair(max_vertex_obj(xcv1), 1)); + } else { + *oi = CGAL::make_object(std::make_pair(min_vertex_obj(xcv1), 1)); + } + + ++oi; + return oi; + // ++endp_coll; + } + + if ((xcv1.data()._max_id == xcv2.data()._max_id) && (xcv2.data()._max_id != no_state)) { + return oi; + + if (xcv1.data()._orientation == CGAL::SMALLER) { + *oi = CGAL::make_object(std::make_pair(max_vertex_obj(xcv1), 1)); + } else { + *oi = CGAL::make_object(std::make_pair(min_vertex_obj(xcv1), 1)); + } + + ++oi; + return oi; + // ++endp_coll; + } + + + if (endp_coll == 1) { + return oi; + } + + // state temp = xcv1.data()._min_id; + + // Base::Intersect_2 int_obj = Base::Intersect_2(m_traits); + // std::vector temp_container; + //const std::pair + + //OutputIterator oi_temp; + + //OutputIterator oi_end = + // code ONLY FOR SEGMENTS !!!!!!!! + + std::list base_objs; + + m_traits->intersect_2_object()(xcv1, xcv2, std::back_inserter(base_objs)); + + if (base_objs.empty()) { + return (oi); + } + + // Attach labels to the intersection objects. + std::list::iterator obj_it; + const std::pair *base_pt; + const Base_x_monotone_curve_2 *base_xcv; + + for (obj_it = base_objs.begin(); obj_it != base_objs.end(); ++obj_it) { + base_pt = + object_cast > (&(*obj_it)); + + if (base_pt != NULL) { + // Attach an invalid label to an itersection point. + *oi = CGAL::make_object + (std::make_pair(Point_2(base_pt->first), base_pt->second)); + ++oi; + } else { + base_xcv = object_cast (&(*obj_it)); + CGAL_assertion(base_xcv != NULL); + + // Attach a merged label to the overlapping curve. + *oi = CGAL::make_object(X_monotone_curve_2(*base_xcv, Segment_Data_Label(no_state, no_state, xcv1.data()._orientation, -1))); + ++oi; + } + } + + + + // CGAL::Object temp_obj; + // CGAL::Object* output = &temp_obj; + // int_obj(xcv1,xcv2,output); + // const std::pair *xp_point; + // const Base_x_monotone_curve_2 *base_xcv; + + // xp_point = object_cast > (output); + // if (xp_point!=NULL) + // { + // *oi = CGAL::make_object(std::make_pair (Point_2(xp_point->first), + // xp_point->second)); + // ++oi; + //} + // else{ + // base_xcv = object_cast (output); + // if (base_xcv!=NULL) + // { + // *oi = CGAL::make_object (X_monotone_curve_2 (*base_xcv,Segment_Data_Label(no_state,no_state,xcv1.data()._orientation))); + // ++oi; + // } + // } + /*else + { + *oi = *output; + ++oi; + }*/ + //if (oi == oi_end) + // return oi_end; + /* if (temp_container.size() == 0) + return oi; + const std::pair *xp_point; + for (std::vector::iterator itr = temp_container.begin();itr != temp_container.end();++itr) + { + xp_point = object_cast > (&(*itr)); + if (xp_point!=NULL) + { + *oi = CGAL::make_object(std::make_pair (Point_2(xp_point->first), + xp_point->second)); + ++oi; + } + } + */ + /* + for (;oi!=oi_end;++oi) + { + xp_point = object_cast > (&(*oi)); + if (xp_point!=NULL) + { + *oi = CGAL::make_object(std::make_pair (Point_2(xp_point->first), + xp_point->second)); + } + } + + */ + //if (xcv1.color() == RB_OVERLAP || xcv2.color() == RB_OVERLAP) + return (oi); + } + + }; + + /*! Obtain an Intersect_2 functor object. */ + Intersect_2 intersect_2_object() const { + return Intersect_2(this); } - }; - /*! Obtain a Construct_min_vertex_2 functor object. */ - Construct_max_vertex_2 construct_max_vertex_2_object () const - { - return - (Construct_max_vertex_2 (((Base*)this)->construct_max_vertex_2_object())); - } - Compare_y_at_x_2 compare_y_at_x_2_object () const - { - //Base::Compare_xy_2 obj(); - return (Compare_y_at_x_2(((Base*)this)->compare_y_at_x_2_object())); - } + //class Ex_point_2 : public Point_2 + //{ + //public: + // Ex_point_2(Point_2& p) + // { - Compare_x_2 compare_x_2_object () const - { - //Base::Compare_xy_2 obj(); - return (Compare_x_2(((Base*)this)->compare_x_2_object())); - } + // } + // int id; + //}; - Compare_endpoints_xy_2 compare_endpoints_xy_2_object () const - { - //Base::Compare_xy_2 obj(); - return (Compare_endpoints_xy_2(((Base*)this)->compare_endpoints_xy_2_object())); - } + class Compare_xy_2 { + protected: + //! The base operator. + Base_compare_xy_2 m_base_cmp_xy; - Compare_y_at_x_right_2 compare_y_at_x_right_2_object() const - { - //Base::Compare_xy_2 obj(); - return (Compare_y_at_x_right_2(((Base*)this)->compare_y_at_x_right_2_object())); - } + /*! Constructor. + * The constructor is declared protected to allow only the functor + * obtaining function, which is a member of the nesting class, + * constructing it. + */ + Compare_xy_2(const Base_compare_xy_2 &base) : + m_base_cmp_xy(base) { + } + + //! Allow its functor obtaining function calling the protected constructor. + friend class Arr_SegmentData_traits; + + public: + Comparison_result operator()(const Point_2 &p1, const Point_2 &p2) const { +// if (&p1 == &p2) + //Ex_point_2 p1_e,p2_e; + //p1_e = *dynamic_cast(&p1); + //p2_e = *dynamic_cast(&p2); + if ((p1.id == p2.id) && (p1.id != state(-1, -1))) { + return EQUAL; + } + + return m_base_cmp_xy(p1, p2); + } + }; + + /*! Obtain a Construct_min_vertex_2 functor object. */ + Compare_xy_2 compare_xy_2_object() const { + //Base::Compare_xy_2 obj(); + return (Compare_xy_2(((Base *)this)->compare_xy_2_object())); + } + + + + /*! A functor that obtains the left endpoint of an x-monotone curve. */ + class Construct_min_vertex_2 { + protected: + //! The base operators. + Base_construct_min_vertex_2 m_base_min_v; + //Base_equal_2 m_base_equal; + + /*! Constructor. + * The constructor is declared protected to allow only the functor + * obtaining function, which is a member of the nesting class, + * constructing it. + */ + Construct_min_vertex_2(const Base_construct_min_vertex_2 &base_min_v + ) : + m_base_min_v(base_min_v) { + } + + //! Allow its functor obtaining function calling the protected constructor. + friend class Arr_SegmentData_traits; + + public: + Point_2 operator()(const X_monotone_curve_2 &xcv) { + Point_2 min_p = m_base_min_v(xcv); + + /* if (xcv.data().size()>1) + min_p.id = -1; + else*/ + if (xcv.label()._orientation == CGAL::SMALLER) { + min_p.id = xcv.data()._min_id; + } else { + min_p.id = xcv.data()._max_id; + } + + return (min_p); + } + }; + + /*! Obtain a Construct_min_vertex_2 functor object. */ + Construct_min_vertex_2 construct_min_vertex_2_object() const { + return + (Construct_min_vertex_2(((Base *)this)->construct_min_vertex_2_object())); + } + + /*! A functor that obtains the right endpoint of an x-monotone curve. */ + class Construct_max_vertex_2 { + protected: + //! The base operators. + Base_construct_max_vertex_2 m_base_max_v; + + + /*! Constructor. + * The constructor is declared protected to allow only the functor + * obtaining function, which is a member of the nesting class, + * constructing it. + */ + Construct_max_vertex_2(const Base_construct_max_vertex_2 &base_max_v) : + m_base_max_v(base_max_v) + + {} + + //! Allow its functor obtaining function calling the protected constructor. + friend class Arr_SegmentData_traits; + + public: + Point_2 operator()(const X_monotone_curve_2 &xcv) const { + Point_2 max_p = m_base_max_v(xcv); + + /* if (xcv.data().size()>1) + max_p.id = -1; + else*/ + if (xcv.label()._orientation == CGAL::SMALLER) { + max_p.id = xcv.data()._max_id; + } else { + max_p.id = xcv.data()._min_id; + } + + //max_p.id = xcv.data()._max_id; + return (max_p); + } + }; + + /*! Obtain a Construct_min_vertex_2 functor object. */ + Construct_max_vertex_2 construct_max_vertex_2_object() const { + return + (Construct_max_vertex_2(((Base *)this)->construct_max_vertex_2_object())); + } + + Compare_y_at_x_2 compare_y_at_x_2_object() const { + //Base::Compare_xy_2 obj(); + return (Compare_y_at_x_2(((Base *)this)->compare_y_at_x_2_object())); + } + + Compare_x_2 compare_x_2_object() const { + //Base::Compare_xy_2 obj(); + return (Compare_x_2(((Base *)this)->compare_x_2_object())); + } + + Compare_endpoints_xy_2 compare_endpoints_xy_2_object() const { + //Base::Compare_xy_2 obj(); + return (Compare_endpoints_xy_2(((Base *)this)->compare_endpoints_xy_2_object())); + } + + Compare_y_at_x_right_2 compare_y_at_x_right_2_object() const { + //Base::Compare_xy_2 obj(); + return (Compare_y_at_x_right_2(((Base *)this)->compare_y_at_x_right_2_object())); + } }; //template class Arr_SegmentData_traits : public Arr_curve_data_traits_2 //{ -// -//public: -// typedef Arr_curve_data_traits_2 Base; -// typedef typename Base::Intersect_2 Base_intersect_2; -// //typedef CGAL::Arr_consolidated_curve_data_traits_2 Data_traits_2; -// typedef typename Arr_SegmentData_traits::Curve_2 Colored_segment_2; -// typedef typename Arr_SegmentData_traits::X_monotone_curve_2 X_monotone_colored_segment_2; -// typedef typename Arr_SegmentData_traits::X_monotone_curve_2 X_monotone_curve_2; -// typedef typename Base::Compare_xy_2 Base_compare_xy_2; -// typedef typename Base::Construct_min_vertex_2 Base_construct_min_vertex_2; -// typedef typename Base::Construct_max_vertex_2 Base_construct_max_vertex_2; -// typedef typename Base::Point_2 Base_point_2; -// typedef typename Base::Curve_2 Base_curve_2; // -// class Intersect_2 { +//public: +// typedef Arr_curve_data_traits_2 Base; +// typedef typename Base::Intersect_2 Base_intersect_2; +// //typedef CGAL::Arr_consolidated_curve_data_traits_2 Data_traits_2; +// typedef typename Arr_SegmentData_traits::Curve_2 Colored_segment_2; +// typedef typename Arr_SegmentData_traits::X_monotone_curve_2 X_monotone_colored_segment_2; +// typedef typename Arr_SegmentData_traits::X_monotone_curve_2 X_monotone_curve_2; +// typedef typename Base::Compare_xy_2 Base_compare_xy_2; +// typedef typename Base::Construct_min_vertex_2 Base_construct_min_vertex_2; +// typedef typename Base::Construct_max_vertex_2 Base_construct_max_vertex_2; +// typedef typename Base::Point_2 Base_point_2; +// typedef typename Base::Curve_2 Base_curve_2; +// +// class Intersect_2 { // protected: // //! The base traits. // const Arr_curve_data_traits_2* m_traits; @@ -659,7 +639,7 @@ public: // // //! Allow its functor obtaining function calling the protected constructor. // friend class Arr_SegmentData_traits; -// +// // public: // template // OutputIterator operator() (const X_monotone_colored_segment_2 & xcv1, @@ -671,37 +651,37 @@ public: // // // //if (xcv1.data().front() == xcv2.data().front()) -// //if (xcv1.data().front()._color == xcv2.data().front()._color) +// //if (xcv1.data().front()._color == xcv2.data().front()._color) // //return (oi); -// Base::Intersect_2 int_obj = Base::Intersect_2(m_traits); -// //OutputIterator oi_temp; -// OutputIterator oi_end = int_obj(xcv1,xcv2,oi); -// if (oi == oi_end) -// return oi_end; -// const std::pair *xp_point; -// for (;oi!=oi_end;++oi) -// { -// xp_point = object_cast > (&(*oi)); -// if (xp_point!=NULL) -// { -// *oi = CGAL::make_object(std::make_pair (Point_2(xp_point->first), -// xp_point->second)); -// } -// } -// +// Base::Intersect_2 int_obj = Base::Intersect_2(m_traits); +// //OutputIterator oi_temp; +// OutputIterator oi_end = int_obj(xcv1,xcv2,oi); +// if (oi == oi_end) +// return oi_end; +// const std::pair *xp_point; +// for (;oi!=oi_end;++oi) +// { +// xp_point = object_cast > (&(*oi)); +// if (xp_point!=NULL) +// { +// *oi = CGAL::make_object(std::make_pair (Point_2(xp_point->first), +// xp_point->second)); +// } +// } +// // //if (xcv1.color() == RB_OVERLAP || xcv2.color() == RB_OVERLAP) // return (oi); // } -// +// // }; // // /*! Obtain an Intersect_2 functor object. */ // Intersect_2 intersect_2_object () const // { -// return Intersect_2(this); +// return Intersect_2(this); // } // -// class Ex_point_2 +// class Ex_point_2 // { // public: // @@ -712,7 +692,7 @@ public: // Base_p m_base_pt; // The base point. // // public: -// int id; +// int id; // /*! Default constructor. */ // Ex_point_2() : // m_base_pt(),id(-1) @@ -750,7 +730,7 @@ public: // return (m_base_pt); // } // -// +// // }; // // typedef Ex_point_2 Point_2; @@ -759,16 +739,16 @@ public: // //class Ex_point_2 : public Point_2 // //{ // //public: -// // Ex_point_2(Point_2& p) -// // { +// // Ex_point_2(Point_2& p) +// // { // -// // } -// // int id; +// // } +// // int id; // //}; // // class Compare_xy_2 { // protected: -// //! The base operator. +// //! The base operator. // Base_compare_xy_2 m_base_cmp_xy; // // /*! Constructor. @@ -782,30 +762,30 @@ public: // // //! Allow its functor obtaining function calling the protected constructor. // friend class Arr_SegmentData_traits; -// +// // public: // Comparison_result operator() (const Point_2& p1, const Point_2& p2) const -// { -//// if (&p1 == &p2) -// //Ex_point_2 p1_e,p2_e; -// //p1_e = *dynamic_cast(&p1); -// //p2_e = *dynamic_cast(&p2); -// if ((p1.id == p2.id) && (p1.id != -1)) -// return EQUAL; +// { +//// if (&p1 == &p2) +// //Ex_point_2 p1_e,p2_e; +// //p1_e = *dynamic_cast(&p1); +// //p2_e = *dynamic_cast(&p2); +// if ((p1.id == p2.id) && (p1.id != -1)) +// return EQUAL; // -// return m_base_cmp_xy(p1,p2); -// } +// return m_base_cmp_xy(p1,p2); +// } // }; // // /*! Obtain a Construct_min_vertex_2 functor object. */ // Compare_xy_2 compare_xy_2_object () const // { -// //Base::Compare_xy_2 obj(); +// //Base::Compare_xy_2 obj(); // return (Compare_xy_2(((Base*)this)->compare_xy_2_object())); // } // // -// +// // /*! A functor that obtains the left endpoint of an x-monotone curve. */ // class Construct_min_vertex_2 { // protected: @@ -825,32 +805,32 @@ public: // // //! Allow its functor obtaining function calling the protected constructor. // friend class Arr_SegmentData_traits; -// +// // public: -// Point_2 operator() (const X_monotone_curve_2& xcv) +// Point_2 operator() (const X_monotone_curve_2& xcv) // { -// Point_2 min_p = m_base_min_v (xcv); -// /* if (xcv.data().size()>1) -// min_p.id = -1; -// else*/ -// min_p.id = xcv.data()._min_id; -// return (min_p); +// Point_2 min_p = m_base_min_v (xcv); +// /* if (xcv.data().size()>1) +// min_p.id = -1; +// else*/ +// min_p.id = xcv.data()._min_id; +// return (min_p); // } // }; // // /*! Obtain a Construct_min_vertex_2 functor object. */ // Construct_min_vertex_2 construct_min_vertex_2_object () const // { -// return +// return // (Construct_min_vertex_2 (((Base*)this)->construct_min_vertex_2_object())); // } -// +// // /*! A functor that obtains the right endpoint of an x-monotone curve. */ // class Construct_max_vertex_2 { // protected: // //! The base operators. // Base_construct_max_vertex_2 m_base_max_v; -// +// // // /*! Constructor. // * The constructor is declared protected to allow only the functor @@ -859,21 +839,21 @@ public: // */ // Construct_max_vertex_2 (const Base_construct_max_vertex_2& base_max_v) : // m_base_max_v (base_max_v) -// +// // {} // // //! Allow its functor obtaining function calling the protected constructor. // friend class Arr_SegmentData_traits; -// +// // public: // Point_2 operator() (const X_monotone_curve_2 & xcv) const // { -// Point_2 max_p = m_base_max_v (xcv); -// /* if (xcv.data().size()>1) -// max_p.id = -1; -// else*/ -// max_p.id = xcv.data()._max_id; -// return (max_p); +// Point_2 max_p = m_base_max_v (xcv); +// /* if (xcv.data().size()>1) +// max_p.id = -1; +// else*/ +// max_p.id = xcv.data()._max_id; +// return (max_p); // } // }; // diff --git a/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/BounderyConvCalc.h b/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/BounderyConvCalc.h index d677a7856b1..f11c187fb1d 100644 --- a/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/BounderyConvCalc.h +++ b/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/BounderyConvCalc.h @@ -5,24 +5,23 @@ #include #include -template class BounderyConvCalc: public IBounderySumCalculator< Kernel_, Container_>{ +template class BounderyConvCalc: public IBounderySumCalculator< Kernel_, Container_> { public: - typedef Arr_segment_traits_2 Traits_2;//Segment_traits_2; - typedef typename Traits_2::X_monotone_curve_2 Segment_2; - typedef std::list Segments_list; + typedef Arr_segment_traits_2 Traits_2;//Segment_traits_2; + typedef typename Traits_2::X_monotone_curve_2 Segment_2; + typedef std::list Segments_list; - virtual void calc_sum(Polygon_2& a,Polygon_2& b,Polygon_2& res_poly) - { - Segments_list reduced_conv; - _mink->buildReducedConvolution(a, b, reduced_conv); + virtual void calc_sum(Polygon_2 &a, Polygon_2 &b, Polygon_2 &res_poly) { + Segments_list reduced_conv; + _mink->buildReducedConvolution(a, b, reduced_conv); - } + } private: - Minkowski_sum_by_convolution_lien_2* _mink; + Minkowski_sum_by_convolution_lien_2 *_mink; }; #endif \ No newline at end of file diff --git a/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/Graphics.h b/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/Graphics.h index bf05c979659..4cabb037c54 100644 --- a/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/Graphics.h +++ b/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/Graphics.h @@ -10,314 +10,304 @@ //#include "ReferencePoint_t.h" //#include "BasicPolygonManipulation_T.h" -class Graphics -{ +class Graphics { public: - typedef QGraphicsLineItem* Line_handle; - typedef std::vector< Line_handle> Object_handle; + typedef QGraphicsLineItem *Line_handle; + typedef std::vector< Line_handle> Object_handle; public: - //constructors - Graphics(int argc, char* argv[],double min_x = -1, double max_x = 1, double min_y = -1, double max_y = 1); - //destructor - ~Graphics(void); - //displays current scene - void display(); - //exports current scene - void save_scene(const std::string& path_name); - //clear the scene - void clear(); - //edge drawing functions - template void draw_edge (const typename K::Point_2& p1,const typename K::Point_2& p2,const QColor& color) - { - _scene.addLine(QLineF( to_screen_double_x (p1.x()), - to_screen_double_y (p1.y()), - to_screen_double_x (p2.x()), - to_screen_double_y (p2.y())), - QPen(color)); - _file_scene.addLine(QLineF( to_file_double_x (p1.x()), - to_file_double_y (p1.y()), - to_file_double_x (p2.x()), - to_file_double_y (p2.y())), - QPen(color)); - - } - - template void draw_edge (const typename K::Point_2& p1,const typename K::Point_2& p2,const QColor& color,const QColor& color2) - { - _scene.addLine(QLineF( to_screen_double_x (p1.x()), - to_screen_double_y (p1.y()), - to_screen_double_x (p2.x()), - to_screen_double_y (p2.y())), - QPen(color)); - _file_scene.addLine(QLineF( to_file_double_x (p1.x()), - to_file_double_y (p1.y()), - to_file_double_x (p2.x()), - to_file_double_y (p2.y())), - QPen(color)); + //constructors + Graphics(int argc, char *argv[], double min_x = -1, double max_x = 1, double min_y = -1, double max_y = 1); + //destructor + ~Graphics(void); + //displays current scene + void display(); + //exports current scene + void save_scene(const std::string &path_name); + //clear the scene + void clear(); + //edge drawing functions + template void draw_edge(const typename K::Point_2 &p1, const typename K::Point_2 &p2, const QColor &color) { + _scene.addLine(QLineF(to_screen_double_x (p1.x()), + to_screen_double_y (p1.y()), + to_screen_double_x (p2.x()), + to_screen_double_y (p2.y())), + QPen(color)); + _file_scene.addLine(QLineF(to_file_double_x (p1.x()), + to_file_double_y (p1.y()), + to_file_double_x (p2.x()), + to_file_double_y (p2.y())), + QPen(color)); - double startX = CGAL::to_double(p1.x()); - double startY = CGAL::to_double(p1.y()); - double endX = CGAL::to_double(p2.x()); - double endY = CGAL::to_double(p2.y()); - double vecX = endX-startX; - double vecY = endY - startY; - double pstartX = endX - 0.1f * vecX; - double pstartY = endY - 0.1f * vecY; - - _scene.addLine(QLineF( to_screen_double_x (pstartX), - to_screen_double_y (pstartY), - to_screen_double_x (p2.x()), - to_screen_double_y (p2.y())), - QPen(color2)); - _file_scene.addLine(QLineF( to_screen_double_x (pstartX), - to_screen_double_y (pstartY), - to_screen_double_x (p2.x()), - to_screen_double_y (p2.y())), - QPen(color2)); - } - template void draw_edge (const typename K::Segment_2& s,const QColor& color) - { - return (this->draw_edge (s.source(),s.target(),color)); - } - - template void draw_edge (const typename K::Segment_2& s,const QColor& color,bool) - { - QColor r(255,0,0); - (this->draw_edge (s.source(),s.target(),color,r)); - } - //cross drawing functions - template void draw_cross(const typename K::Point_2& p,const QColor& color,double size = CROSS_SIZE) - { - draw_edge(K::Point_2(p.x()-size,p.y()),K::Point_2(p.x()+size,p.y()),color); - draw_edge(K::Point_2(p.x(),p.y()+size),K::Point_2(p.x(),p.y()-size),color); - return; - } - //polgon drawing functions - template void draw_polygon(const CGAL::Polygon_2& polygon, const QColor& color) - { - typedef CGAL::Polygon_2::Edge_const_iterator E_iter; - - for (E_iter ei (polygon.edges_begin()) ; ei != polygon.edges_end(); ++ei) - { - draw_edge(*ei,color); } - return ; - } - template void draw_polygon(const CGAL::Polygon_with_holes_2& polygon, const QColor& color) - { - //outer boundary - if (! polygon.is_unbounded()) - draw_polygon (polygon.outer_boundary(),color); - //holes - CGAL::Polygon_with_holes_2::Hole_const_iterator hit; - for (hit = polygon.holes_begin(); hit != polygon.holes_end(); ++hit) - draw_polygon(*hit,color); - } + template void draw_edge(const typename K::Point_2 &p1, const typename K::Point_2 &p2, const QColor &color, const QColor &color2) { + _scene.addLine(QLineF(to_screen_double_x (p1.x()), + to_screen_double_y (p1.y()), + to_screen_double_x (p2.x()), + to_screen_double_y (p2.y())), + QPen(color)); + _file_scene.addLine(QLineF(to_file_double_x (p1.x()), + to_file_double_y (p1.y()), + to_file_double_x (p2.x()), + to_file_double_y (p2.y())), + QPen(color)); - //template void draw_arrangement(const CGAL) - /* - template void draw_polygons(const CGAL::Polygon_set_2& workspace, const QColor& color) - { - std::list > res; - std::list >::const_iterator pi; - workspace.polygons_with_holes (std::back_inserter (res)); + double startX = CGAL::to_double(p1.x()); + double startY = CGAL::to_double(p1.y()); + double endX = CGAL::to_double(p2.x()); + double endY = CGAL::to_double(p2.y()); + double vecX = endX - startX; + double vecY = endY - startY; + double pstartX = endX - 0.1f * vecX; + double pstartY = endY - 0.1f * vecY; - for (pi = res.begin(); pi != res.end(); ++pi) - { + _scene.addLine(QLineF(to_screen_double_x (pstartX), + to_screen_double_y (pstartY), + to_screen_double_x (p2.x()), + to_screen_double_y (p2.y())), + QPen(color2)); + _file_scene.addLine(QLineF(to_screen_double_x (pstartX), + to_screen_double_y (pstartY), + to_screen_double_x (p2.x()), + to_screen_double_y (p2.y())), + QPen(color2)); + } + template void draw_edge(const typename K::Segment_2 &s, const QColor &color) { + return (this->draw_edge (s.source(), s.target(), color)); + } + + template void draw_edge(const typename K::Segment_2 &s, const QColor &color, bool) { + QColor r(255, 0, 0); + (this->draw_edge (s.source(), s.target(), color, r)); + } + //cross drawing functions + template void draw_cross(const typename K::Point_2 &p, const QColor &color, double size = CROSS_SIZE) { + draw_edge(K::Point_2(p.x() - size, p.y()), K::Point_2(p.x() + size, p.y()), color); + draw_edge(K::Point_2(p.x(), p.y() + size), K::Point_2(p.x(), p.y() - size), color); + return; + } + //polgon drawing functions + template void draw_polygon(const CGAL::Polygon_2 &polygon, const QColor &color) { + typedef CGAL::Polygon_2::Edge_const_iterator E_iter; + + for (E_iter ei(polygon.edges_begin()) ; ei != polygon.edges_end(); ++ei) { + draw_edge(*ei, color); + } + + return ; + } + template void draw_polygon(const CGAL::Polygon_with_holes_2 &polygon, const QColor &color) { + //outer boundary + if (! polygon.is_unbounded()) { + draw_polygon (polygon.outer_boundary(), color); + } + + //holes + CGAL::Polygon_with_holes_2::Hole_const_iterator hit; + + for (hit = polygon.holes_begin(); hit != polygon.holes_end(); ++hit) { + draw_polygon(*hit, color); + } + } + + //template void draw_arrangement(const CGAL) + /* + template void draw_polygons(const CGAL::Polygon_set_2& workspace, const QColor& color) + { + std::list > res; + std::list >::const_iterator pi; + workspace.polygons_with_holes (std::back_inserter (res)); + + for (pi = res.begin(); pi != res.end(); ++pi) + { + draw_polygon(*pi,color); + } + return; + } + template void draw_polygons(const std::vector >& workspace, const QColor& color) + { + std::vector >::const_iterator pi; + for (pi=workspace.begin(); pi != workspace.end(); ++pi) + { draw_polygon(*pi,color); - } - return; - } - template void draw_polygons(const std::vector >& workspace, const QColor& color) - { - std::vector >::const_iterator pi; - for (pi=workspace.begin(); pi != workspace.end(); ++pi) - { - draw_polygon(*pi,color); - } - return; - } - template void draw_polygons(const std::vector >& workspace, const QColor& color) - { - std::vector >::const_iterator pi; - for (pi=workspace.begin(); pi != workspace.end(); ++pi) - { - draw_polygon(*pi,color); - } - return; - } - */ - //utils - template void draw_axis (const QColor& color = BLUE) - { - draw_edge (typename K::Segment_2 (typename K::Point_2(0,0),typename K::Point_2(0,1)),color); - draw_edge (typename K::Segment_2 (typename K::Point_2(0,0),typename K::Point_2(1,0)),color); - return; - } - /* template - void draw_path(std::vector >& path, - typename Extended_polygon_t & polygon, - bool to_draw_polygon) - { - double path_size = path.size(); - double color_step = (double)255/(double)path_size; - double d_red=0; - double d_green=255; - - Reference_point_t ref_p; - BOOST_FOREACH (ref_p,path) - { - int red = d_red; - int green = d_green; - polygon.move_absolute(ref_p); - if (to_draw_polygon) - { - draw_polygon (polygon.get_absolute_polygon(),QColor(red,green,0)); - } - else //!(to_draw_polygon) - { - K::Point_2 polygon_ref_point = get_reference_point(polygon.get_absolute_polygon()); - draw_cross(polygon_ref_point ,QColor(red,green,0),0.025); - } - - d_red+=color_step; - d_green-=color_step; } - - return; - } - template - void save_path(std::vector >& path, - typename Extended_polygon_t & polygon, - const std::vector >& workspace, - bool to_draw_polygon, - const std::string& path_name) - { - double path_size = path.size(); - double color_step = (double)255/(double)path_size; - double d_red=0; - double d_green=255; - - Reference_point_t ref_p; - BOOST_FOREACH (ref_p,path) - { - int red = d_red; - int green = d_green; - polygon.move_absolute(ref_p); - - clear(); - draw_polygons(workspace,BLUE); - - if (to_draw_polygon) - draw_polygon (polygon.get_absolute_polygon(),QColor(red,green,0)); - else //!(to_draw_polygon) - draw_cross(get_reference_point(polygon.get_absolute_polygon()) ,QColor(red,green,0),0.025); - - save_scene(path_name); - - d_red+=color_step; - d_green-=color_step; + return; } - - return; - } - template - void draw_path_dbg(std::vector >& path, - typename K::Point_2 & v) - { - double path_size = path.size(); - double color_step = (double)255/(double)path_size; - double d_red=0; - double d_green=255; - - Reference_point_t ref_p; - BOOST_FOREACH (ref_p,path) + template void draw_polygons(const std::vector >& workspace, const QColor& color) { - int red = d_red; - int green = d_green; - - K::Point_2 rotated (rotate_point (v,ref_p.get_rotation())); - K::Point_2 moved (translate_point(rotated,ref_p.get_location())); - - K::Segment_2 rod(ref_p.get_location(),moved); - draw_edge (rod,QColor(red,green,0)); - - d_red+=color_step; - d_green-=color_step; - } - - return; - } - - template - void draw_path_dbg(std::vector >& path, - typename K::Segment_2 & e) - { - double path_size = path.size(); - double color_step = (double)255/(double)path_size; - double d_red=0; - double d_green=255; - - Reference_point_t ref_p; - BOOST_FOREACH (ref_p,path) + std::vector >::const_iterator pi; + for (pi=workspace.begin(); pi != workspace.end(); ++pi) { - int red = d_red; - int green = d_green; - - K::Point_2 rotated1,moved1,rotated2,moved2; - rotated1 = rotate_point (e.source(),ref_p.get_rotation()); - moved1 = translate_point(rotated1,ref_p.get_location()); - rotated2 = rotate_point (e.target(),ref_p.get_rotation()); - moved2 = translate_point(rotated2,ref_p.get_location()); - - K::Segment_2 edge(moved1,moved2); - K::Segment_2 rod1(ref_p.get_location(),moved1); - K::Segment_2 rod2(ref_p.get_location(),moved2); - - draw_edge (edge,QColor(red,green,0)); - draw_edge (rod1,QColor(red,green,0)); - draw_edge (rod2,QColor(red,green,0)); - - d_red+=color_step; - d_green-=color_step; + draw_polygon(*pi,color); } + return; + } + */ + //utils + template void draw_axis(const QColor &color = BLUE) { + draw_edge (typename K::Segment_2(typename K::Point_2(0, 0), typename K::Point_2(0, 1)), color); + draw_edge (typename K::Segment_2(typename K::Point_2(0, 0), typename K::Point_2(1, 0)), color); + return; + } + /* template + void draw_path(std::vector >& path, + typename Extended_polygon_t & polygon, + bool to_draw_polygon) + { + double path_size = path.size(); + double color_step = (double)255/(double)path_size; + double d_red=0; + double d_green=255; - return; - }*/ - private: - template double to_screen_double_x(const NT& x) - { - return ((CGAL::to_double (x) - _min_x) * _ratio_x); - } - template double to_screen_double_y(const NT& y) - { - return (- (CGAL::to_double (y) - _min_y) * _ratio_y); - } - template double to_file_double_x(const NT& x) - { - return (CGAL::to_double (x)); - } - template double to_file_double_y(const NT& y) - { - return (-CGAL::to_double (y)); - } + Reference_point_t ref_p; + BOOST_FOREACH (ref_p,path) + { + int red = d_red; + int green = d_green; + polygon.move_absolute(ref_p); + if (to_draw_polygon) + { + draw_polygon (polygon.get_absolute_polygon(),QColor(red,green,0)); + } + else //!(to_draw_polygon) + { + K::Point_2 polygon_ref_point = get_reference_point(polygon.get_absolute_polygon()); + draw_cross(polygon_ref_point ,QColor(red,green,0),0.025); + } - + d_red+=color_step; + d_green-=color_step; + } + + return; + } + template + void save_path(std::vector >& path, + typename Extended_polygon_t & polygon, + const std::vector >& workspace, + bool to_draw_polygon, + const std::string& path_name) + { + double path_size = path.size(); + double color_step = (double)255/(double)path_size; + double d_red=0; + double d_green=255; + + Reference_point_t ref_p; + BOOST_FOREACH (ref_p,path) + { + int red = d_red; + int green = d_green; + polygon.move_absolute(ref_p); + + clear(); + draw_polygons(workspace,BLUE); + + if (to_draw_polygon) + draw_polygon (polygon.get_absolute_polygon(),QColor(red,green,0)); + else //!(to_draw_polygon) + draw_cross(get_reference_point(polygon.get_absolute_polygon()) ,QColor(red,green,0),0.025); + + save_scene(path_name); + + d_red+=color_step; + d_green-=color_step; + } + + return; + } + template + void draw_path_dbg(std::vector >& path, + typename K::Point_2 & v) + { + double path_size = path.size(); + double color_step = (double)255/(double)path_size; + double d_red=0; + double d_green=255; + + Reference_point_t ref_p; + BOOST_FOREACH (ref_p,path) + { + int red = d_red; + int green = d_green; + + K::Point_2 rotated (rotate_point (v,ref_p.get_rotation())); + K::Point_2 moved (translate_point(rotated,ref_p.get_location())); + + K::Segment_2 rod(ref_p.get_location(),moved); + draw_edge (rod,QColor(red,green,0)); + + d_red+=color_step; + d_green-=color_step; + } + + return; + } + + template + void draw_path_dbg(std::vector >& path, + typename K::Segment_2 & e) + { + double path_size = path.size(); + double color_step = (double)255/(double)path_size; + double d_red=0; + double d_green=255; + + Reference_point_t ref_p; + BOOST_FOREACH (ref_p,path) + { + int red = d_red; + int green = d_green; + + K::Point_2 rotated1,moved1,rotated2,moved2; + rotated1 = rotate_point (e.source(),ref_p.get_rotation()); + moved1 = translate_point(rotated1,ref_p.get_location()); + rotated2 = rotate_point (e.target(),ref_p.get_rotation()); + moved2 = translate_point(rotated2,ref_p.get_location()); + + K::Segment_2 edge(moved1,moved2); + K::Segment_2 rod1(ref_p.get_location(),moved1); + K::Segment_2 rod2(ref_p.get_location(),moved2); + + draw_edge (edge,QColor(red,green,0)); + draw_edge (rod1,QColor(red,green,0)); + draw_edge (rod2,QColor(red,green,0)); + + d_red+=color_step; + d_green-=color_step; + } + + return; + }*/ private: - QApplication app; - QGraphicsScene _scene; + template double to_screen_double_x(const NT &x) { + return ((CGAL::to_double(x) - _min_x) * _ratio_x); + } + template double to_screen_double_y(const NT &y) { + return (- (CGAL::to_double(y) - _min_y) * _ratio_y); + } + template double to_file_double_x(const NT &x) { + return (CGAL::to_double(x)); + } + template double to_file_double_y(const NT &y) { + return (-CGAL::to_double(y)); + } + + +private: + QApplication app; + QGraphicsScene _scene; QGraphicsScene _file_scene; - - double _min_x; - double _max_x; - double _min_y; - double _max_y; - double _ratio_x; - double _ratio_y; + + double _min_x; + double _max_x; + double _min_y; + double _max_y; + double _ratio_x; + double _ratio_y; }; -extern Graphics* global_graphics; +extern Graphics *global_graphics; #endif //Graphics_H diff --git a/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/IBounderySumCalculator.h b/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/IBounderySumCalculator.h index 5209b0d1629..eb54ead2ba7 100644 --- a/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/IBounderySumCalculator.h +++ b/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/IBounderySumCalculator.h @@ -4,13 +4,13 @@ #include #include -template class IBounderySumCalculator{ +template class IBounderySumCalculator { protected: - typedef Kernel_ Kernel; - typedef CGAL::Polygon_2 Polygon_2; + typedef Kernel_ Kernel; + typedef CGAL::Polygon_2 Polygon_2; public: - virtual void calc_sum(Polygon_2& a,Polygon_2& b,Polygon_2& res_poly)=0; + virtual void calc_sum(Polygon_2 &a, Polygon_2 &b, Polygon_2 &res_poly) = 0; }; diff --git a/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/ICollisionDetector.h b/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/ICollisionDetector.h index 8502c4e30c6..289dd783f6a 100644 --- a/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/ICollisionDetector.h +++ b/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/ICollisionDetector.h @@ -4,12 +4,12 @@ #include #include -template class ICollisionDetector{ +template class ICollisionDetector { public: - typedef Kernel_ Kernel; - typedef CGAL::Polygon_2 Polygon_2; - - virtual bool checkCollision(const Polygon_2& p,const Polygon_2& q) =0; + typedef Kernel_ Kernel; + typedef CGAL::Polygon_2 Polygon_2; + + virtual bool checkCollision(const Polygon_2 &p, const Polygon_2 &q) = 0; }; #endif \ No newline at end of file diff --git a/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/Minkowski_sum_reduced_conv_2.h b/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/Minkowski_sum_reduced_conv_2.h index 903c69dcaec..7a3fb6aa310 100644 --- a/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/Minkowski_sum_reduced_conv_2.h +++ b/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/Minkowski_sum_reduced_conv_2.h @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include #include @@ -41,9 +41,9 @@ //#ifdef _DEBUG #define BLA #ifdef _DEBUG - #define SHOW_STAGES 1 +#define SHOW_STAGES 1 #else - #define SHOW_STAGES 0 +#define SHOW_STAGES 0 #endif #define WRITE_ARR 0 @@ -51,3046 +51,3004 @@ namespace CGAL { struct Less_than_handle { - template - bool operator()(Type s1, Type s2) const { return (&(*s1) < &(*s2)); } -}; + template + bool operator()(Type s1, Type s2) const { + return (&(*s1) < & (*s2)); + } +}; /* struct Convseg_Less_than{ - bool operator()(ConvS s1, Type s2) const { return (&(*s1) < &(*s2)); } + bool operator()(ConvS s1, Type s2) const { return (&(*s1) < &(*s2)); } }; */ template - class Arr_map_halfedge : public HalfedgeBase_{ - public: - //std::string name, type; - bool visited; - bool isDegenerate; - int loopNumber; - }; +class Arr_map_halfedge : public HalfedgeBase_ { +public: + //std::string name, type; + bool visited; + bool isDegenerate; + int loopNumber; +}; template > class Arr_my_extended_dcel : - public Arr_dcel_base, - Arr_map_halfedge, - Arr_face_base> - { - public: + class HalfedgeBase_ = Arr_halfedge_base > class Arr_my_extended_dcel : + public Arr_dcel_base, + Arr_map_halfedge, + Arr_face_base> { +public: - template - class rebind - { - //typedef typename VertexBase_::template rebind - // Rebind_vertex; - //typedef typename Rebind_vertex::other Vertex_base; - typedef typename HalfedgeBase_::template rebind - Rebind_halfedge; - typedef typename Rebind_halfedge::other Halfedge_base; - - public: + template + class rebind { + //typedef typename VertexBase_::template rebind + // Rebind_vertex; + //typedef typename Rebind_vertex::other Vertex_base; + typedef typename HalfedgeBase_::template rebind + Rebind_halfedge; + typedef typename Rebind_halfedge::other Halfedge_base; - typedef Arr_my_extended_dcel other; - }; + public: - }; + typedef Arr_my_extended_dcel other; + }; + +}; template -class Minkowski_sum_by_convolution_lien_2{ +class Minkowski_sum_by_convolution_lien_2 { public: - typedef Kernel_ Kernel; - typedef CGAL::Polygon_2 Polygon_2; + typedef Kernel_ Kernel; + typedef CGAL::Polygon_2 Polygon_2; public: - // Kernel types: - typedef typename Kernel::Point_2 Point_2; - typedef typename Kernel::Vector_2 Vector_2; - typedef typename Kernel::Direction_2 Direction_2; - - // Kernel functors: - typedef typename Kernel::Equal_2 Equal_2; - typedef typename Kernel::Construct_translated_point_2 Translate_point_2; - typedef typename Kernel::Construct_vector_2 Construct_vector_2; - typedef typename Kernel::Construct_direction_2 Construct_direction_2; - typedef typename Kernel::Construct_opposite_line_2 Opposite_line_2; - typedef typename Kernel::Orientation_2 Compute_orientation_2; - typedef typename Kernel::Compare_xy_2 Compare_xy_2; - typedef typename Kernel::Counterclockwise_in_between_2 Ccw_in_between_2; - typedef typename Kernel::Angle_2 Compute_Angle_2; - typedef typename Kernel::Compare_x_2 Compare_x_2; - typedef typename Kernel::Is_vertical_2 Is_vertical_2; - typedef typename Kernel::Compute_x_2 Compute_x_2; - typedef typename Kernel::Compute_y_2 Compute_y_2; + // Kernel types: + typedef typename Kernel::Point_2 Point_2; + typedef typename Kernel::Vector_2 Vector_2; + typedef typename Kernel::Direction_2 Direction_2; - // Polygon-related types: - typedef typename Polygon_2::Vertex_circulator Vertex_circulator; - typedef std::pair Vertex_ref; - typedef std::pair Anchor; - typedef std::list Anchors_queue; + // Kernel functors: + typedef typename Kernel::Equal_2 Equal_2; + typedef typename Kernel::Construct_translated_point_2 Translate_point_2; + typedef typename Kernel::Construct_vector_2 Construct_vector_2; + typedef typename Kernel::Construct_direction_2 Construct_direction_2; + typedef typename Kernel::Construct_opposite_line_2 Opposite_line_2; + typedef typename Kernel::Orientation_2 Compute_orientation_2; + typedef typename Kernel::Compare_xy_2 Compare_xy_2; + typedef typename Kernel::Counterclockwise_in_between_2 Ccw_in_between_2; + typedef typename Kernel::Angle_2 Compute_Angle_2; + typedef typename Kernel::Compare_x_2 Compare_x_2; + typedef typename Kernel::Is_vertical_2 Is_vertical_2; + typedef typename Kernel::Compute_x_2 Compute_x_2; + typedef typename Kernel::Compute_y_2 Compute_y_2; - // Traits-related types: - //typedef Arr_segment_traits_2 Traits_2;//Segment_traits_2; - typedef Arr_segment_traits_2 Traits_2_A;//Segment_traits_2; - typedef Arr_SegmentData_traits Traits_2; - //typedef Arr_curve_data_traits_2 Traits_2; - // used - // typedef Arr_curve_data_traits_2 Traits_2; + // Polygon-related types: + typedef typename Polygon_2::Vertex_circulator Vertex_circulator; + typedef std::pair Vertex_ref; + typedef std::pair Anchor; + typedef std::list Anchors_queue; - //typedef Arr_SegmentData_traits Traits_2; -// typedef Arr_labeled_traits_2 Traits_2; - - typedef typename Traits_2_A::Segment_2 Base_Segment_2; - typedef typename Traits_2::X_monotone_curve_2 Segment_2; - //typedef typename Traits_2::X_monotone_curve_2 Labeled_segment_2; - typedef std::list Segments_list; - //typedef std::list Segments_itr_list; + // Traits-related types: + //typedef Arr_segment_traits_2 Traits_2;//Segment_traits_2; + typedef Arr_segment_traits_2 Traits_2_A;//Segment_traits_2; + typedef Arr_SegmentData_traits Traits_2; + //typedef Arr_curve_data_traits_2 Traits_2; + // used + // typedef Arr_curve_data_traits_2 Traits_2; + + //typedef Arr_SegmentData_traits Traits_2; +// typedef Arr_labeled_traits_2 Traits_2; + + typedef typename Traits_2_A::Segment_2 Base_Segment_2; + typedef typename Traits_2::X_monotone_curve_2 Segment_2; + //typedef typename Traits_2::X_monotone_curve_2 Labeled_segment_2; + typedef std::list Segments_list; + //typedef std::list Segments_itr_list; - - //typedef CGAL::Arr_default_dcel Dcel; - typedef CGAL::Arr_my_extended_dcel Dcel; - + + //typedef CGAL::Arr_default_dcel Dcel; + typedef CGAL::Arr_my_extended_dcel Dcel; + // typedef Arr_face_extended_dcel Dcel; - typedef CGAL::Arrangement_with_history_2 Arrangement_history_2; - typedef typename Arrangement_history_2::Halfedge Halfedge; - typedef typename Arrangement_history_2::Vertex Vertex; - typedef typename Arrangement_history_2::Vertex_iterator Vertex_iterator; - typedef typename Arrangement_history_2::Halfedge_iterator Halfedge_iterator; - typedef typename Arrangement_history_2::Edge_iterator Edge_iterator; - typedef typename Arrangement_history_2::Halfedge_handle Halfedge_handle; - typedef typename Arrangement_history_2::Vertex_handle Vertex_handle; - typedef typename Arrangement_history_2::Face_iterator Face_iterator; - typedef typename Arrangement_history_2::Face_handle Face_handle; - //typedef typename Arrangement_history_2::Face_const Face_handle; - typedef typename Arrangement_history_2::Hole_iterator Hole_iterator; - typedef typename Arrangement_history_2::Halfedge_around_vertex_circulator Halfedge_around_vertex_circulator; - typedef typename Arrangement_history_2::Ccb_halfedge_circulator Ccb_halfedge_circulator; + typedef CGAL::Arrangement_with_history_2 Arrangement_history_2; + typedef typename Arrangement_history_2::Halfedge Halfedge; + typedef typename Arrangement_history_2::Vertex Vertex; + typedef typename Arrangement_history_2::Vertex_iterator Vertex_iterator; + typedef typename Arrangement_history_2::Halfedge_iterator Halfedge_iterator; + typedef typename Arrangement_history_2::Edge_iterator Edge_iterator; + typedef typename Arrangement_history_2::Halfedge_handle Halfedge_handle; + typedef typename Arrangement_history_2::Vertex_handle Vertex_handle; + typedef typename Arrangement_history_2::Face_iterator Face_iterator; + typedef typename Arrangement_history_2::Face_handle Face_handle; + //typedef typename Arrangement_history_2::Face_const Face_handle; + typedef typename Arrangement_history_2::Hole_iterator Hole_iterator; + typedef typename Arrangement_history_2::Halfedge_around_vertex_circulator Halfedge_around_vertex_circulator; + typedef typename Arrangement_history_2::Ccb_halfedge_circulator Ccb_halfedge_circulator; - typedef typename Arrangement_history_2::Originating_curve_iterator Originating_curve_iterator; - typedef std::pair StatePair; + typedef typename Arrangement_history_2::Originating_curve_iterator Originating_curve_iterator; + typedef std::pair StatePair; - typedef std::set Edges_set; - typedef std::set Faces_set; + typedef std::set Edges_set; + typedef std::set Faces_set; // typedef Union_of_segment_cycles_2 Union_2; - // Data members: - Equal_2 f_equal; - Translate_point_2 f_add; - Construct_vector_2 f_vector; - Construct_direction_2 f_direction; - Opposite_line_2 f_opp_line; - Compute_orientation_2 f_orientation; - Compare_xy_2 f_compare_xy; - Ccw_in_between_2 f_ccw_in_between; - Compute_Angle_2 f_angle; - Is_vertical_2 f_is_vertical; - Compute_x_2 f_compute_x; - Compute_y_2 f_compute_y; + // Data members: + Equal_2 f_equal; + Translate_point_2 f_add; + Construct_vector_2 f_vector; + Construct_direction_2 f_direction; + Opposite_line_2 f_opp_line; + Compute_orientation_2 f_orientation; + Compare_xy_2 f_compare_xy; + Ccw_in_between_2 f_ccw_in_between; + Compute_Angle_2 f_angle; + Is_vertical_2 f_is_vertical; + Compute_x_2 f_compute_x; + Compute_y_2 f_compute_y; - // Compare_x_2 f_compare_x; - //Traits_2::Compare_endpoints_xy_2 f_compare_endpoints_xy; - typename Traits_2::Compare_endpoints_xy_2 f_compare_endpoints_xy; - typename Traits_2::Compare_y_at_x_2 f_compare_y_at_x; - typename Traits_2::Compare_x_2 f_compare_x; - - friend class ConvSegMapper; - struct ConvSegment - { - Halfedge_handle _he; - ConvSegment(Halfedge_handle& he):_he(he){} - ConvSegment(){} - bool getVisited() const - { - return _he->visited; - } - - bool getDegenerate() const - { - return _he->isDegenerate; - } +// Compare_x_2 f_compare_x; + //Traits_2::Compare_endpoints_xy_2 f_compare_endpoints_xy; + typename Traits_2::Compare_endpoints_xy_2 f_compare_endpoints_xy; + typename Traits_2::Compare_y_at_x_2 f_compare_y_at_x; + typename Traits_2::Compare_x_2 f_compare_x; - int getLoopNum() - { - return _he->loopNumber; - } + friend class ConvSegMapper; + struct ConvSegment { + Halfedge_handle _he; + ConvSegment(Halfedge_handle &he): _he(he) {} + ConvSegment() {} + bool getVisited() const { + return _he->visited; + } - Vertex_handle getSrc() - { - return (_he->source()); - } + bool getDegenerate() const { + return _he->isDegenerate; + } - Vertex_handle getDst() - { - //return Vertex();//_he->target(); - return (_he->target()); - } + int getLoopNum() { + return _he->loopNumber; + } - bool operator<(const ConvSegment& rhs) const - { - //Less_than_handle o(); - //return o.operator()(_he,rhs._he); - return Less_than_handle()(_he,rhs._he); - } + Vertex_handle getSrc() { + return (_he->source()); + } - bool operator==(const ConvSegment& rhs) const - { - return !Less_than_handle()(_he,rhs._he) && !Less_than_handle()(rhs._he,_he); - } + Vertex_handle getDst() { + //return Vertex();//_he->target(); + return (_he->target()); + } - }; + bool operator<(const ConvSegment &rhs) const { + //Less_than_handle o(); + //return o.operator()(_he,rhs._he); + return Less_than_handle()(_he, rhs._he); + } + + bool operator==(const ConvSegment &rhs) const { + return !Less_than_handle()(_he, rhs._he) && !Less_than_handle()(rhs._he, _he); + } + + }; #define FIRST_LOOP 0 - struct ConvSegMapper{ - Arrangement_history_2* _arr; - Minkowski_sum_by_convolution_lien_2* _mink; - ConvSegMapper(Arrangement_history_2 *arr,Minkowski_sum_by_convolution_lien_2* mink):_arr(arr),_mink(mink){ - - } + struct ConvSegMapper { + Arrangement_history_2 *_arr; + Minkowski_sum_by_convolution_lien_2 *_mink; + ConvSegMapper(Arrangement_history_2 *arr, Minkowski_sum_by_convolution_lien_2 *mink): _arr(arr), _mink(mink) { - ConvSegment getSegment(const Halfedge_handle& he) - { - return ConvSegment(_mink->getDirAgreeingHalfedge(*_arr,he)); - } + } - Direction_2 getConvSegDir(const ConvSegment& seg) const - { - return _mink->getHalfedgeDir(seg._he); - } + ConvSegment getSegment(const Halfedge_handle &he) { + return ConvSegment(_mink->getDirAgreeingHalfedge(*_arr, he)); + } - void markVisited(ConvSegment& convSeg,int id) - { - _mink->setEdgeVisited(*convSeg._he,true,id); - } + Direction_2 getConvSegDir(const ConvSegment &seg) const { + return _mink->getHalfedgeDir(seg._he); + } - bool isBBiggerThenAWithReagrdToC(const ConvSegment& a,const ConvSegment& b,const ConvSegment& c) const - { - Direction_2 dir_a = getConvSegDir(a); - Direction_2 dir_b = getConvSegDir(b); - Direction_2 dir_c = getConvSegDir(c); - return _mink->isDirImproving(dir_a,dir_c,dir_b); - } + void markVisited(ConvSegment &convSeg, int id) { + _mink->setEdgeVisited(*convSeg._he, true, id); + } - void getNeighbouringSegments(Vertex_handle v,std::list& outSegments,std::list& inSegmets) - { - std::list inList,outList; - _mink->getEdgesFromVertex(*_arr,v,inList,outList); - typename std::list::const_iterator itr; + bool isBBiggerThenAWithReagrdToC(const ConvSegment &a, const ConvSegment &b, const ConvSegment &c) const { + Direction_2 dir_a = getConvSegDir(a); + Direction_2 dir_b = getConvSegDir(b); + Direction_2 dir_c = getConvSegDir(c); + return _mink->isDirImproving(dir_a, dir_c, dir_b); + } - for (itr = inList.begin();itr!= inList.end();++itr) - { - inSegmets.push_back(getSegment(*itr)); - } + void getNeighbouringSegments(Vertex_handle v, std::list &outSegments, std::list &inSegmets) { + std::list inList, outList; + _mink->getEdgesFromVertex(*_arr, v, inList, outList); + typename std::list::const_iterator itr; - for (itr = outList.begin();itr!= outList.end();++itr) - { - outSegments.push_back(getSegment(*itr)); - } - } + for (itr = inList.begin(); itr != inList.end(); ++itr) { + inSegmets.push_back(getSegment(*itr)); + } - static bool getSegVisited(const ConvSegment& seg) - { - return (seg.getVisited()==true || seg.getDegenerate()); - } + for (itr = outList.begin(); itr != outList.end(); ++itr) { + outSegments.push_back(getSegment(*itr)); + } + } - static bool getSegNotVisited(const ConvSegment& seg) - { - return (seg.getVisited()==false && !seg.getDegenerate()); - } + static bool getSegVisited(const ConvSegment &seg) { + return (seg.getVisited() == true || seg.getDegenerate()); + } - double getSignedAngle(const ConvSegment& enter,const ConvSegment& exit) - { - return _mink->getSignedAngle(enter._he,exit._he); - } + static bool getSegNotVisited(const ConvSegment &seg) { + return (seg.getVisited() == false && !seg.getDegenerate()); + } - void filterNonVisitedSegments(const std::list& inputList,std::list& outList, std::list& visitedSegmentsList) - { - int out_size = count_if(inputList.begin(),inputList.end(),&ConvSegMapper::getSegNotVisited); - outList.resize(out_size); - remove_copy_if(inputList.begin(),inputList.end(),outList.begin(),&ConvSegMapper::getSegVisited); - visitedSegmentsList.resize(inputList.size() - out_size); - remove_copy_if(inputList.begin(),inputList.end(),visitedSegmentsList.begin(),&ConvSegMapper::getSegNotVisited); - } + double getSignedAngle(const ConvSegment &enter, const ConvSegment &exit) { + return _mink->getSignedAngle(enter._he, exit._he); + } - struct SegCompare{ - ConvSegment _incomingSeg; - ConvSegMapper* _mapperInstance; - SegCompare(ConvSegment incomingSeg,ConvSegMapper* mapperInstance):_incomingSeg(incomingSeg),_mapperInstance(mapperInstance){} - bool operator()(ConvSegment a,ConvSegment b) - { - return _mapperInstance->isBBiggerThenAWithReagrdToC(a,b,_incomingSeg); - } - }; + void filterNonVisitedSegments(const std::list &inputList, std::list &outList, std::list &visitedSegmentsList) { + int out_size = count_if(inputList.begin(), inputList.end(), &ConvSegMapper::getSegNotVisited); + outList.resize(out_size); + remove_copy_if(inputList.begin(), inputList.end(), outList.begin(), &ConvSegMapper::getSegVisited); + visitedSegmentsList.resize(inputList.size() - out_size); + remove_copy_if(inputList.begin(), inputList.end(), visitedSegmentsList.begin(), &ConvSegMapper::getSegNotVisited); + } - ConvSegment getMaximalEdge(std::list outgoingSegs,ConvSegment incomingSeg) - { - SegCompare seg_comp(incomingSeg,this); - return *max_element(outgoingSegs.begin(),outgoingSegs.end(),seg_comp); - } + struct SegCompare { + ConvSegment _incomingSeg; + ConvSegMapper *_mapperInstance; + SegCompare(ConvSegment incomingSeg, ConvSegMapper *mapperInstance): _incomingSeg(incomingSeg), _mapperInstance(mapperInstance) {} + bool operator()(ConvSegment a, ConvSegment b) { + return _mapperInstance->isBBiggerThenAWithReagrdToC(a, b, _incomingSeg); + } + }; - bool checkLoopClosed(const Vertex_handle& v,ConvSegment& startingSeg,int id) - { - Halfedge_handle h; - bool notFound = _mink->checkOutgoingNotVisited(*_arr,*v,h,id); - if (h != Halfedge_handle()) - startingSeg = getSegment(h); - return !notFound; - } + ConvSegment getMaximalEdge(std::list outgoingSegs, ConvSegment incomingSeg) { + SegCompare seg_comp(incomingSeg, this); + return *max_element(outgoingSegs.begin(), outgoingSegs.end(), seg_comp); + } - template void fillEdgesSet(T& edges_set) - { - Edge_iterator itr; - //Edges_set edges_set; - for (itr = _arr->edges_begin();itr!=_arr->edges_end();++itr){ - //setEdgeVisited(*itr,false,-1); - _mink->setEdgeVisited(*itr,false,-1); + bool checkLoopClosed(const Vertex_handle &v, ConvSegment &startingSeg, int id) { + Halfedge_handle h; + bool notFound = _mink->checkOutgoingNotVisited(*_arr, *v, h, id); - if (!itr->isDegenerate) - //*oitr++ = getSegment(itr); - edges_set.insert(getSegment(itr)); - } - } + if (h != Halfedge_handle()) { + startingSeg = getSegment(h); + } + + return !notFound; + } + + template void fillEdgesSet(T &edges_set) { + Edge_iterator itr; + + //Edges_set edges_set; + for (itr = _arr->edges_begin(); itr != _arr->edges_end(); ++itr) { + //setEdgeVisited(*itr,false,-1); + _mink->setEdgeVisited(*itr, false, -1); + + if (!itr->isDegenerate) + //*oitr++ = getSegment(itr); + { + edges_set.insert(getSegment(itr)); + } + } + } - ConvSegment getOuterSegment() - { - Face_iterator startFace = _arr->unbounded_face(); - Halfedge_iterator perimiterFace = *(startFace -> holes_begin()); - return getSegment(perimiterFace); - } + ConvSegment getOuterSegment() { + Face_iterator startFace = _arr->unbounded_face(); + Halfedge_iterator perimiterFace = *(startFace -> holes_begin()); + return getSegment(perimiterFace); + } - void removeSegFromArr(const ConvSegment& seg) - { - _arr->remove_edge(seg._he); - } + void removeSegFromArr(const ConvSegment &seg) { + _arr->remove_edge(seg._he); + } - void removeRangeFromArr(std::list& segsToRemove) - { - //for_each(segsToRemove.begin(),segsToRemove.end(),&ConvSegMapper::removeSegFromArr); - for (typename std::list::iterator itr = segsToRemove.begin();itr!=segsToRemove.end();++itr) - { - removeSegFromArr(*itr); - } - } + void removeRangeFromArr(std::list &segsToRemove) { + //for_each(segsToRemove.begin(),segsToRemove.end(),&ConvSegMapper::removeSegFromArr); + for (typename std::list::iterator itr = segsToRemove.begin(); itr != segsToRemove.end(); ++itr) { + removeSegFromArr(*itr); + } + } - - }; - class TraversalManager; - friend class ConvMovement; - struct ConvMovement{ - ConvMovement(ConvSegMapper* mapperInstance,int id,ConvSegment& startedge,TraversalManager* managerInstance):_id(id),_mapperInstance(mapperInstance),_managerInstance(managerInstance) - { - _currEdge = startedge; - _traversedEdges.push_back(_currEdge); - _mapperInstance->markVisited(startedge,id); - _traversing = true; - _loop = NULL; - } + }; - void Traverse() - { - - while (_traversing) - { + class TraversalManager; + friend class ConvMovement; + struct ConvMovement { + ConvMovement(ConvSegMapper *mapperInstance, int id, ConvSegment &startedge, TraversalManager *managerInstance): _id(id), _mapperInstance(mapperInstance), _managerInstance(managerInstance) { + _currEdge = startedge; + _traversedEdges.push_back(_currEdge); + _mapperInstance->markVisited(startedge, id); + _traversing = true; + _loop = NULL; + } - Vertex_handle dst = _currEdge.getDst(); - std::list inList; - std::list outList; - _mapperInstance->getNeighbouringSegments(dst,outList,inList); - std::list filteredSegments,visitedSegments; - _mapperInstance->filterNonVisitedSegments(outList,filteredSegments,visitedSegments); - /* if (outList.size()>1) - { - drawTraversal(); + void Traverse() { - }*/ - if (checkCloseLoop()) - closeLoopEvent(filteredSegments); + while (_traversing) { - if (!_traversing) - break; + Vertex_handle dst = _currEdge.getDst(); + std::list inList; + std::list outList; + _mapperInstance->getNeighbouringSegments(dst, outList, inList); + std::list filteredSegments, visitedSegments; + _mapperInstance->filterNonVisitedSegments(outList, filteredSegments, visitedSegments); - // Check if movement may proceed. - if (filteredSegments.size() >0 ) - { - ConvSegment c = _mapperInstance->getMaximalEdge(filteredSegments,_currEdge); - // Check that there is no visited outgoing edge, with diffrenet loop id (ie closed loop), - // which is better than c. - typename std::list::iterator itr = visitedSegments.begin(); - for (;itr != visitedSegments.end();++itr) - { - if (_mapperInstance->isBBiggerThenAWithReagrdToC(c,*itr,_currEdge) && itr->getLoopNum() != _id && itr->getLoopNum() != FIRST_LOOP) - { - closeEvent(); - _traversing = false; - return; - } - } + /* if (outList.size()>1) + { + drawTraversal(); - double angle = _mapperInstance->getSignedAngle(_currEdge,c); - _angles.push_back(angle); - _anglesSum += angle; - _currEdge = c; - _mapperInstance->markVisited(c,_id); - _traversedEdges.push_back(c); - } - else - { - closeEvent(); - _traversing = false; - } - } - } + }*/ + if (checkCloseLoop()) { + closeLoopEvent(filteredSegments); + } + + if (!_traversing) { + break; + } + + // Check if movement may proceed. + if (filteredSegments.size() > 0) { + ConvSegment c = _mapperInstance->getMaximalEdge(filteredSegments, _currEdge); + // Check that there is no visited outgoing edge, with diffrenet loop id (ie closed loop), + // which is better than c. + typename std::list::iterator itr = visitedSegments.begin(); + + for (; itr != visitedSegments.end(); ++itr) { + if (_mapperInstance->isBBiggerThenAWithReagrdToC(c, *itr, _currEdge) && itr->getLoopNum() != _id && itr->getLoopNum() != FIRST_LOOP) { + closeEvent(); + _traversing = false; + return; + } + } + + double angle = _mapperInstance->getSignedAngle(_currEdge, c); + _angles.push_back(angle); + _anglesSum += angle; + _currEdge = c; + _mapperInstance->markVisited(c, _id); + _traversedEdges.push_back(c); + } else { + closeEvent(); + _traversing = false; + } + } + } // #define SHOW_LOOPS_CONST - void closeLoopEvent(std::list& outGoingOptions) - { - #ifdef SHOW_LOOPS_CONST - drawTraversal(); - #endif - _managerInstance->handleCloseLoopEvent(*_loop,outGoingOptions); - _angles.pop_back(); - } + void closeLoopEvent(std::list &outGoingOptions) { +#ifdef SHOW_LOOPS_CONST + drawTraversal(); +#endif + _managerInstance->handleCloseLoopEvent(*_loop, outGoingOptions); + _angles.pop_back(); + } - void closeEvent() - { - #ifdef SHOW_LOOPS_CONST - drawTraversal(); - #endif - _managerInstance->handleCloseEvent(); - } + void closeEvent() { +#ifdef SHOW_LOOPS_CONST + drawTraversal(); +#endif + _managerInstance->handleCloseEvent(); + } - bool checkCloseLoop() - { - ConvSegment loopStart; - bool found = _mapperInstance->checkLoopClosed(_currEdge.getDst(),loopStart,_id); - if (found) - { - if (_loop!=NULL) - delete _loop; - _loop = new std::pair(loopStart,_currEdge); - double angle = _mapperInstance->getSignedAngle(_currEdge,loopStart); - _angles.push_back(angle); - } - return found; - } + bool checkCloseLoop() { + ConvSegment loopStart; + bool found = _mapperInstance->checkLoopClosed(_currEdge.getDst(), loopStart, _id); - void stopTraverse() - { - _traversing = false; - } + if (found) { + if (_loop != NULL) { + delete _loop; + } - /* - void drawTraversal() - { - - global_graphics->clear(); + _loop = new std::pair(loopStart, _currEdge); + double angle = _mapperInstance->getSignedAngle(_currEdge, loopStart); + _angles.push_back(angle); + } - for (typename std::list::iterator itr = _traversedEdges.begin();itr != _traversedEdges.end(); ++itr) - { - global_graphics->draw_edge((itr->_he)->curve(),QColor(0,255,0),true); - } - global_graphics->display(); - - } + return found; + } + + void stopTraverse() { + _traversing = false; + } + + /* + void drawTraversal() + { + + global_graphics->clear(); + + for (typename std::list::iterator itr = _traversedEdges.begin();itr != _traversedEdges.end(); ++itr) + { + global_graphics->draw_edge((itr->_he)->curve(),QColor(0,255,0),true); + } + global_graphics->display(); + + } + */ + + std::list &getTraversedEdges() { + return _traversedEdges; + } + + std::list &getAngles() { + return _angles; + } + private: + int _id; + ConvSegment _currEdge; + std::list _traversedEdges; + std::list _angles; + ConvSegMapper *_mapperInstance; + TraversalManager *_managerInstance; + bool _traversing; + double _anglesSum; + std::pair *_loop; + }; + + friend class TraversalManager; + class EdgesStore; + class LoopsTracker; + struct TraversalManager { + TraversalManager(ConvSegMapper *mapperInstance): _mapperInstance(mapperInstance) { + _loopId = 0; + _activeMovment = NULL; + } + void traverseLoops() { + EdgesStore edges_db(_mapperInstance); + _currEdgesStore = &edges_db; + int s = edges_db.getSize(); + ConvSegment startEdge = _mapperInstance->getOuterSegment(); + traceLoop(edges_db, startEdge, true); + + while (!edges_db.isEmpty()) { + int s = edges_db.getSize(); + ++_loopId; + startEdge = edges_db.getEdge(); + traceLoop(edges_db, startEdge, false); + } + + } + + void traceLoop(EdgesStore &edgesDB, ConvSegment &startSeg, bool isOuter) { + /* if (_activeMovment != NULL) + delete _activeMovment;*/ + _activeMovment = new ConvMovement(_mapperInstance, _loopId, startSeg, this); + + /*if (_activeLoopTracker != NULL) + delete _activeLoopTracker;*/ + _activeLoopTracker = new LoopsTracker(&(_activeMovment->getTraversedEdges()), &(_activeMovment->getAngles()), isOuter); + + _activeMovment->Traverse(); + + // Delete objects + delete _activeMovment; + delete _activeLoopTracker; + } + + void handleCloseLoopEvent(std::pair &loop, std::list &outGoingOptions) { + _activeLoopTracker->addLoop(loop); + + // check for improvment: (TODO: maybe refactor) + // This checks if the first segment in loop (actually second edge goes into first) is a worse choice then *itr , w.r.t second. + // This means the loop might be improved. + if (_activeLoopTracker->hasLoops()) { + bool stopItrating = true; + + for (typename std::list::iterator itr = outGoingOptions.begin(); itr != outGoingOptions.end(); ++itr) { + if (_mapperInstance->isBBiggerThenAWithReagrdToC(loop.first, *itr, loop.second)) { + stopItrating = false; + break; + } + } + + if (stopItrating) { + handleCloseEvent(); + _activeMovment->stopTraverse(); + } + } + } + + void handleCloseEvent() { + // remove all traversed edges from segments list + + std::list &traversedEdges = _activeMovment->getTraversedEdges(); + _currEdgesStore->removeRange(traversedEdges.begin(), traversedEdges.end()); + + // remove anything but loop from arrangment. + std::list &toRemoveFromArr = _activeLoopTracker->getNonLoopSegmentsList(); + + _mapperInstance->removeRangeFromArr(toRemoveFromArr); + } + + + private: + ConvSegMapper *_mapperInstance; + ConvMovement *_activeMovment; + LoopsTracker *_activeLoopTracker; + EdgesStore *_currEdgesStore; + int _loopId; + }; + + struct LoopsTracker { + LoopsTracker(std::list *segmentsList, std::list *anglesList, bool outerLoop): _segmentsList(segmentsList), _anglesList(anglesList), _outerLoop(outerLoop) { + _hasLoop = false; + _loopsCreated = false; + } + + void addLoop(std::pair &loop) { + typename std::list::iterator loop_begin = find(_segmentsList->begin(), _segmentsList->end(), (loop.first)); + typename std::list::iterator loop_end = find(_segmentsList->begin(), _segmentsList->end(), (loop.second)); + /* if (!_hasLoop) + { + _loopBegin = loop_begin; + _loopEnd = loop_end; + _hasLoop = true; + } + else + {*/ + double angleSum = sumLoopAngles(loop_begin, loop_end); + + if ((angleSum > 0 && _outerLoop) || (angleSum < 0 && !_outerLoop)) { + // update loop + _hasLoop = true; + _loopBegin = loop_begin; + _loopEnd = loop_end; + } + + //} + } + + double sumLoopAngles(typename std::list::iterator &loopBegin, typename std::list::iterator &loopEnd) { + int begin = std::distance(_segmentsList->begin(), loopBegin); + int end = std::distance(_segmentsList->begin(), loopEnd); + std::list::iterator itr_begin = _anglesList->begin(); + advance(itr_begin, begin); + std::list::iterator itr_end = _anglesList->begin(); + advance(itr_end, end + 1); + double sum = 0; + + for (std::list::iterator itr = itr_begin; itr != itr_end; ++itr) { + sum += *itr; + } + + return sum; + } + + std::list &getLoopSegmentsList() { + //_loopsSegmentsList; + //copy(_loopBegin,_loopEnd+1,_loopSegmentsList.begin()); + if (!_loopsCreated) { + createLoopsSegmentsLists(); + } + + return _loopSegmentsList; + } + + std::list &getNonLoopSegmentsList() { + /*if (_loopsSegmentsList.size()==0) + getLoopSegmentsList(); + //_loopsSegmentsList; + sort(_loopsSegmentsList.begin(),_loopsSegmentsList.end()); + std::list segmentsListCopy(*_segmentsList); + sort(segmentsListCopy.begin(),segmentsListCopy.end()); + set_difference(segmentsListCopy.begin(),segmentsListCopy.end(),_loopsSegmentsList.begin(),_loopsSegmentsList.end(),_nonLoopSegmentsList.begin()); + return _nonLoopSegmentsList; + */ + if (!_loopsCreated) { + createLoopsSegmentsLists(); + } + + return _nonLoopSegmentsList; + } + + void createLoopsSegmentsLists() { + copy(_segmentsList->begin(), _segmentsList->end(), back_inserter(_nonLoopSegmentsList)); + + if (_hasLoop) { + /*std::list*/ + typename std::list::iterator loop_begin = find(_nonLoopSegmentsList.begin(), _nonLoopSegmentsList.end(), *_loopBegin); + typename std::list::iterator loop_end = find(_nonLoopSegmentsList.begin(), _nonLoopSegmentsList.end(), *_loopEnd); + //std::list _nonLoopSegmentsList(*_segmentsList); + _loopSegmentsList.splice(_loopSegmentsList.begin(), _nonLoopSegmentsList, loop_begin, ++loop_end); + } + + } + + bool hasLoops() { + return _hasLoop; + } + + private: + typename std::list::iterator _loopBegin, _loopEnd; + std::list *_segmentsList; + std::list *_anglesList; + std::list _loopSegmentsList; + std::list _nonLoopSegmentsList; + bool _outerLoop; + bool _hasLoop; + bool _loopsCreated; + }; + + struct EdgesStore { + EdgesStore(ConvSegMapper *mapper) { + _edgesSet = new std::set(); + mapper->fillEdgesSet(*_edgesSet); + // sort(_edgesSet.begin(),_edgesSet.end()); + } + + template void removeRange(InputIterator start, InputIterator end) { + //std::vector vec(start,end); + //sort(vec.begin(),vec.end()); + //sort(start,end); + //std::vector* seg_set = new std::vector(); + //set_difference(_edgesSet->begin(),_edgesSet->end(),vec.begin(),vec.end(),back_inserter(*seg_set)); + //delete _edgesSet; + //_edgesSet = new std::set(seg_set->begin(),seg_set->end()); + + for (InputIterator itr = start; itr != end; ++itr) { + _edgesSet->erase(*itr); + } + + } + + template void removeRange_bak(InputIterator start, InputIterator end) { + std::vector vec(start, end); + sort(vec.begin(), vec.end()); + //sort(start,end); + std::vector *seg_set = new std::vector(); + set_difference(_edgesSet->begin(), _edgesSet->end(), vec.begin(), vec.end(), back_inserter(*seg_set)); + delete _edgesSet; + _edgesSet = new std::set(seg_set->begin(), seg_set->end()); + } + + ConvSegment getEdge() { + return *(_edgesSet->begin()); + } + + bool isEmpty() { + return (_edgesSet->size() == 0); + } + + int getSize() { + return _edgesSet->size(); + } + + private: + std::set *_edgesSet; + }; + + friend class DegenerateCassesManager; + struct DegenerateCassesManager { + DegenerateCassesManager(Arrangement_history_2 *arr, Minkowski_sum_by_convolution_lien_2 *mink, Polygon_2 *poly1, Polygon_2 *poly2, bool isActive): _arr(arr), _mink(mink), _poly1(poly1), _poly2(poly2), _active(isActive) { + + } + + /* + Go over edges and check if they are degenerate */ + void markDegenerateEdges() { + Edge_iterator itr = _arr->edges_begin(); - std::list& getTraversedEdges() - { - return _traversedEdges; - } + for (; itr != _arr->edges_end(); ++itr) { + _mink->setEdgeVisited(*itr, false, -1); - std::list& getAngles() - { - return _angles; - } - private: - int _id; - ConvSegment _currEdge; - std::list _traversedEdges; - std::list _angles; - ConvSegMapper* _mapperInstance; - TraversalManager* _managerInstance; - bool _traversing; - double _anglesSum; - std::pair* _loop; - }; + if (_active) { + if (_mink->checkDegenerateEdgeOppositeSegments(*_arr, itr)) { + if (!_mink->checkSegmentCollisionDetection(*_arr, itr->curve(), *_poly1, *_poly2)) { + _mink->setEdgeDegenerate(*itr, true); + } else { + _mink->setEdgeDegenerate(*itr, false); + } + } else { + _mink->setEdgeDegenerate(*itr, false); + } + } else { + _mink->setEdgeDegenerate(*itr, false); + } - friend class TraversalManager; - class EdgesStore; - class LoopsTracker; - struct TraversalManager - { - TraversalManager(ConvSegMapper* mapperInstance):_mapperInstance(mapperInstance) - { - _loopId = 0; - _activeMovment = NULL; - } - void traverseLoops() - { - EdgesStore edges_db(_mapperInstance); - _currEdgesStore = &edges_db; - int s = edges_db.getSize(); - ConvSegment startEdge = _mapperInstance->getOuterSegment(); - traceLoop(edges_db,startEdge,true); - - while (!edges_db.isEmpty()) - { - int s = edges_db.getSize(); - ++_loopId; - startEdge = edges_db.getEdge(); - traceLoop(edges_db,startEdge,false); - } - - } - - void traceLoop(EdgesStore& edgesDB,ConvSegment& startSeg,bool isOuter) - { - /* if (_activeMovment != NULL) - delete _activeMovment;*/ - _activeMovment = new ConvMovement(_mapperInstance,_loopId,startSeg,this); - - /*if (_activeLoopTracker != NULL) - delete _activeLoopTracker;*/ - _activeLoopTracker = new LoopsTracker(&(_activeMovment->getTraversedEdges()),&(_activeMovment->getAngles()),isOuter); - - _activeMovment->Traverse(); - - // Delete objects - delete _activeMovment; - delete _activeLoopTracker; - } - - void handleCloseLoopEvent(std::pair& loop,std::list& outGoingOptions) - { - _activeLoopTracker->addLoop(loop); - - // check for improvment: (TODO: maybe refactor) - // This checks if the first segment in loop (actually second edge goes into first) is a worse choice then *itr , w.r.t second. - // This means the loop might be improved. - if (_activeLoopTracker->hasLoops()) - { - bool stopItrating = true; - for (typename std::list::iterator itr = outGoingOptions.begin();itr != outGoingOptions.end();++itr) - { - if (_mapperInstance->isBBiggerThenAWithReagrdToC(loop.first,*itr,loop.second)) - { - stopItrating = false; - break; - } - } - - if (stopItrating) - { - handleCloseEvent(); - _activeMovment->stopTraverse(); - } - } - } - - void handleCloseEvent() - { - // remove all traversed edges from segments list - - std::list& traversedEdges = _activeMovment->getTraversedEdges(); - _currEdgesStore->removeRange(traversedEdges.begin(),traversedEdges.end()); - - // remove anything but loop from arrangment. - std::list& toRemoveFromArr = _activeLoopTracker->getNonLoopSegmentsList(); - - _mapperInstance->removeRangeFromArr(toRemoveFromArr); - } + } + } - private: - ConvSegMapper* _mapperInstance; - ConvMovement* _activeMovment; - LoopsTracker* _activeLoopTracker; - EdgesStore* _currEdgesStore; - int _loopId; - }; + /* + Goes over each vertex and checks if it is degenerate. + */ + void findDegenerateBorderVertices() { + if (!_active) { + return; + } - struct LoopsTracker - { - LoopsTracker(std::list* segmentsList,std::list* anglesList,bool outerLoop):_segmentsList(segmentsList),_anglesList(anglesList),_outerLoop(outerLoop) - { - _hasLoop = false; - _loopsCreated = false; - } + Vertex_iterator itr = _arr->vertices_begin(); - void addLoop(std::pair& loop) - { - typename std::list::iterator loop_begin = find(_segmentsList->begin(),_segmentsList->end(),(loop.first)); - typename std::list::iterator loop_end = find(_segmentsList->begin(),_segmentsList->end(),(loop.second)); -/* if (!_hasLoop) - { - _loopBegin = loop_begin; - _loopEnd = loop_end; - _hasLoop = true; - } - else - {*/ - double angleSum = sumLoopAngles(loop_begin,loop_end); - if ((angleSum >0 && _outerLoop) || (angleSum <0 && !_outerLoop)) - {// update loop - _hasLoop = true; - _loopBegin = loop_begin; - _loopEnd = loop_end; - } - //} - } + /* int vertices_num = _arr->number_of_vertices(); + std::valarray vertices_arr(vertices_num); + int i=0; + for (;itr != _arr->vertices_end();++itr) + { + vertices_arr[i] = itr; + ++i; + } - double sumLoopAngles(typename std::list::iterator& loopBegin,typename std::list::iterator& loopEnd) - { - int begin = std::distance(_segmentsList->begin(),loopBegin); - int end = std::distance(_segmentsList->begin(),loopEnd); - std::list::iterator itr_begin = _anglesList->begin(); - advance(itr_begin,begin); - std::list::iterator itr_end = _anglesList->begin(); - advance(itr_end,end + 1); - double sum = 0; - for (std::list::iterator itr = itr_begin;itr != itr_end;++itr) - { - sum += *itr; - } - return sum; - } - - std::list& getLoopSegmentsList() - { - //_loopsSegmentsList; - //copy(_loopBegin,_loopEnd+1,_loopSegmentsList.begin()); - if (!_loopsCreated) - createLoopsSegmentsLists(); - return _loopSegmentsList; - } + Point_2 p_end; + #pragma omp parallel for default(shared),private(p_end)*/ + for (; itr != _arr->vertices_end(); ++itr) + //for (i=0;i& getNonLoopSegmentsList() - { - /*if (_loopsSegmentsList.size()==0) - getLoopSegmentsList(); - //_loopsSegmentsList; - sort(_loopsSegmentsList.begin(),_loopsSegmentsList.end()); - std::list segmentsListCopy(*_segmentsList); - sort(segmentsListCopy.begin(),segmentsListCopy.end()); - set_difference(segmentsListCopy.begin(),segmentsListCopy.end(),_loopsSegmentsList.begin(),_loopsSegmentsList.end(),_nonLoopSegmentsList.begin()); - return _nonLoopSegmentsList; - */ - if (!_loopsCreated) - createLoopsSegmentsLists(); - return _nonLoopSegmentsList; - } + if (_mink->checkDegenarateVertexIsIntersectionOfThreeSegments(*_arr, itr)) + // if (_mink->checkDegenarateVertexIsIntersectionOfThreeSegments(*_arr,vertices_arr[i])) + { + Point_2 p_end = itr->point(); - void createLoopsSegmentsLists() - { - copy(_segmentsList->begin(),_segmentsList->end(),back_inserter(_nonLoopSegmentsList)); - if (_hasLoop) - { - /*std::list*/ - typename std::list::iterator loop_begin = find(_nonLoopSegmentsList.begin(),_nonLoopSegmentsList.end(),*_loopBegin); - typename std::list::iterator loop_end = find(_nonLoopSegmentsList.begin(),_nonLoopSegmentsList.end(),*_loopEnd); - //std::list _nonLoopSegmentsList(*_segmentsList); - _loopSegmentsList.splice(_loopSegmentsList.begin(),_nonLoopSegmentsList,loop_begin,++loop_end); - } - - } + // p_end = vertices_arr[i]->point(); + /* double x2 = CGAL::to_double(p_end.x()); + double y2 = CGAL::to_double(p_end.y()); + std::cout << x2 << "," << y2 << std::endl;*/ + if (!_mink->checkCollisionDetection(*_arr, itr->point(), *_poly1, *_poly2)) + //if (!_mink->checkCollisionDetection(*_arr,vertices_arr[i]->point(),_collision_detector,*_poly1,*_poly2)) + { + //std::cout << "in" << std::endl; + //#pragma omp critical + _degenerate_points_list.push_back(itr->point()); + //_degenerate_points_list.push_back(vertices_arr[i]->point()); + } + } - bool hasLoops() - { - return _hasLoop; - } - - private: - typename std::list::iterator _loopBegin,_loopEnd; - std::list* _segmentsList; - std::list* _anglesList; - std::list _loopSegmentsList; - std::list _nonLoopSegmentsList; - bool _outerLoop; - bool _hasLoop; - bool _loopsCreated; - }; - - struct EdgesStore - { - EdgesStore(ConvSegMapper* mapper) - { - _edgesSet = new std::set(); - mapper->fillEdgesSet(*_edgesSet); - // sort(_edgesSet.begin(),_edgesSet.end()); - } - - template void removeRange(InputIterator start,InputIterator end) - { - //std::vector vec(start,end); - //sort(vec.begin(),vec.end()); - //sort(start,end); - //std::vector* seg_set = new std::vector(); - //set_difference(_edgesSet->begin(),_edgesSet->end(),vec.begin(),vec.end(),back_inserter(*seg_set)); - //delete _edgesSet; - //_edgesSet = new std::set(seg_set->begin(),seg_set->end()); - - for (InputIterator itr = start; itr != end;++itr) - { - _edgesSet->erase(*itr); - } - - } - - template void removeRange_bak(InputIterator start,InputIterator end) - { - std::vector vec(start,end); - sort(vec.begin(),vec.end()); - //sort(start,end); - std::vector* seg_set = new std::vector(); - set_difference(_edgesSet->begin(),_edgesSet->end(),vec.begin(),vec.end(),back_inserter(*seg_set)); - delete _edgesSet; - _edgesSet = new std::set(seg_set->begin(),seg_set->end()); - } - - ConvSegment getEdge() - { - return *(_edgesSet->begin()); - } - - bool isEmpty() - { - return (_edgesSet->size()==0); - } - - int getSize() - { - return _edgesSet->size(); - } - - private: - std::set* _edgesSet; - }; - - friend class DegenerateCassesManager; - struct DegenerateCassesManager - { - DegenerateCassesManager(Arrangement_history_2* arr,Minkowski_sum_by_convolution_lien_2* mink,Polygon_2* poly1,Polygon_2* poly2,bool isActive):_arr(arr),_mink(mink),_poly1(poly1),_poly2(poly2),_active(isActive) - { - - } - - /* - Go over edges and check if they are degenerate - */ - void markDegenerateEdges() - { - Edge_iterator itr = _arr->edges_begin(); - for(;itr != _arr->edges_end();++itr) - { - _mink->setEdgeVisited(*itr,false,-1); - if (_active) - { - if (_mink->checkDegenerateEdgeOppositeSegments(*_arr,itr)) - { - if (!_mink->checkSegmentCollisionDetection(*_arr,itr->curve(),*_poly1,*_poly2)) - { - _mink->setEdgeDegenerate(*itr,true); - } - else - _mink->setEdgeDegenerate(*itr,false); - } - else - _mink->setEdgeDegenerate(*itr,false); - } - else - { - _mink->setEdgeDegenerate(*itr,false); - } - - } - } + //} + } + } - /* - Goes over each vertex and checks if it is degenerate. - */ - void findDegenerateBorderVertices() - { - if (!_active) - return; - Vertex_iterator itr = _arr->vertices_begin(); - /* int vertices_num = _arr->number_of_vertices(); - std::valarray vertices_arr(vertices_num); - int i=0; - for (;itr != _arr->vertices_end();++itr) - { - vertices_arr[i] = itr; - ++i; - } - - Point_2 p_end; - #pragma omp parallel for default(shared),private(p_end)*/ - for (;itr != _arr->vertices_end();++itr) - //for (i=0;icheckDegenarateVertexIsIntersectionOfThreeSegments(*_arr,itr)) - // if (_mink->checkDegenarateVertexIsIntersectionOfThreeSegments(*_arr,vertices_arr[i])) - { - Point_2 p_end = itr->point(); - // p_end = vertices_arr[i]->point(); - /* double x2 = CGAL::to_double(p_end.x()); - double y2 = CGAL::to_double(p_end.y()); - std::cout << x2 << "," << y2 << std::endl;*/ - if (!_mink->checkCollisionDetection(*_arr,itr->point(),*_poly1,*_poly2)) - //if (!_mink->checkCollisionDetection(*_arr,vertices_arr[i]->point(),_collision_detector,*_poly1,*_poly2)) - { - //std::cout << "in" << std::endl; - //#pragma omp critical - _degenerate_points_list.push_back(itr->point()); - //_degenerate_points_list.push_back(vertices_arr[i]->point()); - } - } - //} - } - } + void addDegenerateVerticesToArr() { + typename std::list::iterator itr = _degenerate_points_list.begin(); + for (; itr != _degenerate_points_list.end(); ++itr) { + CGAL::insert_point(*_arr, *itr); - void addDegenerateVerticesToArr() - { - typename std::list::iterator itr = _degenerate_points_list.begin(); - for (;itr != _degenerate_points_list.end();++itr) - { - CGAL::insert_point(*_arr,*itr); - - } - } + } + } - private: - Arrangement_history_2* _arr; - Minkowski_sum_by_convolution_lien_2* _mink; - std::list _degenerate_points_list; - Polygon_2* _poly1; - Polygon_2* _poly2; - //SweepCollisionDetector _collision_detector; - //NaiveCollisionDetector _collision_detector; - bool _active; - }; + private: + Arrangement_history_2 *_arr; + Minkowski_sum_by_convolution_lien_2 *_mink; + std::list _degenerate_points_list; + Polygon_2 *_poly1; + Polygon_2 *_poly2; + //SweepCollisionDetector _collision_detector; + //NaiveCollisionDetector _collision_detector; + bool _active; + }; public: - - /*! Default constructor. */ - Minkowski_sum_by_convolution_lien_2 () - { - // Obtain kernel functors. - Kernel ker; - f_equal = ker.equal_2_object(); - f_add = ker.construct_translated_point_2_object(); - f_vector = ker.construct_vector_2_object(); - f_direction = ker.construct_direction_2_object(); - f_opp_line = ker.construct_opposite_line_2_object(); - f_orientation = ker.orientation_2_object(); - f_compare_xy = ker.compare_xy_2_object(); - f_ccw_in_between = ker.counterclockwise_in_between_2_object(); - f_angle = ker.angle_2_object(); - f_compare_endpoints_xy = Traits_2().compare_endpoints_xy_2_object(); - f_is_vertical = ker.is_vertical_2_object(); - f_compare_x = Traits_2().compare_x_2_object(); - f_compare_y_at_x = Traits_2().compare_y_at_x_2_object(); - f_compute_x = ker.compute_x_2_object(); - f_compute_y = ker.compute_y_2_object(); - } + /*! Default constructor. */ + Minkowski_sum_by_convolution_lien_2() { + // Obtain kernel functors. + Kernel ker; - /*! - * Compute the Minkowski sum of two simple polygons. - * Note that as the input polygons may not be convex, the Minkowski sum may - * not be a simple polygon. The result is therefore represented as - * the outer boundary of the Minkowski sum (which is always a simple polygon) - * and a container of simple polygons, representing the holes inside this - * polygon. - * \param pgn1 The first polygon. - * \param pgn2 The second polygon. - * \param sum_bound Output: A polygon respresenting the outer boundary - * of the Minkowski sum. - * \param sum_holes Output: An output iterator for the holes in the sum, - * represented as simple polygons. - * \pre Both input polygons are simple. - * \return A past-the-end iterator for the holes in the sum. - */ - template - OutputIterator old_version (const Polygon_2& pgn1, - const Polygon_2& pgn2, - Polygon_2& sum_bound, - OutputIterator sum_holes) - { - CGAL_precondition (pgn1.is_simple()); - CGAL_precondition (pgn2.is_simple()); - CGAL_precondition (pgn1.orientation() == CGAL::COUNTERCLOCKWISE); - CGAL_precondition (pgn2.orientation() == CGAL::COUNTERCLOCKWISE); - Polygon_2 revP1 = revPoly(pgn1); - Polygon_2 p2 = pgn2; - _aabb_collision_detector = new AABBCollisionDetector(p2,revP1); - - Segments_list reduced_conv; - buildReducedConvolution(pgn1,pgn2,reduced_conv); + f_equal = ker.equal_2_object(); + f_add = ker.construct_translated_point_2_object(); + f_vector = ker.construct_vector_2_object(); + f_direction = ker.construct_direction_2_object(); + f_opp_line = ker.construct_opposite_line_2_object(); + f_orientation = ker.orientation_2_object(); + f_compare_xy = ker.compare_xy_2_object(); + f_ccw_in_between = ker.counterclockwise_in_between_2_object(); + f_angle = ker.angle_2_object(); + f_compare_endpoints_xy = Traits_2().compare_endpoints_xy_2_object(); + f_is_vertical = ker.is_vertical_2_object(); + f_compare_x = Traits_2().compare_x_2_object(); + f_compare_y_at_x = Traits_2().compare_y_at_x_2_object(); + f_compute_x = ker.compute_x_2_object(); + f_compute_y = ker.compute_y_2_object(); + } - Arrangement_history_2 arr; - buildArrangementFromConv(reduced_conv,arr); - - const Minkowski_sum_by_convolution_lien_2* ptr = this; - // ConvSegMapper mapper( &arr,const_cast (ptr));*/ - DegenerateCassesManager degHandler(&arr,const_cast (ptr),const_cast (&pgn1),const_cast (&pgn2),true); - degHandler.findDegenerateBorderVertices(); - degHandler.markDegenerateEdges(); - constructOrientableLoops(arr); - -/* - if (SHOW_STAGES) - { - global_graphics->clear(); - draw_arr(arr); - global_graphics->display(); - } + /*! + * Compute the Minkowski sum of two simple polygons. + * Note that as the input polygons may not be convex, the Minkowski sum may + * not be a simple polygon. The result is therefore represented as + * the outer boundary of the Minkowski sum (which is always a simple polygon) + * and a container of simple polygons, representing the holes inside this + * polygon. + * \param pgn1 The first polygon. + * \param pgn2 The second polygon. + * \param sum_bound Output: A polygon respresenting the outer boundary + * of the Minkowski sum. + * \param sum_holes Output: An output iterator for the holes in the sum, + * represented as simple polygons. + * \pre Both input polygons are simple. + * \return A past-the-end iterator for the holes in the sum. */ - Polygon_2 reverse_pgn1 = transform(typename Kernel::Aff_transformation_2(CGAL::Rotation(), 0, -1), pgn1); - nestedLoopsFilter(arr,reverse_pgn1,pgn2); - degHandler.addDegenerateVerticesToArr(); - /* - if (SHOW_STAGES) - { - global_graphics->clear(); - draw_arr(arr); - global_graphics->display(); - } - */ - //collisionDetectionFilter(arr); + template + OutputIterator old_version(const Polygon_2 &pgn1, + const Polygon_2 &pgn2, + Polygon_2 &sum_bound, + OutputIterator sum_holes) { + CGAL_precondition(pgn1.is_simple()); + CGAL_precondition(pgn2.is_simple()); + CGAL_precondition(pgn1.orientation() == CGAL::COUNTERCLOCKWISE); + CGAL_precondition(pgn2.orientation() == CGAL::COUNTERCLOCKWISE); + Polygon_2 revP1 = revPoly(pgn1); + Polygon_2 p2 = pgn2; + _aabb_collision_detector = new AABBCollisionDetector(p2, revP1); - //global_graphics->clear(); - - //draw_arr(arr); - //global_graphics->display(); - //for (Segments_list::const_iterator itr = reduced_conv.begin();itr != reduced_conv.end();++itr) - //{ - // Segment_2 temp = *itr; - // Point_2 p_source = temp.source(); - // Point_2 p_end = temp.target(); - // double x1 = CGAL::to_double(p_source.x()); - // double y1 = CGAL::to_double(p_source.y()); - // double x2 = CGAL::to_double(p_end.x()); - // double y2 = CGAL::to_double(p_end.y()); - //// CGAL::insert(arr,temp); - //} - delete _aabb_collision_detector; - return (sum_holes); - } + Segments_list reduced_conv; + buildReducedConvolution(pgn1, pgn2, reduced_conv); + + Arrangement_history_2 arr; + buildArrangementFromConv(reduced_conv, arr); + + const Minkowski_sum_by_convolution_lien_2 *ptr = this; + // ConvSegMapper mapper( &arr,const_cast (ptr));*/ + DegenerateCassesManager degHandler(&arr, const_cast (ptr), const_cast (&pgn1), const_cast (&pgn2), true); + degHandler.findDegenerateBorderVertices(); + degHandler.markDegenerateEdges(); + constructOrientableLoops(arr); + + /* + if (SHOW_STAGES) + { + global_graphics->clear(); + draw_arr(arr); + global_graphics->display(); + } + */ + Polygon_2 reverse_pgn1 = transform(typename Kernel::Aff_transformation_2(CGAL::Rotation(), 0, -1), pgn1); + nestedLoopsFilter(arr, reverse_pgn1, pgn2); + degHandler.addDegenerateVerticesToArr(); + /* + if (SHOW_STAGES) + { + global_graphics->clear(); + draw_arr(arr); + global_graphics->display(); + } + */ + //collisionDetectionFilter(arr); + + //global_graphics->clear(); + + //draw_arr(arr); + //global_graphics->display(); + //for (Segments_list::const_iterator itr = reduced_conv.begin();itr != reduced_conv.end();++itr) + //{ + // Segment_2 temp = *itr; + // Point_2 p_source = temp.source(); + // Point_2 p_end = temp.target(); + // double x1 = CGAL::to_double(p_source.x()); + // double y1 = CGAL::to_double(p_source.y()); + // double x2 = CGAL::to_double(p_end.x()); + // double y2 = CGAL::to_double(p_end.y()); + //// CGAL::insert(arr,temp); + //} + delete _aabb_collision_detector; + return (sum_holes); + } - template - OutputIterator operator() (const Polygon_2& pgn1, - const Polygon_2& pgn2, - Polygon_2& sum_bound, - OutputIterator sum_holes) - { - CGAL_precondition (pgn1.is_simple()); - CGAL_precondition (pgn2.is_simple()); - CGAL_precondition (pgn1.orientation() == CGAL::COUNTERCLOCKWISE); - CGAL_precondition (pgn2.orientation() == CGAL::COUNTERCLOCKWISE); - Polygon_2 revP1 = revPoly(pgn1); - Polygon_2 p2 = pgn2; - boost::timer t_abb; - _aabb_collision_detector = new AABBCollisionDetector(p2,revP1); - double aabb_build_time = t_abb.elapsed(); - //std::cout << "aabb tree build : " < + OutputIterator operator()(const Polygon_2 &pgn1, + const Polygon_2 &pgn2, + Polygon_2 &sum_bound, + OutputIterator sum_holes) { + CGAL_precondition(pgn1.is_simple()); + CGAL_precondition(pgn2.is_simple()); + CGAL_precondition(pgn1.orientation() == CGAL::COUNTERCLOCKWISE); + CGAL_precondition(pgn2.orientation() == CGAL::COUNTERCLOCKWISE); + Polygon_2 revP1 = revPoly(pgn1); + Polygon_2 p2 = pgn2; + boost::timer t_abb; + _aabb_collision_detector = new AABBCollisionDetector(p2, revP1); + double aabb_build_time = t_abb.elapsed(); + //std::cout << "aabb tree build : " <(ptr));*/ - boost::timer t4; - DegenerateCassesManager degHandler(&arr,const_cast (ptr),const_cast (&pgn1),const_cast (&pgn2),true); - degHandler.findDegenerateBorderVertices(); - degHandler.markDegenerateEdges(); - //degenerate_stage = t4.elapsed(); + //LogMyMemoryUsage(); + //std::cout << "sizeOfReducedConvArrangement : " << arr.number_of_edges() << std::endl; - boost::timer t3; - /* - if (SHOW_STAGES) - { - global_graphics->clear(); - draw_arr(arr); - global_graphics->display(); - } - */ - Polygon_2 reverse_pgn1 = transform(typename Kernel::Aff_transformation_2(CGAL::Rotation(), 0, -1), pgn1); + const Minkowski_sum_by_convolution_lien_2 *ptr = this; + // ConvSegMapper mapper( &arr,const_cast (ptr));*/ + boost::timer t4; + DegenerateCassesManager degHandler(&arr, const_cast (ptr), const_cast (&pgn1), const_cast (&pgn2), true); + degHandler.findDegenerateBorderVertices(); + degHandler.markDegenerateEdges(); + //degenerate_stage = t4.elapsed(); - // trace outer loop - markOutsideLoop(arr,sum_bound); + boost::timer t3; + /* + if (SHOW_STAGES) + { + global_graphics->clear(); + draw_arr(arr); + global_graphics->display(); + } + */ + Polygon_2 reverse_pgn1 = transform(typename Kernel::Aff_transformation_2(CGAL::Rotation(), 0, -1), pgn1); - // trace holes -// int num_faces = arr.number_of_faces(); -// std::vector faces_itrs(num_faces); -// int index = 0; -// for (Face_iterator itr = arr.faces_begin();itr!=arr.faces_end();++itr ) -// { -// faces_itrs[index] = itr; -// ++index; -// } -// omp_set_num_threads(4); + // trace outer loop + markOutsideLoop(arr, sum_bound); + + // trace holes +// int num_faces = arr.number_of_faces(); +// std::vector faces_itrs(num_faces); +// int index = 0; +// for (Face_iterator itr = arr.faces_begin();itr!=arr.faces_end();++itr ) +// { +// faces_itrs[index] = itr; +// ++index; +// } +// omp_set_num_threads(4); //#pragma omp threadprivate(_aabb_collision_detector) -//#pragma omp parallel for -// for (int i = 0;i removeList; - // remove all non marked edges - for (Edge_iterator itr = arr.edges_begin();itr != arr.edges_end();++itr) - { - if ((!itr->visited) && (!itr->isDegenerate)) - removeList.push_back(itr); - } +// Original code here ! + for (Face_iterator itr = arr.faces_begin(); itr != arr.faces_end(); ++itr) { + handleFace(arr, itr, reverse_pgn1, pgn2, sum_holes); + } - for (typename std::list::iterator itr = removeList.begin();itr!=removeList.end();++itr) - arr.remove_edge(*itr); - degHandler.addDegenerateVerticesToArr(); - //final_stage_time = t3.elapsed(); - //std::cout << "degenerate stage : " < removeList; + + // remove all non marked edges + for (Edge_iterator itr = arr.edges_begin(); itr != arr.edges_end(); ++itr) { + if ((!itr->visited) && (!itr->isDegenerate)) { + removeList.push_back(itr); + } + } + + for (typename std::list::iterator itr = removeList.begin(); itr != removeList.end(); ++itr) { + arr.remove_edge(*itr); + } + + degHandler.addDegenerateVerticesToArr(); + //final_stage_time = t3.elapsed(); + //std::cout << "degenerate stage : " <clear(); + draw_arr(arr); + global_graphics->display(); + } + */ + + /*constructOrientableLoops(arr); + + if (SHOW_STAGES) + { + global_graphics->clear(); + draw_arr(arr); + global_graphics->display(); + } + Polygon_2 reverse_pgn1 = transform(Kernel::Aff_transformation_2(CGAL::Rotation(), 0, -1), pgn1); + nestedLoopsFilter(arr,reverse_pgn1,pgn2); + degHandler.addDegenerateVerticesToArr(); + if (SHOW_STAGES) + { + global_graphics->clear(); + draw_arr(arr); + global_graphics->display(); + } + */ + //collisionDetectionFilter(arr); + + //global_graphics->clear(); + + //draw_arr(arr); + //global_graphics->display(); + //for (Segments_list::const_iterator itr = reduced_conv.begin();itr != reduced_conv.end();++itr) + //{ + // Segment_2 temp = *itr; + // Point_2 p_source = temp.source(); + // Point_2 p_end = temp.target(); + // double x1 = CGAL::to_double(p_source.x()); + // double y1 = CGAL::to_double(p_source.y()); + // double x2 = CGAL::to_double(p_end.x()); + // double y2 = CGAL::to_double(p_end.y()); + //// CGAL::insert(arr,temp); + //} + delete _aabb_collision_detector; + return (sum_holes); + } + + void markOutsideLoop(Arrangement_history_2 &arr) { + Face_iterator ub_face = arr.unbounded_face(); + Hole_iterator holes_itr = ub_face->holes_begin(); + Ccb_halfedge_circulator circ_start = *holes_itr; + Ccb_halfedge_circulator circ = circ_start; + + do { + setEdgeVisited(*circ, true, 0); + ++circ; + } while (circ != circ_start); + + } + + void markOutsideLoop(Arrangement_history_2 &arr, Polygon_2 &out_bound) { + Face_iterator ub_face = arr.unbounded_face(); + Hole_iterator holes_itr = ub_face->holes_begin(); + Ccb_halfedge_circulator circ_start = *holes_itr; + Ccb_halfedge_circulator circ = circ_start; + + do { + setEdgeVisited(*circ, true, 0); + out_bound.push_back(circ->source()->point()); + --circ; + } while (circ != circ_start); + + } /* - if (SHOW_STAGES) - { - global_graphics->clear(); - draw_arr(arr); - global_graphics->display(); - } - */ + void handleFace(Arrangement_history_2& arr,Face_handle itr,const Polygon_2& reverse_pgn1,const Polygon_2& pgn2) + { + if (itr->holes_begin() != itr->holes_end()) + return; - /*constructOrientableLoops(arr); - - if (SHOW_STAGES) - { - global_graphics->clear(); - draw_arr(arr); - global_graphics->display(); - } - Polygon_2 reverse_pgn1 = transform(Kernel::Aff_transformation_2(CGAL::Rotation(), 0, -1), pgn1); - nestedLoopsFilter(arr,reverse_pgn1,pgn2); - degHandler.addDegenerateVerticesToArr(); - if (SHOW_STAGES) - { - global_graphics->clear(); - draw_arr(arr); - global_graphics->display(); - } - */ - //collisionDetectionFilter(arr); - - //global_graphics->clear(); - - //draw_arr(arr); - //global_graphics->display(); - //for (Segments_list::const_iterator itr = reduced_conv.begin();itr != reduced_conv.end();++itr) - //{ - // Segment_2 temp = *itr; - // Point_2 p_source = temp.source(); - // Point_2 p_end = temp.target(); - // double x1 = CGAL::to_double(p_source.x()); - // double y1 = CGAL::to_double(p_source.y()); - // double x2 = CGAL::to_double(p_end.x()); - // double y2 = CGAL::to_double(p_end.y()); - //// CGAL::insert(arr,temp); - //} - delete _aabb_collision_detector; - return (sum_holes); - } - - void markOutsideLoop(Arrangement_history_2& arr){ - Face_iterator ub_face = arr.unbounded_face(); - Hole_iterator holes_itr = ub_face->holes_begin (); - Ccb_halfedge_circulator circ_start = *holes_itr; - Ccb_halfedge_circulator circ = circ_start; - do{ - setEdgeVisited(*circ,true,0); - ++circ; - }while(circ!=circ_start); - - } - - void markOutsideLoop(Arrangement_history_2& arr, Polygon_2& out_bound){ - Face_iterator ub_face = arr.unbounded_face(); - Hole_iterator holes_itr = ub_face->holes_begin (); - Ccb_halfedge_circulator circ_start = *holes_itr; - Ccb_halfedge_circulator circ = circ_start; - do{ - setEdgeVisited(*circ,true,0); - out_bound.push_back (circ->source()->point()); - --circ; - }while(circ!=circ_start); - - } - /* - void handleFace(Arrangement_history_2& arr,Face_handle itr,const Polygon_2& reverse_pgn1,const Polygon_2& pgn2) - { - if (itr->holes_begin() != itr->holes_end()) - return; - - Ccb_halfedge_circulator start = itr->outer_ccb(); - Ccb_halfedge_circulator circ = start; - - - // orientation check - do{ - if (!checkTripNotSameDirWithSegment(arr,circ)) - return; - ++circ; - }while (circ!=start); - //checkTripNotSameDirWithSegment - - // collision detection check. - bool coll_detect = checkCollisionDetection(arr,start,reverse_pgn1,pgn2); - if (coll_detect) - return; - - // mark as hole - circ = start; - // Polygon_2 pgn_hole; - do{ - setEdgeVisited(*circ,true,0); - // pgn_hole.push_back (circ->source()->point()); - --circ; - }while (circ!=start); - - }*/ - - template - void handleFace(Arrangement_history_2& arr,Face_handle itr,const Polygon_2& reverse_pgn1,const Polygon_2& pgn2,OutputIterator holes) - { - if (itr->holes_begin() != itr->holes_end()) - return; - - Ccb_halfedge_circulator start = itr->outer_ccb(); - Ccb_halfedge_circulator circ = start; + Ccb_halfedge_circulator start = itr->outer_ccb(); + Ccb_halfedge_circulator circ = start; - // orientation check - do{ - if (!checkTripNotSameDirWithSegment(arr,circ)) - return; - ++circ; - }while (circ!=start); - //checkTripNotSameDirWithSegment + // orientation check + do{ + if (!checkTripNotSameDirWithSegment(arr,circ)) + return; + ++circ; + }while (circ!=start); + //checkTripNotSameDirWithSegment - // collision detection check. - bool coll_detect = checkCollisionDetection(arr,start,reverse_pgn1,pgn2); - if (coll_detect) - return; + // collision detection check. + bool coll_detect = checkCollisionDetection(arr,start,reverse_pgn1,pgn2); + if (coll_detect) + return; + + // mark as hole + circ = start; + // Polygon_2 pgn_hole; + do{ + setEdgeVisited(*circ,true,0); + // pgn_hole.push_back (circ->source()->point()); + --circ; + }while (circ!=start); + + }*/ + + template + void handleFace(Arrangement_history_2 &arr, Face_handle itr, const Polygon_2 &reverse_pgn1, const Polygon_2 &pgn2, OutputIterator holes) { + if (itr->holes_begin() != itr->holes_end()) { + return; + } + + Ccb_halfedge_circulator start = itr->outer_ccb(); + Ccb_halfedge_circulator circ = start; + + + // orientation check + do { + if (!checkTripNotSameDirWithSegment(arr, circ)) { + return; + } + + ++circ; + } while (circ != start); + + //checkTripNotSameDirWithSegment + + // collision detection check. + bool coll_detect = checkCollisionDetection(arr, start, reverse_pgn1, pgn2); + + if (coll_detect) { + return; + } + + // mark as hole + circ = start; + Polygon_2 pgn_hole; + + do { + setEdgeVisited(*circ, true, 0); + pgn_hole.push_back(circ->source()->point()); + --circ; + } while (circ != start); - // mark as hole - circ = start; - Polygon_2 pgn_hole; - do{ - setEdgeVisited(*circ,true,0); - pgn_hole.push_back (circ->source()->point()); - --circ; - }while (circ!=start); //#pragma omp critical -// { - *holes = pgn_hole; - ++holes; -// } - - } +// { + *holes = pgn_hole; + ++holes; +// } - /*! - * Compute the boundery Minkowski sum of two simple polygons. - * The result is represented as - * the outer boundary of the Minkowski sum (which is always a simple polygon). - * \param pgn1 The first polygon. - * \param pgn2 The second polygon. - * \param sum_bound Output: A polygon respresenting the outer boundary - * of the Minkowski sum. - * - * \pre Both input polygons are simple. - * \return A past-the-end iterator for the holes in the sum. - */ - template - OutputIterator operator() (const Polygon_2& pgn1, - const Polygon_2& pgn2, - Polygon_2& sum_bound) const - { - CGAL_precondition (pgn1.is_simple()); - CGAL_precondition (pgn2.is_simple()); - - Segments_list reduced_conv; - buildReducedConvolution(pgn1,pgn2,reduced_conv); + } -/* Arrangement_history_2 arr; - buildArrangementFromConv(reduced_conv,arr); -*/ - const Minkowski_sum_by_convolution_lien_2* ptr = this; - // ConvSegMapper mapper( &arr,const_cast (ptr));*/ -/* DegenerateCassesManager degHandler(&arr,const_cast (ptr),const_cast (&pgn1),const_cast (&pgn2)); - degHandler.findDegenerateBorderVertices(); - degHandler.markDegenerateEdges(); - constructOrientableLoops(arr); + /*! + * Compute the boundery Minkowski sum of two simple polygons. + * The result is represented as + * the outer boundary of the Minkowski sum (which is always a simple polygon). + * \param pgn1 The first polygon. + * \param pgn2 The second polygon. + * \param sum_bound Output: A polygon respresenting the outer boundary + * of the Minkowski sum. + * + * \pre Both input polygons are simple. + * \return A past-the-end iterator for the holes in the sum. + */ + template + OutputIterator operator()(const Polygon_2 &pgn1, + const Polygon_2 &pgn2, + Polygon_2 &sum_bound) const { + CGAL_precondition(pgn1.is_simple()); + CGAL_precondition(pgn2.is_simple()); - if (SHOW_STAGES) - { - global_graphics->clear(); - draw_arr(arr); - global_graphics->display(); - } - Polygon_2 reverse_pgn1 = transform(Kernel::Aff_transformation_2(CGAL::Rotation(), 0, -1), pgn1); - nestedLoopsFilter(arr,reverse_pgn1,pgn2); - degHandler.addDegenerateVerticesToArr(); - if (SHOW_STAGES) - { - global_graphics->clear(); - draw_arr(arr); - global_graphics->display(); - } - */ - } + Segments_list reduced_conv; + buildReducedConvolution(pgn1, pgn2, reduced_conv); + + /* Arrangement_history_2 arr; + buildArrangementFromConv(reduced_conv,arr); + */ + const Minkowski_sum_by_convolution_lien_2 *ptr = this; + // ConvSegMapper mapper( &arr,const_cast (ptr));*/ + /* DegenerateCassesManager degHandler(&arr,const_cast (ptr),const_cast (&pgn1),const_cast (&pgn2)); + degHandler.findDegenerateBorderVertices(); + degHandler.markDegenerateEdges(); + constructOrientableLoops(arr); + + if (SHOW_STAGES) + { + global_graphics->clear(); + draw_arr(arr); + global_graphics->display(); + } + Polygon_2 reverse_pgn1 = transform(Kernel::Aff_transformation_2(CGAL::Rotation(), 0, -1), pgn1); + nestedLoopsFilter(arr,reverse_pgn1,pgn2); + degHandler.addDegenerateVerticesToArr(); + if (SHOW_STAGES) + { + global_graphics->clear(); + draw_arr(arr); + global_graphics->display(); + } + */ + } - void fillPolyDirs(const Polygon_2& pgn1,std::vector& outVec) const - { - unsigned int n1 = pgn1.size(); - for (int i=0;i<(n1-1);++i) - { - outVec[i] = f_direction(f_vector(pgn1[i],pgn1[i+1])); + void fillPolyDirs(const Polygon_2 &pgn1, std::vector &outVec) const { + unsigned int n1 = pgn1.size(); - } - outVec[n1-1] = f_direction(f_vector(pgn1[n1-1],pgn1[0])); - } - void buildReducedConvolution(const Polygon_2& pgn1, const Polygon_2& pgn2, Segments_list& reduced_conv) const - { - unsigned int n1 = pgn1.size(); - unsigned int n2 = pgn2.size(); - Vertex_circulator vert_p1,vert_p2,prev_p1,prev_p2,next_p1,next_p2; - vert_p1 = prev_p1 = next_p1 = pgn1.vertices_circulator(); - vert_p2 = prev_p2 = next_p2 = pgn2.vertices_circulator(); + for (int i = 0; i < (n1 - 1); ++i) { + outVec[i] = f_direction(f_vector(pgn1[i], pgn1[i + 1])); - --prev_p1; - --prev_p2; - ++next_p1; - ++next_p2; - bool is_end_coincide; - bool is_start_coincide; + } - boost::unordered_map,Point_2> points_map; - for (unsigned int i1 = 0;i1(i1,i2)] = f_add(*vert_p1,Vector_2(Point_2(ORIGIN),*vert_p2)); - ++vert_p2; - } - ++vert_p1; - } + outVec[n1 - 1] = f_direction(f_vector(pgn1[n1 - 1], pgn1[0])); + } + void buildReducedConvolution(const Polygon_2 &pgn1, const Polygon_2 &pgn2, Segments_list &reduced_conv) const { + unsigned int n1 = pgn1.size(); + unsigned int n2 = pgn2.size(); + Vertex_circulator vert_p1, vert_p2, prev_p1, prev_p2, next_p1, next_p2; + vert_p1 = prev_p1 = next_p1 = pgn1.vertices_circulator(); + vert_p2 = prev_p2 = next_p2 = pgn2.vertices_circulator(); - std::vector p1_dirs(n1); - std::vector p2_dirs(n2); - - fillPolyDirs(pgn1,p1_dirs); - fillPolyDirs(pgn2,p2_dirs); + --prev_p1; + --prev_p2; + ++next_p1; + ++next_p2; + bool is_end_coincide; + bool is_start_coincide; - vert_p1 = pgn1.vertices_circulator(); - vert_p2 = pgn2.vertices_circulator(); + boost::unordered_map, Point_2> points_map; - for (unsigned int i1 = 0;i1(i1,i2)]; - int prev_i1 = i1-1; - if (prev_i1 == -1) - prev_i1 = n1-1; - int prev_i2 = i2-1; - if (prev_i2 == -1) - prev_i2 = n2-1; - //if (!checkReflex(*prev_p1,*vert_p1,*next_p1) && checkSwept(*prev_p1,*vert_p1,*next_p1,*vert_p2,*next_p2,is_start_coincide,is_end_coincide)){ - if (!checkReflex(*prev_p1,*vert_p1,*next_p1) && checkSwept(p1_dirs[prev_i1],p1_dirs[i1],p2_dirs[i2],is_start_coincide,is_end_coincide)){ - //Point_2 end_point = f_add(start_point,Vector_2(*vert_p2,*next_p2)); - int cyc_ind = i2; - ++cyc_ind; - if (cyc_ind==n2) - cyc_ind = 0; - Point_2 end_point = points_map[std::pair(i1,cyc_ind)]; + for (unsigned int i1 = 0; i1 < n1; ++i1) { + for (unsigned int i2 = 0; i2 < n2; ++i2) { + points_map[std::pair(i1, i2)] = f_add(*vert_p1, Vector_2(Point_2(ORIGIN), *vert_p2)); + ++vert_p2; + } - /* double x1 = CGAL::to_double(start_point.x()); - double y1 = CGAL::to_double(start_point.y()); - double x2 = CGAL::to_double(end_point.x()); - double y2 = CGAL::to_double(end_point.y()); - double x3 = CGAL::to_double((*vert_p2).x()); - double y3 = CGAL::to_double((*vert_p2).y()); - double x4 = CGAL::to_double((*vert_p1).x()); - double y4 = CGAL::to_double((*vert_p1).y());*/ - CGAL::Comparison_result cres = f_compare_xy(start_point,end_point); - Segment_2 conv_seg = Segment_2(Traits_2_A::Segment_2(start_point,end_point),cres); - //Segment_2 conv_seg; - //if (cres == CGAL::SMALLER) - //{ - // //Traits_2_B::X_monotone_curve_2 tempseg = Traits_2_B::X_monotone_curve_2(Traits_2_A::Segment_2(start_point,end_point),Segment_Data_Label(i1+i2*n1,i1+cyc_ind*n1)); - // conv_seg = Segment_2(Traits_2_A::Segment_2(start_point,end_point),Segment_Data_Label(i1+i2*n1,i1+cyc_ind*n1,cres)); - //} - //else - // conv_seg = Segment_2(Traits_2_A::Segment_2(start_point,end_point),Segment_Data_Label(i1+cyc_ind*n1,i1+i2*n1,cres)); - //CGAL::Comparison_result aaa = conv_seg.data(); - if (!is_end_coincide) - reduced_conv.push_back(conv_seg); - } - //if (!checkReflex(*prev_p2,*vert_p2,*next_p2) && checkSwept(*prev_p2,*vert_p2,*next_p2,*vert_p1,*next_p1,is_start_coincide,is_end_coincide)){ - if (!checkReflex(*prev_p2,*vert_p2,*next_p2) && checkSwept(p2_dirs[prev_i2],p2_dirs[i2],p1_dirs[i1],is_start_coincide,is_end_coincide)){ - //Point_2 end_point = f_add(start_point,Vector_2(*vert_p1,*next_p1)); - int cyc_ind = i1; - ++cyc_ind; - if (cyc_ind==n1) - cyc_ind = 0; - Point_2 end_point = points_map[std::pair(cyc_ind,i2)]; + ++vert_p1; + } + + std::vector p1_dirs(n1); + std::vector p2_dirs(n2); + + fillPolyDirs(pgn1, p1_dirs); + fillPolyDirs(pgn2, p2_dirs); + + vert_p1 = pgn1.vertices_circulator(); + vert_p2 = pgn2.vertices_circulator(); + + for (unsigned int i1 = 0; i1 < n1; ++i1) { + for (unsigned int i2 = 0; i2 < n2; ++i2) { + + //Point_2 start_point = f_add(*vert_p1,Vector_2(Point_2(ORIGIN),*vert_p2)); + Point_2 start_point = points_map[std::pair(i1, i2)]; + int prev_i1 = i1 - 1; + + if (prev_i1 == -1) { + prev_i1 = n1 - 1; + } + + int prev_i2 = i2 - 1; + + if (prev_i2 == -1) { + prev_i2 = n2 - 1; + } + + //if (!checkReflex(*prev_p1,*vert_p1,*next_p1) && checkSwept(*prev_p1,*vert_p1,*next_p1,*vert_p2,*next_p2,is_start_coincide,is_end_coincide)){ + if (!checkReflex(*prev_p1, *vert_p1, *next_p1) && checkSwept(p1_dirs[prev_i1], p1_dirs[i1], p2_dirs[i2], is_start_coincide, is_end_coincide)) { + //Point_2 end_point = f_add(start_point,Vector_2(*vert_p2,*next_p2)); + int cyc_ind = i2; + ++cyc_ind; + + if (cyc_ind == n2) { + cyc_ind = 0; + } + + Point_2 end_point = points_map[std::pair(i1, cyc_ind)]; + + /* double x1 = CGAL::to_double(start_point.x()); + double y1 = CGAL::to_double(start_point.y()); + double x2 = CGAL::to_double(end_point.x()); + double y2 = CGAL::to_double(end_point.y()); + double x3 = CGAL::to_double((*vert_p2).x()); + double y3 = CGAL::to_double((*vert_p2).y()); + double x4 = CGAL::to_double((*vert_p1).x()); + double y4 = CGAL::to_double((*vert_p1).y());*/ + CGAL::Comparison_result cres = f_compare_xy(start_point, end_point); + Segment_2 conv_seg = Segment_2(Traits_2_A::Segment_2(start_point, end_point), cres); + + //Segment_2 conv_seg; + //if (cres == CGAL::SMALLER) + //{ + // //Traits_2_B::X_monotone_curve_2 tempseg = Traits_2_B::X_monotone_curve_2(Traits_2_A::Segment_2(start_point,end_point),Segment_Data_Label(i1+i2*n1,i1+cyc_ind*n1)); + // conv_seg = Segment_2(Traits_2_A::Segment_2(start_point,end_point),Segment_Data_Label(i1+i2*n1,i1+cyc_ind*n1,cres)); + //} + //else + // conv_seg = Segment_2(Traits_2_A::Segment_2(start_point,end_point),Segment_Data_Label(i1+cyc_ind*n1,i1+i2*n1,cres)); + //CGAL::Comparison_result aaa = conv_seg.data(); + if (!is_end_coincide) { + reduced_conv.push_back(conv_seg); + } + } + + //if (!checkReflex(*prev_p2,*vert_p2,*next_p2) && checkSwept(*prev_p2,*vert_p2,*next_p2,*vert_p1,*next_p1,is_start_coincide,is_end_coincide)){ + if (!checkReflex(*prev_p2, *vert_p2, *next_p2) && checkSwept(p2_dirs[prev_i2], p2_dirs[i2], p1_dirs[i1], is_start_coincide, is_end_coincide)) { + //Point_2 end_point = f_add(start_point,Vector_2(*vert_p1,*next_p1)); + int cyc_ind = i1; + ++cyc_ind; + + if (cyc_ind == n1) { + cyc_ind = 0; + } + + Point_2 end_point = points_map[std::pair(cyc_ind, i2)]; - //Segment_2 conv_seg = Segment_2(Traits_2_A::Segment_2(start_point,end_point),f_compare_xy(start_point,end_point)); - CGAL::Comparison_result cres = f_compare_xy(start_point,end_point); - Segment_2 conv_seg = Segment_2(Traits_2_A::Segment_2(start_point,end_point),cres); - /*Segment_2 conv_seg; - if (cres == CGAL::SMALLER) - conv_seg = Segment_2(Traits_2_A::Segment_2(start_point,end_point),Segment_Data_Label(i1+i2*n1,cyc_ind+i2*n1,cres)); - else - conv_seg = Segment_2(Traits_2_A::Segment_2(start_point,end_point),Segment_Data_Label(cyc_ind+i2*n1,i1+i2*n1,cres));*/ + //Segment_2 conv_seg = Segment_2(Traits_2_A::Segment_2(start_point,end_point),f_compare_xy(start_point,end_point)); + CGAL::Comparison_result cres = f_compare_xy(start_point, end_point); + Segment_2 conv_seg = Segment_2(Traits_2_A::Segment_2(start_point, end_point), cres); + /*Segment_2 conv_seg; + if (cres == CGAL::SMALLER) + conv_seg = Segment_2(Traits_2_A::Segment_2(start_point,end_point),Segment_Data_Label(i1+i2*n1,cyc_ind+i2*n1,cres)); + else + conv_seg = Segment_2(Traits_2_A::Segment_2(start_point,end_point),Segment_Data_Label(cyc_ind+i2*n1,i1+i2*n1,cres));*/ - //Segment_2 conv_seg = Segment_2(start_point,end_point,f_compare_xy(start_point,end_point)); - if (!is_start_coincide) - reduced_conv.push_back(conv_seg); - } - - prev_p2 = vert_p2; - vert_p2 = next_p2; - ++next_p2; - - } - prev_p1 = vert_p1; - vert_p1 = next_p1; - ++next_p1; - } + //Segment_2 conv_seg = Segment_2(start_point,end_point,f_compare_xy(start_point,end_point)); + if (!is_start_coincide) { + reduced_conv.push_back(conv_seg); + } + } - } + prev_p2 = vert_p2; + vert_p2 = next_p2; + ++next_p2; - // Increse a cyclic integer counter with limit lim. - int cyclicInc(int i,int lim) const - { - i = i+1; - if (i>=lim) - i= 0; - return i; - } + } - // Decrease a cyclic integer counter with limit lim. - int cyclicDec(int i,int lim) const - { - i = i-1; - if (i<0) - i= lim-1; - return i; - } + prev_p1 = vert_p1; + vert_p1 = next_p1; + ++next_p1; + } - // Gets point corresponding to a state (i,j) if exists, creates this point if asked for first time. - Point_2 addGetPoint(int i1,int i2,boost::unordered_map,Point_2>& points_map,const Polygon_2& pgn1, const Polygon_2& pgn2) const - { - Point_2 result; - if (points_map.count(StatePair(i1,i2))==0) - { - result = f_add(pgn1[i1],Vector_2(Point_2(ORIGIN),pgn2[i2])); - points_map[StatePair(i1,i2)] = result; - } - else - result = points_map[StatePair(i1,i2)]; - return result; - } + } - // Builds the reduced convolution using the fiber grid approach. for each starting vertex, try to add out-going next states(two states). - // If a visited vertex is reached then do not explore. This is a BFS like iteration beggining from each vertex in the first column of the - // fiber grid. - void buildReducedConvolutionFiberGrid(const Polygon_2& pgn1, const Polygon_2& pgn2, Segments_list& reduced_conv) const - { - unsigned int n1 = pgn1.size(); - unsigned int n2 = pgn2.size(); - int i1 = 0; - int i2 = 0; + // Increse a cyclic integer counter with limit lim. + int cyclicInc(int i, int lim) const { + i = i + 1; - bool is_end_coincide; - bool is_start_coincide; + if (i >= lim) { + i = 0; + } - // Init the direcions of both polygons. - std::vector p1_dirs(n1); - std::vector p2_dirs(n2); - - fillPolyDirs(pgn1,p1_dirs); - fillPolyDirs(pgn2,p2_dirs); + return i; + } - - boost::unordered_set visited_vertices_set; - std::queue state_queue; - boost::unordered_map,Point_2> points_map; + // Decrease a cyclic integer counter with limit lim. + int cyclicDec(int i, int lim) const { + i = i - 1; - // init the queue with vertices from the first column - for (int i=n1-1;i>=0;--i){ - state_queue.push(StatePair(i,0)); - } + if (i < 0) { + i = lim - 1; + } - - while (state_queue.size() > 0){ - StatePair curr_state = state_queue.front(); - state_queue.pop(); + return i; + } - i1 = curr_state.first; - i2 = curr_state.second; + // Gets point corresponding to a state (i,j) if exists, creates this point if asked for first time. + Point_2 addGetPoint(int i1, int i2, boost::unordered_map, Point_2> &points_map, const Polygon_2 &pgn1, const Polygon_2 &pgn2) const { + Point_2 result; - if (visited_vertices_set.count(curr_state) > 0) - continue; + if (points_map.count(StatePair(i1, i2)) == 0) { + result = f_add(pgn1[i1], Vector_2(Point_2(ORIGIN), pgn2[i2])); + points_map[StatePair(i1, i2)] = result; + } else { + result = points_map[StatePair(i1, i2)]; + } - visited_vertices_set.insert(curr_state); + return result; + } - // add two outgoing edges: - int next_p1 = cyclicInc(i1,n1); - int next_p2 = cyclicInc(i2,n2); - int prev_p1 = cyclicDec(i1,n1); - int prev_p2 = cyclicDec(i2,n2); + // Builds the reduced convolution using the fiber grid approach. for each starting vertex, try to add out-going next states(two states). + // If a visited vertex is reached then do not explore. This is a BFS like iteration beggining from each vertex in the first column of the + // fiber grid. + void buildReducedConvolutionFiberGrid(const Polygon_2 &pgn1, const Polygon_2 &pgn2, Segments_list &reduced_conv) const { + unsigned int n1 = pgn1.size(); + unsigned int n2 = pgn2.size(); + int i1 = 0; + int i2 = 0; + + bool is_end_coincide; + bool is_start_coincide; + + // Init the direcions of both polygons. + std::vector p1_dirs(n1); + std::vector p2_dirs(n2); + + fillPolyDirs(pgn1, p1_dirs); + fillPolyDirs(pgn2, p2_dirs); - StatePair next_state_p1 = StatePair(next_p1,i2); - StatePair next_state_p2 = StatePair(i1,next_p2); - - + boost::unordered_set visited_vertices_set; + std::queue state_queue; + boost::unordered_map, Point_2> points_map; - // add geometric entites of the transition from state (i,j) to (i+1,j) and (i,j+1), if they are in the reduced convolution. - - - // Add an edge from Q - if (checkSwept(p1_dirs[prev_p1],p1_dirs[i1],p2_dirs[i2],is_start_coincide,is_end_coincide) && !is_end_coincide) - { - state_queue.push(next_state_p2); - if (!checkReflex(pgn1[prev_p1],pgn1[i1],pgn1[next_p1])) - { - //if (!is_end_coincide) // symbolic rotation - //{ - Point_2 start_point = addGetPoint(i1,i2,points_map,pgn1,pgn2); - Point_2 end_point = addGetPoint(i1,next_p2,points_map,pgn1,pgn2); + // init the queue with vertices from the first column + for (int i = n1 - 1; i >= 0; --i) { + state_queue.push(StatePair(i, 0)); + } - CGAL::Comparison_result cres = f_compare_xy(start_point,end_point); - //Segment_2 conv_seg = Segment_2(Traits_2_A::Segment_2(start_point,end_point),Segment_Data_Label(state(i1,i2),state(i1,next_p2),cres)); - Segment_2 conv_seg = Segment_2(typename Traits_2_A::Segment_2(start_point,end_point),Segment_Data_Label(state(i1,i2),state(i1,next_p2),cres,1)); - //Segment_2 conv_seg = Segment_2(Traits_2_A::Segment_2(start_point,end_point),cres); - - reduced_conv.push_back(conv_seg); - //} - } - } - - // Add an edge from P - if (checkSwept(p2_dirs[prev_p2],p2_dirs[i2],p1_dirs[i1],is_start_coincide,is_end_coincide) && !is_start_coincide) - { - state_queue.push(next_state_p1); - if (!checkReflex(pgn2[prev_p2],pgn2[i2],pgn2[next_p2]) ){ - //if () // symbolic rotation - //{ - Point_2 start_point = addGetPoint(i1,i2,points_map,pgn1,pgn2); - Point_2 end_point = addGetPoint(next_p1,i2,points_map,pgn1,pgn2); - CGAL::Comparison_result cres = f_compare_xy(start_point,end_point); - Segment_2 conv_seg = Segment_2(typename Traits_2_A::Segment_2(start_point,end_point),Segment_Data_Label(state(i1,i2),state(next_p1,i2),cres,0)); - //Segment_2 conv_seg = Segment_2(Traits_2_A::Segment_2(start_point,end_point),cres); - reduced_conv.push_back(conv_seg); - //} - } - } - } + while (state_queue.size() > 0) { + StatePair curr_state = state_queue.front(); + state_queue.pop(); - } + i1 = curr_state.first; + i2 = curr_state.second; + + if (visited_vertices_set.count(curr_state) > 0) { + continue; + } + + visited_vertices_set.insert(curr_state); + + // add two outgoing edges: + int next_p1 = cyclicInc(i1, n1); + int next_p2 = cyclicInc(i2, n2); + int prev_p1 = cyclicDec(i1, n1); + int prev_p2 = cyclicDec(i2, n2); + + + StatePair next_state_p1 = StatePair(next_p1, i2); + StatePair next_state_p2 = StatePair(i1, next_p2); + + + + // add geometric entites of the transition from state (i,j) to (i+1,j) and (i,j+1), if they are in the reduced convolution. + + + // Add an edge from Q + if (checkSwept(p1_dirs[prev_p1], p1_dirs[i1], p2_dirs[i2], is_start_coincide, is_end_coincide) && !is_end_coincide) { + state_queue.push(next_state_p2); + + if (!checkReflex(pgn1[prev_p1], pgn1[i1], pgn1[next_p1])) { + //if (!is_end_coincide) // symbolic rotation + //{ + Point_2 start_point = addGetPoint(i1, i2, points_map, pgn1, pgn2); + Point_2 end_point = addGetPoint(i1, next_p2, points_map, pgn1, pgn2); + + CGAL::Comparison_result cres = f_compare_xy(start_point, end_point); + //Segment_2 conv_seg = Segment_2(Traits_2_A::Segment_2(start_point,end_point),Segment_Data_Label(state(i1,i2),state(i1,next_p2),cres)); + Segment_2 conv_seg = Segment_2(typename Traits_2_A::Segment_2(start_point, end_point), Segment_Data_Label(state(i1, i2), state(i1, next_p2), cres, 1)); + //Segment_2 conv_seg = Segment_2(Traits_2_A::Segment_2(start_point,end_point),cres); + + reduced_conv.push_back(conv_seg); + //} + } + } + + // Add an edge from P + if (checkSwept(p2_dirs[prev_p2], p2_dirs[i2], p1_dirs[i1], is_start_coincide, is_end_coincide) && !is_start_coincide) { + state_queue.push(next_state_p1); + + if (!checkReflex(pgn2[prev_p2], pgn2[i2], pgn2[next_p2])) { + //if () // symbolic rotation + //{ + Point_2 start_point = addGetPoint(i1, i2, points_map, pgn1, pgn2); + Point_2 end_point = addGetPoint(next_p1, i2, points_map, pgn1, pgn2); + + CGAL::Comparison_result cres = f_compare_xy(start_point, end_point); + Segment_2 conv_seg = Segment_2(typename Traits_2_A::Segment_2(start_point, end_point), Segment_Data_Label(state(i1, i2), state(next_p1, i2), cres, 0)); + //Segment_2 conv_seg = Segment_2(Traits_2_A::Segment_2(start_point,end_point),cres); + reduced_conv.push_back(conv_seg); + //} + } + } + } + + } private: - SweepCollisionDetector collision_detector; - AABBCollisionDetector* _aabb_collision_detector; - /* - Perform final stage of filtering : collision detection. - */ -/* void collisionDetectionFilter(Arrangement_history_2& arr) const - { - ICollisionDetector& collision_detector = new NaiveCollisionDetector(); - Face_iterator startFace = arr.unbounded_face(); - Hole_iterator hi; - Ccb_halfedge_circulator perimiterFace; - for (hi = startFace->holes_begin(); hi != startFace->holes_end(); ++hi) { - perimiterFace = *hi; - } + SweepCollisionDetector collision_detector; + AABBCollisionDetector *_aabb_collision_detector; + /* + Perform final stage of filtering : collision detection. + */ + /* void collisionDetectionFilter(Arrangement_history_2& arr) const + { + ICollisionDetector& collision_detector = new NaiveCollisionDetector(); + Face_iterator startFace = arr.unbounded_face(); + Hole_iterator hi; + Ccb_halfedge_circulator perimiterFace; + for (hi = startFace->holes_begin(); hi != startFace->holes_end(); ++hi) { + perimiterFace = *hi; + } - Halfedge_handle inside_face_edge = hi->twin(); - Face_handle container_face = inside_face_edge->face(); + Halfedge_handle inside_face_edge = hi->twin(); + Face_handle container_face = inside_face_edge->face(); - } -*/ - /* - Performs the stage 3 of filtering: removing nested loops which are not in the correct orientation. - */ - void nestedLoopsFilter(Arrangement_history_2& arr,const Polygon_2& pgn1,const Polygon_2& pgn2) const - { - Face_iterator startFace = arr.unbounded_face(); - Hole_iterator hi; - Ccb_halfedge_circulator perimiterFace; - for (hi = startFace->holes_begin(); hi != startFace->holes_end(); ++hi) { - perimiterFace = *hi; - } + } + */ + /* + Performs the stage 3 of filtering: removing nested loops which are not in the correct orientation. + */ + void nestedLoopsFilter(Arrangement_history_2 &arr, const Polygon_2 &pgn1, const Polygon_2 &pgn2) const { + Face_iterator startFace = arr.unbounded_face(); + Hole_iterator hi; + Ccb_halfedge_circulator perimiterFace; - //std::cout << "nested loop start\n"; - - // now for each hole in main face we will determine it's orientation. - nestedLoopsFilterRec(arr,perimiterFace,false,pgn1,pgn2); - } + for (hi = startFace->holes_begin(); hi != startFace->holes_end(); ++hi) { + perimiterFace = *hi; + } - /* - For each loop we represent it by the halfedge which is the twin of the face loop. - ie this edge is part of the clockwise oriented halfedges loop outside the face. - */ - void nestedLoopsFilterRec(Arrangement_history_2& arr,Halfedge_handle& handle,bool inwards,const Polygon_2& pgn1,const Polygon_2& pgn2) const - { - std::list holesEdges; - std::list after_removal_hole_edges; - std::list faces_list; + //std::cout << "nested loop start\n"; - Face_iterator startFace = arr.unbounded_face(); - Halfedge_handle inside_face_edge = handle->twin(); - Face_handle container_face = inside_face_edge->face(); - - Face_iterator face_itr=arr.faces_begin(); - for (;face_itr!=arr.faces_end();++face_itr) - { - if (!(face_itr->is_unbounded()) && face_itr!= container_face) - { - Halfedge_handle h_e = face_itr->outer_ccb()->twin(); - holesEdges.push_back(h_e); - } - } - - while(holesEdges.size() > 0) // remove loops from faces - { - /*int bla = holesEdges.size(); - std::cout << "in holes: " << bla << "\n";*/ - Halfedge_handle he = holesEdges.front(); - // printHe(he); - holesEdges.pop_front(); - - if (!he->isDegenerate) - { - if (!removeAllNonConformingLoops(arr,he,inwards,holesEdges,pgn1,pgn2)) - { - - - /*for (hi = startFace->holes_begin(); hi != startFace->holes_end(); ++hi) { - perimiterFace = *hi; - }*/ - /*std::cout << "not removed"; - int bla = holesEdges.size(); - std::cout << "in holes: " << bla << "\n";*/ - after_removal_hole_edges.push_back(he); - } - } - /*else - { - std::cout << "degen not removed"; - int bla = holesEdges.size(); - std::cout << "in holes: " << bla << "\n"; - }*/ - - } - Hole_iterator hi; - //Ccb_halfedge_circulator perimiterFace; - hi = startFace->holes_begin(); - container_face = (*hi)->twin()->face(); - /* global_graphics->clear(); - - draw_arr(arr); - global_graphics->display();*/ -// Hole_iterator hi; - Ccb_halfedge_circulator outside_face_itr; - // push initial list of holes to list. - for (hi =container_face->holes_begin();hi!= container_face->holes_end(); ++hi ) // remove degenrate cases which are false - { - outside_face_itr = *hi; - Halfedge_handle h_e= outside_face_itr;//->twin(); - holesEdges.push_back(h_e); - } - - while(holesEdges.size() > 0) - { - /* int bla = holesEdges.size(); - std::cout << "in holes: " << bla << "\n";*/ - Halfedge_handle he = holesEdges.front(); - // printHe(he); - holesEdges.pop_front(); - - if (!he->isDegenerate) - { - if (!removeAllNonConformingLoops(arr,he,inwards,holesEdges,pgn1,pgn2)) - { - Hole_iterator hi; - //Ccb_halfedge_circulator perimiterFace; - /* hi = startFace->holes_begin(); - container_face = (*hi)->twin()->face();*/ - /* std::cout << "not removed"; - int bla = holesEdges.size(); - std::cout << "in holes: " << bla << "\n";*/ - after_removal_hole_edges.push_back(he); - } - } - /*else - { - std::cout << "degen not removed"; - int bla = holesEdges.size(); - std::cout << "in holes: " << bla << "\n"; - }*/ - - } - - // std::list semi_holes; - //findSemiHoles(arr,handle,semi_holes); - // holesEdges.insert(holesEdges.begin(),semi_holes.begin(),semi_holes.end()); - - // while we still have holes , leave only loops orientable with current direction. - - /* std::cout << "number of hole edges " << holesEdges.size() << "\n"; - std::cout << arr.number_of_faces() << " faces:" << std::endl; - - - std::cout << arr.number_of_faces() << " faces:" << std::endl;*/ -/* global_graphics->clear(); - - draw_arr(arr); - global_graphics->display(); - */ - -/* for (std::list::iterator itr = after_removal_hole_edges.begin();itr != after_removal_hole_edges.end() ; ++itr) - { - nestedLoopsFilterRec(arr,*itr, !inwards,pgn1,pgn2); - } - */ - /*container_face = inside_face_edge->face(); - // now all the holes are in correct orientation, recursivaly call this func: - for (hi =container_face->holes_begin();hi!= container_face->holes_end(); ++hi ) - { - outside_face_itr = *hi; - nestedLoopsFilterRec(arr,outside_face_itr, !inwards,pgn1,pgn2); - // Halfedge_handle h_e= outside_face_itr.twin(); - // holesEdges.push_back(h_e); - }*/ - } - - - -// /* -// For each loop we represent it by the halfedge which is the twin of the face loop. -// ie this edge is part of the clockwise oriented halfedges loop outside the face. -// */ -// void nestedLoopsFilterRec(Arrangement_history_2& arr,Halfedge_handle& handle,bool inwards,const Polygon_2& pgn1,const Polygon_2& pgn2) const -// { -// std::list holesEdges; -// std::list after_removal_hole_edges; -// // std::list faces_list; -// -// -// Halfedge_handle inside_face_edge = handle->twin(); -// Face_handle container_face = inside_face_edge->face(); -// -// -// -// Hole_iterator hi; -// Ccb_halfedge_circulator outside_face_itr; -// // push initial list of holes to list. -// for (hi =container_face->holes_begin();hi!= container_face->holes_end(); ++hi ) -// { -// outside_face_itr = *hi; -// Halfedge_handle h_e= outside_face_itr;//->twin(); -// holesEdges.push_back(h_e); -// } -// -// // std::list semi_holes; -// //findSemiHoles(arr,handle,semi_holes); -// // holesEdges.insert(holesEdges.begin(),semi_holes.begin(),semi_holes.end()); -// -// // while we still have holes , leave only loops orientable with current direction. -// -// std::cout << "number of hole edges " << holesEdges.size() << "\n"; -// std::cout << arr.number_of_faces() << " faces:" << std::endl; -// while(holesEdges.size() > 0) -// { -// /* int bla = holesEdges.size(); -// std::cout << "in holes: " << bla << "\n";*/ -// Halfedge_handle he = holesEdges.front(); -// // printHe(he); -// holesEdges.pop_front(); -// -// if (!he->isDegenerate) -// { -// if (!removeAllNonConformingLoops(arr,he,inwards,holesEdges,pgn1,pgn2)) -// { -// std::cout << "not removed"; -// int bla = holesEdges.size(); -// std::cout << "in holes: " << bla << "\n"; -// after_removal_hole_edges.push_back(he); -// } -// } -// else -// { -// std::cout << "degen not removed"; -// int bla = holesEdges.size(); -// std::cout << "in holes: " << bla << "\n"; -// } -// -// } -// -// std::cout << arr.number_of_faces() << " faces:" << std::endl; -///* global_graphics->clear(); -// -// draw_arr(arr); -// global_graphics->display(); -// */ -// -// for (std::list::iterator itr = after_removal_hole_edges.begin();itr != after_removal_hole_edges.end() ; ++itr) -// { -// nestedLoopsFilterRec(arr,*itr, !inwards,pgn1,pgn2); -// } -// -// /*container_face = inside_face_edge->face(); -// // now all the holes are in correct orientation, recursivaly call this func: -// for (hi =container_face->holes_begin();hi!= container_face->holes_end(); ++hi ) -// { -// outside_face_itr = *hi; -// nestedLoopsFilterRec(arr,outside_face_itr, !inwards,pgn1,pgn2); -// // Halfedge_handle h_e= outside_face_itr.twin(); -// // holesEdges.push_back(h_e); -// }*/ -// } - - // find all faces who has handle's face sorrounding them, but are not holes. - void findSemiHoles(Arrangement_history_2& arr,Halfedge_handle& handle,std::list& semi_holes) const - { - Faces_set faces_in_face; - Face_handle outside_face = handle->face(); - Ccb_halfedge_circulator circ = handle->twin()->ccb(); - Ccb_halfedge_circulator curr = circ; - do{ - // check if the twin edge is the regular outside face or a different one. if so we are in half island. - Face_handle curr_sec_face = curr->twin()->face(); - if (curr_sec_face != outside_face) - { - typename Faces_set::iterator itr = faces_in_face.find(curr_sec_face); - - if (itr == faces_in_face.end()) - { - faces_in_face.insert(curr_sec_face); - } - } - }while(++curr!=circ); - for (typename Faces_set::iterator itr = faces_in_face.begin();itr!= faces_in_face.end();++itr) - { - Face_handle h = *itr; - semi_holes.push_back((h->outer_ccb()->twin())); - } - /*Halfedge_handle inside_face_edge = handle->twin(); - Face_handle outside_face = handle->face(); - - Face_handle inside_face = inside_face_edge->face(); - Faces_set visited_faces;*/ - - } - - bool removeAllNonConformingLoops(Arrangement_history_2& arr,Halfedge_handle& handle,bool inwards,std::list& holesEdges,const Polygon_2& pgn1,const Polygon_2& pgn2) const - { - // check if loop is in the right direction ((a || b) && !(a && b)) - bool a =!checkTripSameDirWithSegment(arr, handle); - bool b = inwards; - // nor a,b - bool conforming_loop = !((a || b) && !(a && b)); - - if (!conforming_loop) - { - //std::cout << "start remove\n"; - - /* Halfedge_handle inside_face_edge = handle->twin(); - Face_handle container_face = inside_face_edge->face(); - Hole_iterator hi; - Ccb_halfedge_circulator outside_face_itr; - // push initial list of holes to list. - for (hi =container_face->holes_begin();hi!= container_face->holes_end(); ++hi ) - { - outside_face_itr = *hi; - Halfedge_handle h_e= outside_face_itr->twin(); - holesEdges.push_back(h_e); - } - */ - removeFaceLoop(arr,handle->twin()); - //std::cout << "end remove\n"; - return true; - } - - // Check collision detection criterion - bool coll_detect = checkCollisionDetection(arr,handle,pgn1,pgn2); - if (coll_detect) - { - removeFaceLoop(arr,handle->twin()); - //std::cout << "end remove\n"; - return true; - } - return false; - - } - - Polygon_2 revPoly(const Polygon_2& input) const - { - Polygon_2 out; - typename Polygon_2::Vertex_iterator itr = input.vertices_begin(); - for (;itr!= input.vertices_end();++itr) - { - out.push_back(Point_2(-itr->x(),-itr->y())); - } - if (out.orientation()==CGAL::CLOCKWISE) - out.reverse_orientation(); - -/* - QColor c1(0,255,0); - QColor c2(0,0,255); - */ - - - return out; - - } - - /*void buildCollisionDetector(const Polygon_2& pgn1,const Polygon_2& pgn2) - { - q = revPoly(pgn2); - - }*/ - - /*ICollisionDetector* getColDetect() const - { - return (ICollisionDetector*)&collision_detector; - }*/ - - AABBCollisionDetector* getColDetect() const - { - return _aabb_collision_detector; - } - - /* - This version assumes poly1 is reflected through origin. (as called from nested loops filter) - */ - bool checkCollisionDetection(Arrangement_history_2& arr,Halfedge_handle& handle,const Polygon_2& pgn1,const Polygon_2& pgn2) const - { - //ICollisionDetector& collision_detector = SweepCollisionDetector(); - //ICollisionDetector* collision_detector = getColDetect(); - AABBCollisionDetector* collision_detector = getColDetect(); - //ICollisionDetector& collision_detector = NaiveCollisionDetector(); - //handle = handle->twin(); - - /*Point_2 p = handle->source()->point(); - Point_2 p2 = handle->target()->point(); - Point_2 mid_point = CGAL::midpoint(p,p2);*/ - Point_2 mid_point = findInsidePoint(arr,handle); - //Polygon_2 r_pgn1 = CGAL::transform(Kernel::Aff_transformation_2(CGAL::Rotation(),0,-1), pgn1); - Polygon_2 t_pgn1 = transform(typename Kernel::Aff_transformation_2(CGAL::Translation(), Vector_2(CGAL::ORIGIN,mid_point)), pgn1); - collision_detector->setTranslationPoint(mid_point); - //QColor c1(0,255,0); - //QColor c2(0,0,255); - - //global_graphics->draw_polygon(t_pgn1,c1); - //global_graphics->draw_polygon(pgn2,c2); - //global_graphics->display(); - //global_graphics->clear(); - return collision_detector->checkCollision(t_pgn1,pgn2); - } - - Point_2 findInsidePoint(Arrangement_history_2& arr,Halfedge_handle& handle) const - { - - Ccb_halfedge_circulator currHandle = handle->ccb(); - Ccb_halfedge_circulator nextHandle = currHandle; - ++nextHandle; - //while ((currHandle->curve().is_vertical()) || currHandle->direction() != nextHandle->direction()) - while (currHandle->direction() != nextHandle->direction()) - { -// printHe(currHandle); -// printHe(nextHandle); - ++currHandle; - ++nextHandle; - if (checkReflex(currHandle->source()->point(),currHandle->target()->point(),nextHandle->target()->point())) - break; - } - - Point_2 p = currHandle->source()->point(); - Point_2 p2 = currHandle->target()->point(); - Point_2 work_point = p2; - - Ccb_halfedge_circulator best_edge= handle; - bool has_some_point = false; - Ccb_halfedge_circulator circ = nextHandle; - Ccb_halfedge_circulator end = handle; - - bool shoot_upwards = (currHandle->direction() == ARR_LEFT_TO_RIGHT); - if (nextHandle->curve().is_vertical()) - work_point = CGAL::midpoint(p,p2); - if (currHandle->curve().is_vertical()) - { - p = nextHandle->source()->point(); - p2 = nextHandle->target()->point(); - work_point = CGAL::midpoint(p,p2); - ++best_edge; - ++circ; - ++end; - } - //Point_2 mid_point = CGAL::midpoint(p,p2); - - ++circ; - while (circ!=end) - { - Base_Segment_2 circ_curve = circ->curve(); - - if (f_compare_x(work_point,circ_curve.min()) != f_compare_x(work_point,circ_curve.max())) - { // we have an edge with same x range as endpoint of - bool above_first = (f_compare_y_at_x(work_point,circ_curve) == SMALLER); - if (has_some_point) - { - bool under_best; - Base_Segment_2 best_edge_curve = best_edge->curve(); - if (f_compare_x(best_edge_curve.min(),circ_curve.min()) != f_compare_x(best_edge_curve.max(),circ_curve.min())) - { - under_best = f_compare_y_at_x(circ_curve.min(),best_edge_curve) == SMALLER; - - } - else - { - under_best = f_compare_y_at_x(best_edge_curve.min(),circ_curve) != SMALLER; - } - if ( (shoot_upwards && above_first && under_best) ||(!shoot_upwards && !above_first && !under_best)) - best_edge = circ; - } - else - { - has_some_point = true; - best_edge = circ; - } - } - ++circ; - } - - if (best_edge->curve().is_vertical()) - { - Base_Segment_2 best_edge_curve = best_edge->curve(); - typename Kernel::FT x0 = f_compute_x(work_point); - typename Kernel::FT y_point = f_compute_y(work_point); - - if (shoot_upwards){ - typename Kernel::FT y_best = f_compute_y(best_edge_curve.min()); - typename Kernel::FT y = (y_best-y_point)/2 + y_point; - return Point_2(x0,y); - } - else - { - typename Kernel::FT y_best = f_compute_y(best_edge_curve.min()); - typename Kernel::FT y = (y_point - y_best)/2 + y_best; - return Point_2(x0,y); - } - return work_point; - } - Base_Segment_2 best_edge_curve = best_edge->curve(); - typename Kernel::FT x0 = f_compute_x(work_point); - typename Kernel::FT x1 = f_compute_x(best_edge_curve.min()); - typename Kernel::FT x2 = f_compute_x(best_edge_curve.max()); - typename Kernel::FT alpha = (x0-x2)/(x1-x2); - - typename Kernel::FT y_best = alpha*f_compute_y(best_edge_curve.min())+ (1-alpha)*f_compute_y(best_edge_curve.max()); - typename Kernel::FT y_point = f_compute_y(work_point); - typename Kernel::FT y = (y_best-y_point)/2 + y_point; - - - return Point_2(x0,y); - //return work_point; - } - - /* - This version reflects poly 1. - */ - bool checkCollisionDetection(Arrangement_history_2& arr,Point_2& point,const Polygon_2& pgn1,const Polygon_2& pgn2) const - { - //ICollisionDetector& collision_detector = NaiveCollisionDetector(); - //ICollisionDetector* collision_detector = getColDetect(); - AABBCollisionDetector* collision_detector = getColDetect(); - //handle = handle->twin(); - Point_2 p = point; - //Polygon_2 r_pgn1 = CGAL::transform(Kernel::Aff_transformation_2(CGAL::Rotation(),0,-1), pgn1); - Polygon_2 r_pgn1 = revPoly(pgn1); - Polygon_2 t_pgn1 = transform(typename Kernel::Aff_transformation_2(CGAL::Translation(), Vector_2(CGAL::ORIGIN,p)), r_pgn1); - collision_detector->setTranslationPoint(p); - /* QColor c1(0,255,0); - QColor c2(0,0,255); - - global_graphics->draw_polygon(t_pgn1,c1); - global_graphics->draw_polygon(pgn2,c2); - global_graphics->display(); - global_graphics->clear(); */ - return collision_detector->checkCollision(t_pgn1,pgn2); - } - - bool checkSegmentCollisionDetection(Arrangement_history_2& arr,Segment_2& seg,const Polygon_2& pgn1,const Polygon_2& pgn2) const - { - Point_2 mid_point= CGAL::midpoint(seg.source(),seg.target()); - return checkCollisionDetection(arr,mid_point,pgn1,pgn2); - } - - void removeFaceLoop(Arrangement_history_2& arr,Halfedge_handle& handle) const - { - std::list remove_list; - Ccb_halfedge_circulator circ = handle->ccb(); - remove_list.push_front(handle); - ++circ; - //Halfedge_iterator startEdge = circ.begin(); - while ( circ != handle) - { - remove_list.push_front(circ); - ++circ; - } - - for (typename std::list::iterator itr = remove_list.begin();itr != remove_list.end();++itr) - { - arr.remove_edge(*itr); - } - } - void buildArrangementFromConv(const Segments_list& reduced_conv,Arrangement_history_2& arr) const - { - CGAL_precondition (arr.is_empty()); - CGAL::insert (arr, reduced_conv.begin(),reduced_conv.end()); - } - - void constructOrientableLoops(Arrangement_history_2& arr) const - { - - /* - if (SHOW_STAGES) - { - draw_arr(arr); - global_graphics->display(); - } - */ - - if (WRITE_ARR) - { - std::ofstream file("arr.txt"); - file << arr; - } - const Minkowski_sum_by_convolution_lien_2* ptr = this; - ConvSegMapper mapper( &arr,const_cast (ptr)); - TraversalManager manager(&mapper); - manager.traverseLoops(); - - /* OLD Version 10/7/11 - Edge_iterator itr; - Edges_set edges_set; - for (itr = arr.edges_begin();itr!=arr.edges_end();++itr){ - setEdgeVisited(*itr,false,-1); - edges_set.insert(itr); - - } - - - // trace orientable loops: - - while (edges_set.size() != 0) - { - traceOrientableLoops( arr,edges_set); - } - */ - /*std::cout << "arr" << std::endl; - for (itr = arr.edges_begin();itr!=arr.edges_end();++itr){ - - printHe(itr); - }*/ - //typename iterator_traits::value_type seg; - - } - - - bool checkDegenerateEdgeOppositeSegments(Arrangement_history_2& arr,Halfedge_handle he) const - { - Originating_curve_iterator segment_itr;// = arr.originating_curves_begin ( *he); - //bool found = false; - //segment = NULL; - - std::list segments_dir_list; - - for (segment_itr = arr.originating_curves_begin(he);segment_itr != arr.originating_curves_end(he);++segment_itr) - { - Segment_2 segment = *segment_itr; - /*std::cout << "checktrip: " << std::endl; - printSegment(segment); - printHe(he);*/ - Direction_2 seg_dir = f_direction(f_vector(segment.source(),segment.target())); - segments_dir_list.push_back(seg_dir); - //Direction_2 start_he_dir = f_direction((f_vector(he->source()->point(),he->target()->point()))); - - - } - - //Direction_2 start_dir = segments_dir_list.begin(); - segments_dir_list.sort(); - typename std::list::iterator end = unique(segments_dir_list.begin(),segments_dir_list.end()); - int i =distance(segments_dir_list.begin(),end); - return i>1; - - } - - bool checkDegenarateVertexIsIntersectionOfThreeSegments(Arrangement_history_2& arr,Vertex_handle vh) - { - Halfedge_around_vertex_circulator itr = vh->incident_halfedges(); - Halfedge_around_vertex_circulator start = itr; - int count_degree =0; - do{ - ++count_degree; - } - while(++itr!=start); - - if (count_degree <=2) - return false; - - Originating_curve_iterator segment_itr; - std::list orig_segments_list; - std::list segments_dir_list; - //std::list<> originating_curves_list; - - // Handle the standard case where we have two intersecting convolution segments. - if (count_degree == 4){ - do{ - for (segment_itr = arr.originating_curves_begin(itr);segment_itr != arr.originating_curves_end(itr);++segment_itr){ - Segment_2 segment = *segment_itr; - orig_segments_list.push_back(&(*segment_itr)); - } - } while(++itr!=start); - orig_segments_list.sort(); - typename std::list::iterator end = unique(orig_segments_list.begin(),orig_segments_list.end()); - int i =distance(orig_segments_list.begin(),end); - if (i==2) // this is two curves crossing case. - return false; - } - - - /* DEBUG - if ( != 4) - { - std::cout << "Degree not 4 : " << count_degree << std::endl; - } -*/ - - do{ - - for (segment_itr = arr.originating_curves_begin(itr);segment_itr != arr.originating_curves_end(itr);++segment_itr) - { - Segment_2 segment = *segment_itr; - //printSegment(*segment_itr); - //orig_segments_list.push_back(&(*segment_itr)); - Direction_2 seg_dir = f_direction(f_vector(segment.source(),segment.target())); - segments_dir_list.push_back(seg_dir); - - } - - } - while(++itr!=start); - - - - segments_dir_list.sort(); - typename std::list::iterator end = unique(segments_dir_list.begin(),segments_dir_list.end()); - int i =distance(segments_dir_list.begin(),end); - return i>2; - //orig_segments_list.sort(); - - - /*std::list::iterator end = unique(orig_segments_list.begin(),orig_segments_list.end()); - int i =distance(orig_segments_list.begin(),end); - - return (distance(orig_segments_list.begin(),end) > 2);*/ - } - - // Gets the he that agrees in direction with the convolution segment. - Halfedge_handle getDirAgreeingHalfedge(Arrangement_history_2& arr,const Halfedge_handle& he) const - { - Halfedge_handle curr_halfedge = he; - if (!checkTripSameDirWithSegment(arr,he)) - curr_halfedge = curr_halfedge->twin(); - return curr_halfedge; - } - - // Gets list of incoming and outgoing edges(as defined by directions of segments in the convolution) from the vertex. - void getEdgesFromVertex(Arrangement_history_2& arr,Vertex_handle v_src,std::list& inList,std::list& outList) const - { - outList.clear(); - inList.clear(); - Halfedge_around_vertex_circulator itr = v_src->incident_halfedges(); - Halfedge_around_vertex_circulator start = itr; - do{ - Halfedge_handle curr_edge = getDirAgreeingHalfedge(arr,itr); - if ((curr_edge->source()) == v_src) - { - outList.push_back(curr_edge); - }else - { - inList.push_back(curr_edge); - } - - } - while(++itr!=start); - } - - // Returns the direction of a half edge - Direction_2 getHalfedgeDir(const Halfedge_handle& he) const - { - Direction_2 dir = f_direction((f_vector(he->source()->point(),he->target()->point()))); - return dir; - } - - double getSignedAngle(const Halfedge_handle& h_enter,const Halfedge_handle& h_exit) const - { - Direction_2 dir_enter = getHalfedgeDir(h_enter); - Direction_2 dir_exit = getHalfedgeDir(h_exit); - Vector_2 vec_enter = dir_enter.vector(); - Vector_2 vec_exit = dir_exit.vector(); - Point_2 org(CGAL::ORIGIN); - Vector_2 origin_vec(org,org); - Orientation sign_or = f_orientation(vec_enter,vec_exit); - float sign = 0.f; - if (sign_or == CGAL::LEFT_TURN) - sign = 1; - else - if (sign_or == CGAL::RIGHT_TURN) - sign = -1; - else - sign = 0; - - double prod = CGAL::to_double(vec_enter*vec_exit); - - /*if ((CGAL::is_zero(vec_enter.squared_length()) == CGAL::Tag_true) || (CGAL::is_zero(vec_exit.squared_length()) == CGAL::Tag_true)) - return 0;*/ - if (f_equal(vec_enter,origin_vec) || f_equal(vec_exit,origin_vec)) - return 0; - - double len1 = sqrt(CGAL::to_double(vec_enter.squared_length())); - double len2 = sqrt(CGAL::to_double(vec_exit.squared_length())); - //if (abs(len1 -eps()) == 0 || len2 == 0) - double p = prod/(len1*len2); - p = min((double)(1),p); - p = max((double)(-1),p); - double ang = acos(p); - return sign*ang; - } + // now for each hole in main face we will determine it's orientation. + nestedLoopsFilterRec(arr, perimiterFace, false, pgn1, pgn2); + } /* - void traceOrientableLoopNew(Arrangement_history_2& arr,Halfedge_handle& start_halfedge,bool is_outer_loop,int loop_counter,Edges_set& edges_set) const - { - std::list temp_segments; - Halfedge_handle trace_start = getDirAgreeingHalfedge(arr,start_edge); - Halfedge_handle curr_halfedge = trace_start; - double sum_angles = 0; - bool done = false; - bool improving = false; - while (!done){ - bool has_loop_closed = false; + For each loop we represent it by the halfedge which is the twin of the face loop. + ie this edge is part of the clockwise oriented halfedges loop outside the face. + */ + void nestedLoopsFilterRec(Arrangement_history_2 &arr, Halfedge_handle &handle, bool inwards, const Polygon_2 &pgn1, const Polygon_2 &pgn2) const { + std::list holesEdges; + std::list after_removal_hole_edges; + std::list faces_list; - Halfedge_handle next_halfedge = traverseNextHalfedge(Arrangement_history_2& arr,curr_halfedge,has_next_edge,loop_counter,has_loop_closed,loop_start_handle,loop_end_handle); - - if (has_loop_closed) - { - double temp_sum = sum + getSignedAngle(curr_edge,loop_closed_handle); - // check if loop is in correct orientation. - if ((temp_sum > 0 && is_outer_loop) || (temp_sum < 0 && !is_outer_loop)) - { - - improving = true; - sum =0; - // loop was closed and nowhere to continue - if (!has_next_edge) - { - // a loop closes with part of the edges. we have to remove edges till next_halfedge from arrangment, - // and clear the list. - removeHalfEdgesArrPart(arr,edges_set,temp_segments,loop_start_handle); - //removeHalfEdgesArrPart(arr,edges_set,temp_segments,curr_halfedge); - nextLoop(temp_segments, arr,edges_set, curr_halfedge,start_halfedge,done,loop_counter); + Face_iterator startFace = arr.unbounded_face(); + Halfedge_handle inside_face_edge = handle->twin(); + Face_handle container_face = inside_face_edge->face(); - } - } - } - else - { + Face_iterator face_itr = arr.faces_begin(); - } - } - } + for (; face_itr != arr.faces_end(); ++face_itr) { + if (!(face_itr->is_unbounded()) && face_itr != container_face) { + Halfedge_handle h_e = face_itr->outer_ccb()->twin(); + holesEdges.push_back(h_e); + } + } + + while (holesEdges.size() > 0) { // remove loops from faces + /*int bla = holesEdges.size(); + std::cout << "in holes: " << bla << "\n";*/ + Halfedge_handle he = holesEdges.front(); + // printHe(he); + holesEdges.pop_front(); + + if (!he->isDegenerate) { + if (!removeAllNonConformingLoops(arr, he, inwards, holesEdges, pgn1, pgn2)) { + + + /*for (hi = startFace->holes_begin(); hi != startFace->holes_end(); ++hi) { + perimiterFace = *hi; + }*/ + /*std::cout << "not removed"; + int bla = holesEdges.size(); + std::cout << "in holes: " << bla << "\n";*/ + after_removal_hole_edges.push_back(he); + } + } + + /*else + { + std::cout << "degen not removed"; + int bla = holesEdges.size(); + std::cout << "in holes: " << bla << "\n"; + }*/ + + } + + Hole_iterator hi; + //Ccb_halfedge_circulator perimiterFace; + hi = startFace->holes_begin(); + container_face = (*hi)->twin()->face(); + /* global_graphics->clear(); + + draw_arr(arr); + global_graphics->display();*/ +// Hole_iterator hi; + Ccb_halfedge_circulator outside_face_itr; + + // push initial list of holes to list. + for (hi = container_face->holes_begin(); hi != container_face->holes_end(); ++hi) { // remove degenrate cases which are false + outside_face_itr = *hi; + Halfedge_handle h_e = outside_face_itr; //->twin(); + holesEdges.push_back(h_e); + } + + while (holesEdges.size() > 0) { + /* int bla = holesEdges.size(); + std::cout << "in holes: " << bla << "\n";*/ + Halfedge_handle he = holesEdges.front(); + // printHe(he); + holesEdges.pop_front(); + + if (!he->isDegenerate) { + if (!removeAllNonConformingLoops(arr, he, inwards, holesEdges, pgn1, pgn2)) { + Hole_iterator hi; + //Ccb_halfedge_circulator perimiterFace; + /* hi = startFace->holes_begin(); + container_face = (*hi)->twin()->face();*/ + /* std::cout << "not removed"; + int bla = holesEdges.size(); + std::cout << "in holes: " << bla << "\n";*/ + after_removal_hole_edges.push_back(he); + } + } + + /*else + { + std::cout << "degen not removed"; + int bla = holesEdges.size(); + std::cout << "in holes: " << bla << "\n"; + }*/ + + } + + // std::list semi_holes; + //findSemiHoles(arr,handle,semi_holes); + // holesEdges.insert(holesEdges.begin(),semi_holes.begin(),semi_holes.end()); + + // while we still have holes , leave only loops orientable with current direction. + + /* std::cout << "number of hole edges " << holesEdges.size() << "\n"; + std::cout << arr.number_of_faces() << " faces:" << std::endl; + + + std::cout << arr.number_of_faces() << " faces:" << std::endl;*/ + /* global_graphics->clear(); + + draw_arr(arr); + global_graphics->display(); + */ + + /* for (std::list::iterator itr = after_removal_hole_edges.begin();itr != after_removal_hole_edges.end() ; ++itr) + { + nestedLoopsFilterRec(arr,*itr, !inwards,pgn1,pgn2); + } + */ + /*container_face = inside_face_edge->face(); + // now all the holes are in correct orientation, recursivaly call this func: + for (hi =container_face->holes_begin();hi!= container_face->holes_end(); ++hi ) + { + outside_face_itr = *hi; + nestedLoopsFilterRec(arr,outside_face_itr, !inwards,pgn1,pgn2); + // Halfedge_handle h_e= outside_face_itr.twin(); + // holesEdges.push_back(h_e); + }*/ + } + + + +// /* +// For each loop we represent it by the halfedge which is the twin of the face loop. +// ie this edge is part of the clockwise oriented halfedges loop outside the face. +// */ +// void nestedLoopsFilterRec(Arrangement_history_2& arr,Halfedge_handle& handle,bool inwards,const Polygon_2& pgn1,const Polygon_2& pgn2) const +// { +// std::list holesEdges; +// std::list after_removal_hole_edges; +// // std::list faces_list; +// +// +// Halfedge_handle inside_face_edge = handle->twin(); +// Face_handle container_face = inside_face_edge->face(); +// +// +// +// Hole_iterator hi; +// Ccb_halfedge_circulator outside_face_itr; +// // push initial list of holes to list. +// for (hi =container_face->holes_begin();hi!= container_face->holes_end(); ++hi ) +// { +// outside_face_itr = *hi; +// Halfedge_handle h_e= outside_face_itr;//->twin(); +// holesEdges.push_back(h_e); +// } +// +// // std::list semi_holes; +// //findSemiHoles(arr,handle,semi_holes); +// // holesEdges.insert(holesEdges.begin(),semi_holes.begin(),semi_holes.end()); +// +// // while we still have holes , leave only loops orientable with current direction. +// +// std::cout << "number of hole edges " << holesEdges.size() << "\n"; +// std::cout << arr.number_of_faces() << " faces:" << std::endl; +// while(holesEdges.size() > 0) +// { +// /* int bla = holesEdges.size(); +// std::cout << "in holes: " << bla << "\n";*/ +// Halfedge_handle he = holesEdges.front(); +// // printHe(he); +// holesEdges.pop_front(); +// +// if (!he->isDegenerate) +// { +// if (!removeAllNonConformingLoops(arr,he,inwards,holesEdges,pgn1,pgn2)) +// { +// std::cout << "not removed"; +// int bla = holesEdges.size(); +// std::cout << "in holes: " << bla << "\n"; +// after_removal_hole_edges.push_back(he); +// } +// } +// else +// { +// std::cout << "degen not removed"; +// int bla = holesEdges.size(); +// std::cout << "in holes: " << bla << "\n"; +// } +// +// } +// +// std::cout << arr.number_of_faces() << " faces:" << std::endl; +///* global_graphics->clear(); +// +// draw_arr(arr); +// global_graphics->display(); +// */ +// +// for (std::list::iterator itr = after_removal_hole_edges.begin();itr != after_removal_hole_edges.end() ; ++itr) +// { +// nestedLoopsFilterRec(arr,*itr, !inwards,pgn1,pgn2); +// } +// +// /*container_face = inside_face_edge->face(); +// // now all the holes are in correct orientation, recursivaly call this func: +// for (hi =container_face->holes_begin();hi!= container_face->holes_end(); ++hi ) +// { +// outside_face_itr = *hi; +// nestedLoopsFilterRec(arr,outside_face_itr, !inwards,pgn1,pgn2); +// // Halfedge_handle h_e= outside_face_itr.twin(); +// // holesEdges.push_back(h_e); +// }*/ +// } + + // find all faces who has handle's face sorrounding them, but are not holes. + void findSemiHoles(Arrangement_history_2 &arr, Halfedge_handle &handle, std::list &semi_holes) const { + Faces_set faces_in_face; + Face_handle outside_face = handle->face(); + Ccb_halfedge_circulator circ = handle->twin()->ccb(); + Ccb_halfedge_circulator curr = circ; + + do { + // check if the twin edge is the regular outside face or a different one. if so we are in half island. + Face_handle curr_sec_face = curr->twin()->face(); + + if (curr_sec_face != outside_face) { + typename Faces_set::iterator itr = faces_in_face.find(curr_sec_face); + + if (itr == faces_in_face.end()) { + faces_in_face.insert(curr_sec_face); + } + } + } while (++curr != circ); + + for (typename Faces_set::iterator itr = faces_in_face.begin(); itr != faces_in_face.end(); ++itr) { + Face_handle h = *itr; + semi_holes.push_back((h->outer_ccb()->twin())); + } + + /*Halfedge_handle inside_face_edge = handle->twin(); + Face_handle outside_face = handle->face(); + + Face_handle inside_face = inside_face_edge->face(); + Faces_set visited_faces;*/ + + } + + bool removeAllNonConformingLoops(Arrangement_history_2 &arr, Halfedge_handle &handle, bool inwards, std::list &holesEdges, const Polygon_2 &pgn1, const Polygon_2 &pgn2) const { + // check if loop is in the right direction ((a || b) && !(a && b)) + bool a = !checkTripSameDirWithSegment(arr, handle); + bool b = inwards; + // nor a,b + bool conforming_loop = !((a || b) && !(a && b)); + + if (!conforming_loop) { + //std::cout << "start remove\n"; + + /* Halfedge_handle inside_face_edge = handle->twin(); + Face_handle container_face = inside_face_edge->face(); + Hole_iterator hi; + Ccb_halfedge_circulator outside_face_itr; + // push initial list of holes to list. + for (hi =container_face->holes_begin();hi!= container_face->holes_end(); ++hi ) + { + outside_face_itr = *hi; + Halfedge_handle h_e= outside_face_itr->twin(); + holesEdges.push_back(h_e); + } + */ + removeFaceLoop(arr, handle->twin()); + //std::cout << "end remove\n"; + return true; + } + + // Check collision detection criterion + bool coll_detect = checkCollisionDetection(arr, handle, pgn1, pgn2); + + if (coll_detect) { + removeFaceLoop(arr, handle->twin()); + //std::cout << "end remove\n"; + return true; + } + + return false; + + } + + Polygon_2 revPoly(const Polygon_2 &input) const { + Polygon_2 out; + typename Polygon_2::Vertex_iterator itr = input.vertices_begin(); + + for (; itr != input.vertices_end(); ++itr) { + out.push_back(Point_2(-itr->x(), -itr->y())); + } + + if (out.orientation() == CGAL::CLOCKWISE) { + out.reverse_orientation(); + } + + /* + QColor c1(0,255,0); + QColor c2(0,0,255); + */ + + + return out; + + } + + /*void buildCollisionDetector(const Polygon_2& pgn1,const Polygon_2& pgn2) + { + q = revPoly(pgn2); + + }*/ + + /*ICollisionDetector* getColDetect() const + { + return (ICollisionDetector*)&collision_detector; + }*/ + + AABBCollisionDetector *getColDetect() const { + return _aabb_collision_detector; + } + + /* + This version assumes poly1 is reflected through origin. (as called from nested loops filter) + */ + bool checkCollisionDetection(Arrangement_history_2 &arr, Halfedge_handle &handle, const Polygon_2 &pgn1, const Polygon_2 &pgn2) const { + //ICollisionDetector& collision_detector = SweepCollisionDetector(); + //ICollisionDetector* collision_detector = getColDetect(); + AABBCollisionDetector *collision_detector = getColDetect(); + //ICollisionDetector& collision_detector = NaiveCollisionDetector(); + //handle = handle->twin(); + + /*Point_2 p = handle->source()->point(); + Point_2 p2 = handle->target()->point(); + Point_2 mid_point = CGAL::midpoint(p,p2);*/ + Point_2 mid_point = findInsidePoint(arr, handle); + //Polygon_2 r_pgn1 = CGAL::transform(Kernel::Aff_transformation_2(CGAL::Rotation(),0,-1), pgn1); + Polygon_2 t_pgn1 = transform(typename Kernel::Aff_transformation_2(CGAL::Translation(), Vector_2(CGAL::ORIGIN, mid_point)), pgn1); + collision_detector->setTranslationPoint(mid_point); + //QColor c1(0,255,0); + //QColor c2(0,0,255); + + //global_graphics->draw_polygon(t_pgn1,c1); + //global_graphics->draw_polygon(pgn2,c2); + //global_graphics->display(); + //global_graphics->clear(); + return collision_detector->checkCollision(t_pgn1, pgn2); + } + + Point_2 findInsidePoint(Arrangement_history_2 &arr, Halfedge_handle &handle) const { + + Ccb_halfedge_circulator currHandle = handle->ccb(); + Ccb_halfedge_circulator nextHandle = currHandle; + ++nextHandle; + + //while ((currHandle->curve().is_vertical()) || currHandle->direction() != nextHandle->direction()) + while (currHandle->direction() != nextHandle->direction()) { +// printHe(currHandle); +// printHe(nextHandle); + ++currHandle; + ++nextHandle; + + if (checkReflex(currHandle->source()->point(), currHandle->target()->point(), nextHandle->target()->point())) { + break; + } + } + + Point_2 p = currHandle->source()->point(); + Point_2 p2 = currHandle->target()->point(); + Point_2 work_point = p2; + + Ccb_halfedge_circulator best_edge = handle; + bool has_some_point = false; + Ccb_halfedge_circulator circ = nextHandle; + Ccb_halfedge_circulator end = handle; + + bool shoot_upwards = (currHandle->direction() == ARR_LEFT_TO_RIGHT); + + if (nextHandle->curve().is_vertical()) { + work_point = CGAL::midpoint(p, p2); + } + + if (currHandle->curve().is_vertical()) { + p = nextHandle->source()->point(); + p2 = nextHandle->target()->point(); + work_point = CGAL::midpoint(p, p2); + ++best_edge; + ++circ; + ++end; + } + + //Point_2 mid_point = CGAL::midpoint(p,p2); + + ++circ; + + while (circ != end) { + Base_Segment_2 circ_curve = circ->curve(); + + if (f_compare_x(work_point, circ_curve.min()) != f_compare_x(work_point, circ_curve.max())) { + // we have an edge with same x range as endpoint of + bool above_first = (f_compare_y_at_x(work_point, circ_curve) == SMALLER); + + if (has_some_point) { + bool under_best; + Base_Segment_2 best_edge_curve = best_edge->curve(); + + if (f_compare_x(best_edge_curve.min(), circ_curve.min()) != f_compare_x(best_edge_curve.max(), circ_curve.min())) { + under_best = f_compare_y_at_x(circ_curve.min(), best_edge_curve) == SMALLER; + + } else { + under_best = f_compare_y_at_x(best_edge_curve.min(), circ_curve) != SMALLER; + } + + if ((shoot_upwards && above_first && under_best) || (!shoot_upwards && !above_first && !under_best)) { + best_edge = circ; + } + } else { + has_some_point = true; + best_edge = circ; + } + } + + ++circ; + } + + if (best_edge->curve().is_vertical()) { + Base_Segment_2 best_edge_curve = best_edge->curve(); + typename Kernel::FT x0 = f_compute_x(work_point); + typename Kernel::FT y_point = f_compute_y(work_point); + + if (shoot_upwards) { + typename Kernel::FT y_best = f_compute_y(best_edge_curve.min()); + typename Kernel::FT y = (y_best - y_point) / 2 + y_point; + return Point_2(x0, y); + } else { + typename Kernel::FT y_best = f_compute_y(best_edge_curve.min()); + typename Kernel::FT y = (y_point - y_best) / 2 + y_best; + return Point_2(x0, y); + } + + return work_point; + } + + Base_Segment_2 best_edge_curve = best_edge->curve(); + typename Kernel::FT x0 = f_compute_x(work_point); + typename Kernel::FT x1 = f_compute_x(best_edge_curve.min()); + typename Kernel::FT x2 = f_compute_x(best_edge_curve.max()); + typename Kernel::FT alpha = (x0 - x2) / (x1 - x2); + + typename Kernel::FT y_best = alpha * f_compute_y(best_edge_curve.min()) + (1 - alpha) * f_compute_y(best_edge_curve.max()); + typename Kernel::FT y_point = f_compute_y(work_point); + typename Kernel::FT y = (y_best - y_point) / 2 + y_point; + + + return Point_2(x0, y); + //return work_point; + } + + /* + This version reflects poly 1. + */ + bool checkCollisionDetection(Arrangement_history_2 &arr, Point_2 &point, const Polygon_2 &pgn1, const Polygon_2 &pgn2) const { + //ICollisionDetector& collision_detector = NaiveCollisionDetector(); + //ICollisionDetector* collision_detector = getColDetect(); + AABBCollisionDetector *collision_detector = getColDetect(); + //handle = handle->twin(); + Point_2 p = point; + //Polygon_2 r_pgn1 = CGAL::transform(Kernel::Aff_transformation_2(CGAL::Rotation(),0,-1), pgn1); + Polygon_2 r_pgn1 = revPoly(pgn1); + Polygon_2 t_pgn1 = transform(typename Kernel::Aff_transformation_2(CGAL::Translation(), Vector_2(CGAL::ORIGIN, p)), r_pgn1); + collision_detector->setTranslationPoint(p); + /* QColor c1(0,255,0); + QColor c2(0,0,255); + + global_graphics->draw_polygon(t_pgn1,c1); + global_graphics->draw_polygon(pgn2,c2); + global_graphics->display(); + global_graphics->clear(); */ + return collision_detector->checkCollision(t_pgn1, pgn2); + } + + bool checkSegmentCollisionDetection(Arrangement_history_2 &arr, Segment_2 &seg, const Polygon_2 &pgn1, const Polygon_2 &pgn2) const { + Point_2 mid_point = CGAL::midpoint(seg.source(), seg.target()); + return checkCollisionDetection(arr, mid_point, pgn1, pgn2); + } + + void removeFaceLoop(Arrangement_history_2 &arr, Halfedge_handle &handle) const { + std::list remove_list; + Ccb_halfedge_circulator circ = handle->ccb(); + remove_list.push_front(handle); + ++circ; + + //Halfedge_iterator startEdge = circ.begin(); + while (circ != handle) { + remove_list.push_front(circ); + ++circ; + } + + for (typename std::list::iterator itr = remove_list.begin(); itr != remove_list.end(); ++itr) { + arr.remove_edge(*itr); + } + } + void buildArrangementFromConv(const Segments_list &reduced_conv, Arrangement_history_2 &arr) const { + CGAL_precondition(arr.is_empty()); + CGAL::insert(arr, reduced_conv.begin(), reduced_conv.end()); + } + + void constructOrientableLoops(Arrangement_history_2 &arr) const { + + /* + if (SHOW_STAGES) + { + draw_arr(arr); + global_graphics->display(); + } + */ + + if (WRITE_ARR) { + std::ofstream file("arr.txt"); + file << arr; + } + + const Minkowski_sum_by_convolution_lien_2 *ptr = this; + ConvSegMapper mapper(&arr, const_cast (ptr)); + TraversalManager manager(&mapper); + manager.traverseLoops(); + + /* OLD Version 10/7/11 + Edge_iterator itr; + Edges_set edges_set; + for (itr = arr.edges_begin();itr!=arr.edges_end();++itr){ + setEdgeVisited(*itr,false,-1); + edges_set.insert(itr); + + } + + + // trace orientable loops: + + while (edges_set.size() != 0) + { + traceOrientableLoops( arr,edges_set); + } + */ + /*std::cout << "arr" << std::endl; + for (itr = arr.edges_begin();itr!=arr.edges_end();++itr){ + + printHe(itr); + }*/ + //typename iterator_traits::value_type seg; + + } + + + bool checkDegenerateEdgeOppositeSegments(Arrangement_history_2 &arr, Halfedge_handle he) const { + Originating_curve_iterator segment_itr;// = arr.originating_curves_begin ( *he); + //bool found = false; + //segment = NULL; + + std::list segments_dir_list; + + for (segment_itr = arr.originating_curves_begin(he); segment_itr != arr.originating_curves_end(he); ++segment_itr) { + Segment_2 segment = *segment_itr; + /*std::cout << "checktrip: " << std::endl; + printSegment(segment); + printHe(he);*/ + Direction_2 seg_dir = f_direction(f_vector(segment.source(), segment.target())); + segments_dir_list.push_back(seg_dir); + //Direction_2 start_he_dir = f_direction((f_vector(he->source()->point(),he->target()->point()))); + + + } + + //Direction_2 start_dir = segments_dir_list.begin(); + segments_dir_list.sort(); + typename std::list::iterator end = unique(segments_dir_list.begin(), segments_dir_list.end()); + int i = distance(segments_dir_list.begin(), end); + return i > 1; + + } + + bool checkDegenarateVertexIsIntersectionOfThreeSegments(Arrangement_history_2 &arr, Vertex_handle vh) { + Halfedge_around_vertex_circulator itr = vh->incident_halfedges(); + Halfedge_around_vertex_circulator start = itr; + int count_degree = 0; + + do { + ++count_degree; + } while (++itr != start); + + if (count_degree <= 2) { + return false; + } + + Originating_curve_iterator segment_itr; + std::list orig_segments_list; + std::list segments_dir_list; + //std::list<> originating_curves_list; + + // Handle the standard case where we have two intersecting convolution segments. + if (count_degree == 4) { + do { + for (segment_itr = arr.originating_curves_begin(itr); segment_itr != arr.originating_curves_end(itr); ++segment_itr) { + Segment_2 segment = *segment_itr; + orig_segments_list.push_back(&(*segment_itr)); + } + } while (++itr != start); + + orig_segments_list.sort(); + typename std::list::iterator end = unique(orig_segments_list.begin(), orig_segments_list.end()); + int i = distance(orig_segments_list.begin(), end); + + if (i == 2) { // this is two curves crossing case. + return false; + } + } + + + /* DEBUG + if ( != 4) + { + std::cout << "Degree not 4 : " << count_degree << std::endl; + } + */ + + do { + + for (segment_itr = arr.originating_curves_begin(itr); segment_itr != arr.originating_curves_end(itr); ++segment_itr) { + Segment_2 segment = *segment_itr; + //printSegment(*segment_itr); + //orig_segments_list.push_back(&(*segment_itr)); + Direction_2 seg_dir = f_direction(f_vector(segment.source(), segment.target())); + segments_dir_list.push_back(seg_dir); + + } + + } while (++itr != start); + + + + segments_dir_list.sort(); + typename std::list::iterator end = unique(segments_dir_list.begin(), segments_dir_list.end()); + int i = distance(segments_dir_list.begin(), end); + return i > 2; + //orig_segments_list.sort(); + + + /*std::list::iterator end = unique(orig_segments_list.begin(),orig_segments_list.end()); + int i =distance(orig_segments_list.begin(),end); + + return (distance(orig_segments_list.begin(),end) > 2);*/ + } + + // Gets the he that agrees in direction with the convolution segment. + Halfedge_handle getDirAgreeingHalfedge(Arrangement_history_2 &arr, const Halfedge_handle &he) const { + Halfedge_handle curr_halfedge = he; + + if (!checkTripSameDirWithSegment(arr, he)) { + curr_halfedge = curr_halfedge->twin(); + } + + return curr_halfedge; + } + + // Gets list of incoming and outgoing edges(as defined by directions of segments in the convolution) from the vertex. + void getEdgesFromVertex(Arrangement_history_2 &arr, Vertex_handle v_src, std::list &inList, std::list &outList) const { + outList.clear(); + inList.clear(); + Halfedge_around_vertex_circulator itr = v_src->incident_halfedges(); + Halfedge_around_vertex_circulator start = itr; + + do { + Halfedge_handle curr_edge = getDirAgreeingHalfedge(arr, itr); + + if ((curr_edge->source()) == v_src) { + outList.push_back(curr_edge); + } else { + inList.push_back(curr_edge); + } + + } while (++itr != start); + } + + // Returns the direction of a half edge + Direction_2 getHalfedgeDir(const Halfedge_handle &he) const { + Direction_2 dir = f_direction((f_vector(he->source()->point(), he->target()->point()))); + return dir; + } + + double getSignedAngle(const Halfedge_handle &h_enter, const Halfedge_handle &h_exit) const { + Direction_2 dir_enter = getHalfedgeDir(h_enter); + Direction_2 dir_exit = getHalfedgeDir(h_exit); + Vector_2 vec_enter = dir_enter.vector(); + Vector_2 vec_exit = dir_exit.vector(); + Point_2 org(CGAL::ORIGIN); + Vector_2 origin_vec(org, org); + Orientation sign_or = f_orientation(vec_enter, vec_exit); + float sign = 0.f; + + if (sign_or == CGAL::LEFT_TURN) { + sign = 1; + } else if (sign_or == CGAL::RIGHT_TURN) { + sign = -1; + } else { + sign = 0; + } + + double prod = CGAL::to_double(vec_enter * vec_exit); + + /*if ((CGAL::is_zero(vec_enter.squared_length()) == CGAL::Tag_true) || (CGAL::is_zero(vec_exit.squared_length()) == CGAL::Tag_true)) + return 0;*/ + if (f_equal(vec_enter, origin_vec) || f_equal(vec_exit, origin_vec)) { + return 0; + } + + double len1 = sqrt(CGAL::to_double(vec_enter.squared_length())); + double len2 = sqrt(CGAL::to_double(vec_exit.squared_length())); + //if (abs(len1 -eps()) == 0 || len2 == 0) + double p = prod / (len1 * len2); + p = min((double)(1), p); + p = max((double)(-1), p); + double ang = acos(p); + return sign * ang; + } + + /* + void traceOrientableLoopNew(Arrangement_history_2& arr,Halfedge_handle& start_halfedge,bool is_outer_loop,int loop_counter,Edges_set& edges_set) const + { + std::list temp_segments; + Halfedge_handle trace_start = getDirAgreeingHalfedge(arr,start_edge); + Halfedge_handle curr_halfedge = trace_start; + double sum_angles = 0; + bool done = false; + bool improving = false; + while (!done){ + bool has_loop_closed = false; + + Halfedge_handle next_halfedge = traverseNextHalfedge(Arrangement_history_2& arr,curr_halfedge,has_next_edge,loop_counter,has_loop_closed,loop_start_handle,loop_end_handle); + + if (has_loop_closed) + { + double temp_sum = sum + getSignedAngle(curr_edge,loop_closed_handle); + // check if loop is in correct orientation. + if ((temp_sum > 0 && is_outer_loop) || (temp_sum < 0 && !is_outer_loop)) + { + + improving = true; + sum =0; + // loop was closed and nowhere to continue + if (!has_next_edge) + { + // a loop closes with part of the edges. we have to remove edges till next_halfedge from arrangment, + // and clear the list. + removeHalfEdgesArrPart(arr,edges_set,temp_segments,loop_start_handle); + //removeHalfEdgesArrPart(arr,edges_set,temp_segments,curr_halfedge); + nextLoop(temp_segments, arr,edges_set, curr_halfedge,start_halfedge,done,loop_counter); + + } + } + } + else + { + + } + } + } */ - Halfedge_handle traverseNextHalfedge() - { - - } - - - - void traceOrientableLoops(Arrangement_history_2& arr,Edges_set& edges_set) const - { - //#define SHOW_LOOPS_CONST - int loop_counter = 0; - std::list temp_segments; - - double angles_sum = 0; - - // get an edge that is surly on the outside border. we will start from the external loop. - Face_iterator startFace = arr.unbounded_face(); - Halfedge_iterator perimiterFace = *(startFace -> holes_begin()); - //Ccb_halfedge_circulator perimiterFace = *(startFace -> holes_begin()); - /*for (hi = startFace->holes_begin(); hi != startFace->holes_end(); ++hi) { - perimiterFace = *hi; - }*/ - // change we trace outer loop first - Halfedge_iterator curr_halfedge = perimiterFace;//(*edges_set.begin()); - - //Originating_curve_iterator first_segment_itr = arr.originating_curves_begin ( *curr_halfedge); - //Segment_2 first_segment = *first_segment_itr; - //Direction_2 start_seg_dir = f_direction(f_vector(first_segment.source(),first_segment.target())); - //Direction_2 start_he_dir = f_direction((f_vector(curr_seg.source(),curr_seg.target())); - - if (!checkTripSameDirWithSegment(arr,curr_halfedge)) - curr_halfedge = curr_halfedge->twin(); - - - Halfedge_iterator start_halfedge = curr_halfedge; - temp_segments.push_back(curr_halfedge); - setEdgeVisited(*curr_halfedge,true,loop_counter); - Halfedge_handle close_loop_handle; - Halfedge_handle before_close_loop_handle; - bool isOrientable = true; - bool close_loop_found = false; - bool tracing_holes = false; - //int loop_counter; - - while(isOrientable ) - { - // after first loop we are starting to trace the holes. - if (loop_counter >0) - tracing_holes = true; - printHe(curr_halfedge); - /*for (Originating_curve_iterator itr = arr.originating_curves_begin ( curr_halfedge);itr!=arr.originating_curves_end( curr_halfedge);++itr ){ - Segment_2 segment = *itr; - - }*/ - /////////////////////////DEBUG - //Segment_2 temp = curr_halfedge->curve(); - Point_2 p_source = curr_halfedge->source()->point(); - Point_2 p_end = curr_halfedge->target()->point(); - double x1 = CGAL::to_double(p_source.x()); - double y1 = CGAL::to_double(p_source.y()); - double x2 = CGAL::to_double(p_end.x()); - double y2 = CGAL::to_double(p_end.y()); - int size_edges_set = edges_set.size(); - - /////////////////////////DEBUG - Vertex_iterator v_target = curr_halfedge->target(); - p_source = v_target->point(); - double x = CGAL::to_double(p_source.x()); - double y = CGAL::to_double(p_source.y()); - Halfedge_around_vertex_circulator itr = v_target->incident_halfedges(); - bool next_edge_found; - bool temp_close_loop_found =false; - - Halfedge_iterator next_halfedge = getLargestExitingClockwiseEdge(arr,curr_halfedge,*v_target,next_edge_found,loop_counter,temp_close_loop_found,close_loop_handle); - if (!next_halfedge->visited && next_edge_found) - setEdgeVisited(*next_halfedge,true,loop_counter); - // if any ending of loop was found remember it. - if (temp_close_loop_found) - { - before_close_loop_handle = curr_halfedge; - close_loop_found = true; - } - // printHe(next_halfedge); - //Halfedge_handle next_halfedge = getLargestExitingClockwiseEdge(); - - // Check if we are stuck or we have met a visited edge which closes the loop: - if (!next_edge_found ){ - Halfedge_handle temp_twin = next_halfedge->twin(); - if ((next_halfedge->loopNumber == loop_counter) && (next_halfedge != curr_halfedge) && (temp_twin != curr_halfedge)){ - #ifdef SHOW_LOOPS_CONST - //global_graphics->clear(); - - for (std::list::iterator itr = temp_segments.begin();itr != temp_segments.end(); ++itr) - { - //global_graphics->draw_edge((*itr)->curve(),QColor(0,255,0),true); - } - //global_graphics->display(); - #endif - // a loop closes with part of the edges. we have to remove edges till next_halfedge from arrangment, - // and clear the list. - removeHalfEdgesArrPart(arr,edges_set,temp_segments,next_halfedge); - //removeHalfEdgesArrPart(arr,edges_set,temp_segments,curr_halfedge); - nextLoop(temp_segments, arr,edges_set, curr_halfedge,start_halfedge,isOrientable,loop_counter); - } - - else - { - if (close_loop_found) - { - #ifdef SHOW_LOOPS_CONST - //global_graphics->clear(); - - for (std::list::iterator itr = temp_segments.begin();itr != temp_segments.end(); ++itr) - { - //global_graphics->draw_edge((*itr)->curve(),QColor(0,255,0),true); - } - //global_graphics->display(); - #endif - removeHalfEdgesArrPartEnd(arr,edges_set,temp_segments,close_loop_handle,before_close_loop_handle); - nextLoop(temp_segments, arr,edges_set, curr_halfedge,start_halfedge,isOrientable,loop_counter); - close_loop_found = false; - } - else - {// we are stuck. - #ifdef SHOW_LOOPS_CONST - //global_graphics->clear(); - - for (std::list::iterator itr = temp_segments.begin();itr != temp_segments.end(); ++itr) - { - //global_graphics->draw_edge((*itr)->curve(),QColor(0,255,0),true); - } - - //global_graphics->display(); - #endif - removeHalfEdgesArr(arr,edges_set,temp_segments); - nextLoop(temp_segments, arr,edges_set, curr_halfedge,start_halfedge,isOrientable,loop_counter); - } - } - } - else{ - - if (close_loop_found) - { // We have closed the loop, attempted to expand it and got stuck so remove everything but the loop. - // THIS IS WRONG ?????????????????????????????????????????????????????????????????????????????????????????????? - // THIS IS WRONG ?????????????????????????????????????????????????????????????????????????????????????????????? - // THIS IS WRONG ?????????????????????????????????????????????????????????????????????????????????????????????? - // THIS IS WRONG ?????????????????????????????????????????????????????????????????????????????????????????????? - // THIS IS WRONG ?????????????????????????????????????????????????????????????????????????????????????????????? - // THIS IS WRONG ?????????????????????????????????????????????????????????????????????????????????????????????? - - // THIS IS WRONG ?????????????????????????????????????????????????????????????????????????????????????????????? - // THIS IS WRONG ?????????????????????????????????????????????????????????????????????????????????????????????? - - // THIS IS WRONG ?????????????????????????????????????????????????????????????????????????????????????????????? - // THIS IS WRONG ?????????????????????????????????????????????????????????????????????????????????????????????? - - - #ifdef SHOW_LOOPS_CONST - //global_graphics->clear(); - - for (std::list::iterator itr = temp_segments.begin();itr != temp_segments.end(); ++itr) - { - //global_graphics->draw_edge((*itr)->curve(),QColor(0,255,0),true); - } - //global_graphics->display(); - #endif - removeHalfEdgesArrPartEnd(arr,edges_set,temp_segments,close_loop_handle,before_close_loop_handle); - nextLoop(temp_segments, arr,edges_set, curr_halfedge,start_halfedge,isOrientable,loop_counter); - close_loop_found = false; - } - else - { - curr_halfedge = next_halfedge; - temp_segments.push_back(curr_halfedge); - int size_temp_segments = temp_segments.size(); - // check if loop has closed. - // if (next_halfedge->source() == start_halfedge->source() && next_halfedge->target() == start_halfedge->target()) - if (next_halfedge== start_halfedge) - { - #ifdef SHOW_LOOPS_CONST - //global_graphics->clear(); - - for (std::list::iterator itr = temp_segments.begin();itr != temp_segments.end(); ++itr) - { - //global_graphics->draw_edge((*itr)->curve(),QColor(0,255,0),true); - } - - //global_graphics->display(); - #endif - removeHalfedgesSet(arr,edges_set,temp_segments); - nextLoop(temp_segments, arr,edges_set, curr_halfedge,start_halfedge,isOrientable,loop_counter); - } - } - } - - - - } - //printHe(curr_halfedge); - - } - - void nextLoop(std::list& temp_segments,Arrangement_history_2& arr,Edges_set& edges_set,Halfedge_iterator& curr_halfedge,Halfedge_iterator& start_halfedge,bool& isOrientable,int& loop_counter) const - { - temp_segments.clear(); - if (edges_set.size()>0){ - ++loop_counter; - curr_halfedge = (*edges_set.begin()); - while (curr_halfedge->visited && edges_set.size()>0 ) - { - typename Edges_set::iterator testItem = edges_set.find(curr_halfedge); - if (testItem == edges_set.end()){ - testItem = edges_set.find(((curr_halfedge)->twin())); - if (testItem != edges_set.end()){ - edges_set.erase(testItem); - } - } - else - edges_set.erase(testItem); - curr_halfedge = (*edges_set.begin()); - } - if (!checkTripSameDirWithSegment(arr,curr_halfedge)) - curr_halfedge = curr_halfedge->twin(); - setEdgeVisited(*curr_halfedge,true,loop_counter); - temp_segments.push_back(curr_halfedge); - start_halfedge = curr_halfedge; - } - else{ - isOrientable = false; - } - } - - void setEdgeVisited(Halfedge& he,bool value,int id) const - { - he.visited = value; - he.twin()->visited = value; - he.loopNumber = id; - he.twin()->loopNumber = id; - } - - void setEdgeDegenerate(Halfedge& he,bool value) const - { - he.isDegenerate = value; - he.twin()->isDegenerate = value; - } - - bool getEdgeDegenerate(Halfedge_handle& he) const - { - return he.isDegenerate; - } - - bool getEdgeVisited(Halfedge_handle& he) const - { - return he.visited; - } - - - - // Removes the edges matching to halfedges from the set - void removeHalfedgesSet(Arrangement_history_2& arr,Edges_set& edges_set,std::list& temp_segments) const - { - removeHalfEdgesInner(arr,edges_set,temp_segments,false,false,false,*(temp_segments.begin()),*(temp_segments.begin())); - } - - // Removes the edges matching to halfedges from the set and arrangment - void removeHalfEdgesArr(Arrangement_history_2& arr,Edges_set& edges_set,std::list& temp_segments) const - { - removeHalfEdgesInner(arr,edges_set,temp_segments,true,false,false,*(temp_segments.begin()),*(temp_segments.begin())); - } - - // Remove edges before loop and keep loop - void removeHalfEdgesArrPart(Arrangement_history_2& arr,Edges_set& edges_set,std::list& temp_segments,Halfedge_handle& partition) const - { - removeHalfEdgesInner(arr,edges_set,temp_segments,false,true,false,partition,*(temp_segments.begin())); - } - - // Remove edges before loop and keep loop and remove edges after loop. - void removeHalfEdgesArrPartEnd(Arrangement_history_2& arr,Edges_set& edges_set,std::list& temp_segments,Halfedge_handle& partition,Halfedge_handle& end_partition) const - { - removeHalfEdgesInner(arr,edges_set,temp_segments,false,true,true,partition,end_partition); - } - - // remove half edges from set or set and arrangment. - void removeHalfEdgesInner(Arrangement_history_2& arr,Edges_set& edges_set,std::list& temp_segments,bool remove_arr,bool range,bool end_range,Halfedge_handle& partition_itr,Halfedge_handle& partition_end_itr ) const - { - bool part_reached = false; - - typename Edges_set::iterator partItem = edges_set.find(partition_itr); - if (partItem == edges_set.end()){ - partItem = edges_set.find(((*partition_itr).twin())); - } - - typename Edges_set::iterator part_item_end = edges_set.find(partition_end_itr); - if (part_item_end == edges_set.end()){ - part_item_end = edges_set.find(((*partition_end_itr).twin())); - } - - Halfedge_handle h_e_start; - if (partItem != edges_set.end()){ - h_e_start = *partItem; - } - Halfedge_handle h_e_finish; - if (part_item_end != edges_set.end()) - { - h_e_finish = *part_item_end; - } - - printHe(h_e_start); - - bool mark_change_part = false; - - for (typename std::list::iterator itr = temp_segments.begin();itr != temp_segments.end();++itr) - { - //int a = edges_set.size(); - //int b = temp_segments.size(); - //Halfedge_handle h1 = *itr; - //Halfedge_handle h2 = *partItem; - printHe(*itr); - - if (range && !part_reached && ((*itr == h_e_start) || (*itr == h_e_start->twin())) ) - part_reached = true; - - // If we have to close the loop check if range end has arrived - if (range && end_range &&part_reached && (((*itr) == h_e_finish) || (*itr == h_e_finish->twin()) ) ) - mark_change_part = true; - - - - typename Edges_set::iterator testItem = edges_set.find(*itr); - if (testItem == edges_set.end()){ - testItem = edges_set.find(((*itr)->twin())); - if (testItem != edges_set.end()){ - edges_set.erase(testItem); - if (remove_arr || (range && !part_reached)) - arr.remove_edge(*itr); - } - } - else{ - edges_set.erase(testItem); - if (remove_arr || (range && !part_reached)) - arr.remove_edge(*itr); - } - - if (mark_change_part) - part_reached = false; - } - } - - - Halfedge_handle getLargestExitingClockwiseEdge(Arrangement_history_2& arr,Halfedge_iterator& curr_halfedge,Vertex& v_target,bool& next_edge_found,int loop_number,bool& close_loop_found,Halfedge_handle& handle_close_loop) const - { - Point_2 p_source = v_target.point(); - double x1 = CGAL::to_double(p_source.x()); - double y1 = CGAL::to_double(p_source.y()); - Halfedge_around_vertex_circulator itr = v_target.incident_halfedges(); - Halfedge_around_vertex_circulator start = itr; - Halfedge_around_vertex_circulator tmp = itr; - ++itr; - //unsigned int number_of_incident_edges = itr.size(); - if (itr == tmp){ - next_edge_found = false; - return itr; - } -// --itr; - bool found = false; - Direction_2 entering_dir = f_direction((f_vector(curr_halfedge->source()->point(),curr_halfedge->target()->point()))); - - // find first edge which is valid in direction with respect to original edges. - // - int count =0; - bool res; - - while ((!(res = checkTripSameDirWithSegment(arr,((itr->twin())))) || (curr_halfedge == itr) || (itr->visited)) && (itr!=start) ) - { - ++itr; - ++ count; - } - Halfedge_handle maybe_visited; - if (count == 1) - { - - close_loop_found = false; - if (!checkOutgoingNotVisited(arr,v_target,maybe_visited,loop_number)) - { - close_loop_found = true; - handle_close_loop = maybe_visited; - } - } - - if (!res || itr->visited ){ - next_edge_found = false; - return itr->twin(); - } - - if (count != 1) - { - //Halfedge_handle maybe_visited; - close_loop_found = false; - if (!checkOutgoingNotVisited(arr,v_target,maybe_visited,loop_number)) - { - close_loop_found = true; - handle_close_loop = maybe_visited; - } - } - - //Halfedge& min_he = itr->twin(); - - // Now we have the first edge, check if we can improve - Halfedge_around_vertex_circulator next_edge_itr = itr; - ++next_edge_itr; - //Halfedge_iterator best_he = - count =0; - Direction_2 min_edge_dir = f_direction((f_vector(itr->twin()->source()->point(),itr->twin()->target()->point()))); - while (next_edge_itr != itr) - { - if (checkTripSameDirWithSegment(arr,((next_edge_itr->twin())))){ - Direction_2 new_edge_dir = f_direction((f_vector(next_edge_itr->twin()->source()->point(),next_edge_itr->twin()->target()->point()))); - // If the new edge improves the old one, ie it is larger and satisfies the improvment rule, which is under consideration. - // currently, being the anticlocwise most if we are in right halfplane of the entering direction, and then choose anti clockwise most from left plane. - if ( isDirImproving(min_edge_dir,entering_dir,new_edge_dir) && - (!next_edge_itr->visited) - ){ - //(f_ccw_in_between(new_edge_dir,-entering_dir,min_edge_dir) && f_ccw_in_between(new_edge_dir,min_edge_dir,entering_dir))){ - itr = next_edge_itr; - min_edge_dir = f_direction((f_vector(itr->twin()->source()->point(),itr->twin()->target()->point()))); - } - } - ++count; - ++next_edge_itr; - } - if (close_loop_found) - { - Direction_2 new_edge_dir = f_direction((f_vector(maybe_visited->twin()->source()->point(),maybe_visited->twin()->target()->point()))); - if (isDirImproving(min_edge_dir,entering_dir,new_edge_dir)) - { - next_edge_found = true; - return maybe_visited->twin(); - } - } - - next_edge_found = true; - return itr->twin(); - - - } - - //bool isDirImproving(Direction_2& min_edge_dir,Direction_2& entering_dir,Direction_2& new_edge_dir) const - //{ - ///* return (( ((entering_dir == new_edge_dir ) || (f_ccw_in_between(entering_dir,new_edge_dir,min_edge_dir) || (min_edge_dir == entering_dir) )) && (!f_ccw_in_between(min_edge_dir,-entering_dir,new_edge_dir))) || - // (f_ccw_in_between(min_edge_dir,new_edge_dir,-entering_dir) && !f_ccw_in_between(entering_dir,min_edge_dir,new_edge_dir) && (min_edge_dir!=entering_dir)));*/ - // // - // if ((entering_dir == min_edge_dir ) || f_ccw_in_between(min_edge_dir,-entering_dir,entering_dir)) // if minimal dir is to the right - // { - // return f_ccw_in_between(new_edge_dir,-entering_dir,min_edge_dir); - // } - // else // min dir is to the left. - // { - // if (f_ccw_in_between(new_edge_dir,-entering_dir,entering_dir) || (entering_dir == new_edge_dir ) ) // if new dir is to the right it is better. - // return true; - // return f_ccw_in_between(new_edge_dir,min_edge_dir,-entering_dir); // else check improvment on left side. - // } - //} - - bool isDirImproving(Direction_2& min_edge_dir,Direction_2& entering_dir,Direction_2& new_edge_dir) const - { - /* return (( ((entering_dir == new_edge_dir ) || (f_ccw_in_between(entering_dir,new_edge_dir,min_edge_dir) || (min_edge_dir == entering_dir) )) && (!f_ccw_in_between(min_edge_dir,-entering_dir,new_edge_dir))) || - (f_ccw_in_between(min_edge_dir,new_edge_dir,-entering_dir) && !f_ccw_in_between(entering_dir,min_edge_dir,new_edge_dir) && (min_edge_dir!=entering_dir)));*/ - // - Direction_2 opp_enter = -entering_dir; - if ((opp_enter == min_edge_dir ) ) // if minimal dir equals -entering dir - { - return true; - } - else // - { - return f_ccw_in_between(new_edge_dir,opp_enter,min_edge_dir); - /* if (f_ccw_in_between(new_edge_dir,-entering_dir,entering_dir) || (entering_dir == new_edge_dir ) ) // if new dir is to the right it is better. - return true; - return f_ccw_in_between(new_edge_dir,min_edge_dir,-entering_dir); // else check improvment on left side.*/ - } - } - - - /* - Checks that the edge leads to a vertex which an outgoing visited edge has been ie returns false if we close a loop. - h returns the edge which begins the loop - */ - bool checkOutgoingNotVisited(Arrangement_history_2& arr,Vertex& v_target,Halfedge_handle& h,int loop_number) const - { - Point_2 p_source = v_target.point(); - - Halfedge_around_vertex_circulator itr = v_target.incident_halfedges(); - Halfedge_around_vertex_circulator start = itr; - - do{ - if (checkTripSameDirWithSegment(arr,((itr->twin()))) && itr->visited && itr->loopNumber == loop_number) - { - h = itr; - return false; - } - }while (++itr != start ); - return true; - } - - bool checkTripSameDirWithSegment_bak(Arrangement_history_2& arr,Halfedge_handle he) const - { - Originating_curve_iterator segment_itr;// = arr.originating_curves_begin ( *he); - //bool found = false; - //segment = NULL; - Direction_2 start_he_dir = f_direction((f_vector(he->source()->point(),he->target()->point()))); - - for (segment_itr = arr.originating_curves_begin (he);segment_itr != arr.originating_curves_end(he);++segment_itr) - { - Segment_2 segment = *segment_itr; - /*std::cout << "checktrip: " << std::endl; - printSegment(segment); - printHe(he);*/ - Direction_2 start_seg_dir = f_direction(f_vector(segment.source(),segment.target())); - - - if (start_seg_dir == start_he_dir){ - return true; - - } - } - - return false; - } - - bool checkTripSameDirWithSegment(Arrangement_history_2& arr,Halfedge_handle he) const - { - Originating_curve_iterator segment_itr;// = arr.originating_curves_begin ( *he); - //bool found = false; - //segment = NULL; - //Vector_2 start_he_dir = (f_vector(he->source()->point(),he->target()->point())); - - for (segment_itr = arr.originating_curves_begin (he);segment_itr != arr.originating_curves_end(he);++segment_itr) - { - Segment_2 segment = *segment_itr; - /*std::cout << "checktrip: " << std::endl; - printSegment(segment); - printHe(he);*/ - //Vector_2 start_seg_dir = f_vector(segment.source(),segment.target()); - - - //if (CGAL::angle(start_he_dir,start_seg_dir)==CGAL::ACUTE){ - //if (f_angle(start_he_dir,start_seg_dir)==CGAL::ACUTE){ - - /* - if (CGAL::collinear_are_ordered_along_line(segment.source(),he->source()->point(),he->target()->point())){ - return true;} - */ - - - CGAL::Comparison_result c1 = f_compare_endpoints_xy(segment); - CGAL::Comparison_result c2 = (CGAL::Comparison_result)he->direction();//f_compare_xy(he->source()->point(),he->target()->point()); - bool same_dir = (c1==c2); - if (same_dir) - return true; - - - } - - return false; - } - - bool checkTripNotSameDirWithSegment(Arrangement_history_2& arr,Halfedge_handle he) const - { - Originating_curve_iterator segment_itr;// = arr.originating_curves_begin ( *he); - //bool found = false; - //segment = NULL; - //Vector_2 start_he_dir = (f_vector(he->source()->point(),he->target()->point())); - - for (segment_itr = arr.originating_curves_begin (he);segment_itr != arr.originating_curves_end(he);++segment_itr) - { - Segment_2 segment = *segment_itr; - /*std::cout << "checktrip: " << std::endl; - printSegment(segment); - printHe(he);*/ - //Vector_2 start_seg_dir = f_vector(segment.source(),segment.target()); - - - //if (CGAL::angle(start_he_dir,start_seg_dir)==CGAL::ACUTE){ - //if (f_angle(start_he_dir,start_seg_dir)==CGAL::ACUTE){ - - /* - if (CGAL::collinear_are_ordered_along_line(segment.source(),he->source()->point(),he->target()->point())){ - return true;} - */ - - - CGAL::Comparison_result c1 = segment.label()._orientation;//f_compare_endpoints_xy(segment); - //CGAL::Comparison_result c1 = segment.data();//f_compare_endpoints_xy(segment); - CGAL::Comparison_result c2 = (CGAL::Comparison_result)he->direction();//f_compare_xy(he->source()->point(),he->target()->point()); - bool same_dir = (c1!=c2); - if (same_dir) - return true; - - - } - - return false; - } - - - - bool checkReflex(const Point_2& prev,const Point_2& curr,const Point_2& next) const - { - CGAL::Orientation res_ori = f_orientation (prev, curr, next); - //if (f_orientation (prev, curr, next) == COLLINEAR) - - return ((res_ori == RIGHT_TURN) || (res_ori == COLLINEAR)); - } - - /*bool checkSwept(const Point_2& prev,const Point_2& curr,const Point_2& next,const Point_2& start,const Point_2& end) const - { - Direction_2 dir_start = f_direction(f_vector(prev,curr)); - Direction_2 dir_end = f_direction(f_vector(curr,next)); - Direction_2 dir_new = f_direction(f_vector(start,end)); - return (dir_new == dir_start) || f_ccw_in_between(dir_new,dir_start,dir_end) || (dir_end == dir_new); - }*/ - - bool checkSwept(const Point_2& prev,const Point_2& curr,const Point_2& next,const Point_2& start,const Point_2& end, bool& isStartConcide,bool& isEndConcide) const - { - Direction_2 dir_start = f_direction(f_vector(prev,curr)); - Direction_2 dir_end = f_direction(f_vector(curr,next)); - Direction_2 dir_new = f_direction(f_vector(start,end)); - isStartConcide = dir_new == dir_start; - isEndConcide = dir_end == dir_new; - - return isStartConcide || f_ccw_in_between(dir_new,dir_start,dir_end) ||isEndConcide; - } - - bool checkSwept(Direction_2& dir_start,Direction_2& dir_end,Direction_2& dir_new, bool& isStartConcide,bool& isEndConcide) const - { - /* Direction_2 dir_start = f_direction(f_vector(prev,curr)); - Direction_2 dir_end = f_direction(f_vector(curr,next)); - Direction_2 dir_new = f_direction(f_vector(start,end));*/ - isStartConcide = dir_new == dir_start; - isEndConcide = dir_end == dir_new; - - return isStartConcide || f_ccw_in_between(dir_new,dir_start,dir_end) ||isEndConcide; - } - - void printHe(Halfedge_handle he) const - { - //Segment_2 temp = he->curve(); - if (!HE_WRITE) - return; - Point_2 p_source = he->source()->point(); - Point_2 p_end = he->target()->point(); - double x1 = CGAL::to_double(p_source.x()); - double y1 = CGAL::to_double(p_source.y()); - double x2 = CGAL::to_double(p_end.x()); - double y2 = CGAL::to_double(p_end.y()); - - std::cout << x1 << "," << y1 << "," << x2 << "," << y2 << std::endl; - } - - void printSegment(Segment_2& seg) const - { - //Segment_2 temp = he->curve(); - if (!HE_WRITE) - return; - Point_2 p_source = seg.source(); - Point_2 p_end = seg.target(); - double x1 = CGAL::to_double(p_source.x()); - double y1 = CGAL::to_double(p_source.y()); - double x2 = CGAL::to_double(p_end.x()); - double y2 = CGAL::to_double(p_end.y()); - - std::cout << x1 << "," << y1 << "," << x2 << "," << y2 << std::endl; - } - - void draw_arr(Arrangement_history_2& arr) const - { - //QColor c(0,255,0); - for (Edge_iterator itr = arr.edges_begin();itr!=arr.edges_end();++itr){ - printSegment(itr->curve()); - //global_graphics->draw_edge(itr->curve(),c,true); - - } - - // draw isolated vertices - /* Face_handle unbounded_face = arr.unbounded_face(); - - Hole_iterator hi; - Ccb_halfedge_circulator perimiterFace; - for (hi = unbounded_face->holes_begin(); hi != unbounded_face->holes_end(); ++hi) { - perimiterFace = *hi; - } - hi->*/ - Vertex_iterator vit; - //QColor c2(0,255,255); - for (vit = arr.vertices_begin(); vit != arr.vertices_end(); ++vit) { - - if (vit->is_isolated()) - { - //global_graphics->draw_cross(vit->point(),c2,0.1); - } - - } - - - } - - + Halfedge_handle traverseNextHalfedge() { + + } + + + + void traceOrientableLoops(Arrangement_history_2 &arr, Edges_set &edges_set) const { + //#define SHOW_LOOPS_CONST + int loop_counter = 0; + std::list temp_segments; + + double angles_sum = 0; + + // get an edge that is surly on the outside border. we will start from the external loop. + Face_iterator startFace = arr.unbounded_face(); + Halfedge_iterator perimiterFace = *(startFace -> holes_begin()); + //Ccb_halfedge_circulator perimiterFace = *(startFace -> holes_begin()); + /*for (hi = startFace->holes_begin(); hi != startFace->holes_end(); ++hi) { + perimiterFace = *hi; + }*/ + // change we trace outer loop first + Halfedge_iterator curr_halfedge = perimiterFace;//(*edges_set.begin()); + + //Originating_curve_iterator first_segment_itr = arr.originating_curves_begin ( *curr_halfedge); + //Segment_2 first_segment = *first_segment_itr; + //Direction_2 start_seg_dir = f_direction(f_vector(first_segment.source(),first_segment.target())); + //Direction_2 start_he_dir = f_direction((f_vector(curr_seg.source(),curr_seg.target())); + + if (!checkTripSameDirWithSegment(arr, curr_halfedge)) { + curr_halfedge = curr_halfedge->twin(); + } + + + Halfedge_iterator start_halfedge = curr_halfedge; + temp_segments.push_back(curr_halfedge); + setEdgeVisited(*curr_halfedge, true, loop_counter); + Halfedge_handle close_loop_handle; + Halfedge_handle before_close_loop_handle; + bool isOrientable = true; + bool close_loop_found = false; + bool tracing_holes = false; + //int loop_counter; + + while (isOrientable) { + // after first loop we are starting to trace the holes. + if (loop_counter > 0) { + tracing_holes = true; + } + + printHe(curr_halfedge); + /*for (Originating_curve_iterator itr = arr.originating_curves_begin ( curr_halfedge);itr!=arr.originating_curves_end( curr_halfedge);++itr ){ + Segment_2 segment = *itr; + + }*/ + /////////////////////////DEBUG + //Segment_2 temp = curr_halfedge->curve(); + Point_2 p_source = curr_halfedge->source()->point(); + Point_2 p_end = curr_halfedge->target()->point(); + double x1 = CGAL::to_double(p_source.x()); + double y1 = CGAL::to_double(p_source.y()); + double x2 = CGAL::to_double(p_end.x()); + double y2 = CGAL::to_double(p_end.y()); + int size_edges_set = edges_set.size(); + + /////////////////////////DEBUG + Vertex_iterator v_target = curr_halfedge->target(); + p_source = v_target->point(); + double x = CGAL::to_double(p_source.x()); + double y = CGAL::to_double(p_source.y()); + Halfedge_around_vertex_circulator itr = v_target->incident_halfedges(); + bool next_edge_found; + bool temp_close_loop_found = false; + + Halfedge_iterator next_halfedge = getLargestExitingClockwiseEdge(arr, curr_halfedge, *v_target, next_edge_found, loop_counter, temp_close_loop_found, close_loop_handle); + + if (!next_halfedge->visited && next_edge_found) { + setEdgeVisited(*next_halfedge, true, loop_counter); + } + + // if any ending of loop was found remember it. + if (temp_close_loop_found) { + before_close_loop_handle = curr_halfedge; + close_loop_found = true; + } + + // printHe(next_halfedge); + //Halfedge_handle next_halfedge = getLargestExitingClockwiseEdge(); + + // Check if we are stuck or we have met a visited edge which closes the loop: + if (!next_edge_found) { + Halfedge_handle temp_twin = next_halfedge->twin(); + + if ((next_halfedge->loopNumber == loop_counter) && (next_halfedge != curr_halfedge) && (temp_twin != curr_halfedge)) { +#ifdef SHOW_LOOPS_CONST + //global_graphics->clear(); + + for (std::list::iterator itr = temp_segments.begin(); itr != temp_segments.end(); ++itr) { + //global_graphics->draw_edge((*itr)->curve(),QColor(0,255,0),true); + } + + //global_graphics->display(); +#endif + // a loop closes with part of the edges. we have to remove edges till next_halfedge from arrangment, + // and clear the list. + removeHalfEdgesArrPart(arr, edges_set, temp_segments, next_halfedge); + //removeHalfEdgesArrPart(arr,edges_set,temp_segments,curr_halfedge); + nextLoop(temp_segments, arr, edges_set, curr_halfedge, start_halfedge, isOrientable, loop_counter); + } + + else { + if (close_loop_found) { +#ifdef SHOW_LOOPS_CONST + //global_graphics->clear(); + + for (std::list::iterator itr = temp_segments.begin(); itr != temp_segments.end(); ++itr) { + //global_graphics->draw_edge((*itr)->curve(),QColor(0,255,0),true); + } + + //global_graphics->display(); +#endif + removeHalfEdgesArrPartEnd(arr, edges_set, temp_segments, close_loop_handle, before_close_loop_handle); + nextLoop(temp_segments, arr, edges_set, curr_halfedge, start_halfedge, isOrientable, loop_counter); + close_loop_found = false; + } else { + // we are stuck. +#ifdef SHOW_LOOPS_CONST + //global_graphics->clear(); + + for (std::list::iterator itr = temp_segments.begin(); itr != temp_segments.end(); ++itr) { + //global_graphics->draw_edge((*itr)->curve(),QColor(0,255,0),true); + } + + //global_graphics->display(); +#endif + removeHalfEdgesArr(arr, edges_set, temp_segments); + nextLoop(temp_segments, arr, edges_set, curr_halfedge, start_halfedge, isOrientable, loop_counter); + } + } + } else { + + if (close_loop_found) { + // We have closed the loop, attempted to expand it and got stuck so remove everything but the loop. + // THIS IS WRONG ?????????????????????????????????????????????????????????????????????????????????????????????? + // THIS IS WRONG ?????????????????????????????????????????????????????????????????????????????????????????????? + // THIS IS WRONG ?????????????????????????????????????????????????????????????????????????????????????????????? + // THIS IS WRONG ?????????????????????????????????????????????????????????????????????????????????????????????? + // THIS IS WRONG ?????????????????????????????????????????????????????????????????????????????????????????????? + // THIS IS WRONG ?????????????????????????????????????????????????????????????????????????????????????????????? + + // THIS IS WRONG ?????????????????????????????????????????????????????????????????????????????????????????????? + // THIS IS WRONG ?????????????????????????????????????????????????????????????????????????????????????????????? + + // THIS IS WRONG ?????????????????????????????????????????????????????????????????????????????????????????????? + // THIS IS WRONG ?????????????????????????????????????????????????????????????????????????????????????????????? + + +#ifdef SHOW_LOOPS_CONST + //global_graphics->clear(); + + for (std::list::iterator itr = temp_segments.begin(); itr != temp_segments.end(); ++itr) { + //global_graphics->draw_edge((*itr)->curve(),QColor(0,255,0),true); + } + + //global_graphics->display(); +#endif + removeHalfEdgesArrPartEnd(arr, edges_set, temp_segments, close_loop_handle, before_close_loop_handle); + nextLoop(temp_segments, arr, edges_set, curr_halfedge, start_halfedge, isOrientable, loop_counter); + close_loop_found = false; + } else { + curr_halfedge = next_halfedge; + temp_segments.push_back(curr_halfedge); + int size_temp_segments = temp_segments.size(); + + // check if loop has closed. + // if (next_halfedge->source() == start_halfedge->source() && next_halfedge->target() == start_halfedge->target()) + if (next_halfedge == start_halfedge) { +#ifdef SHOW_LOOPS_CONST + //global_graphics->clear(); + + for (std::list::iterator itr = temp_segments.begin(); itr != temp_segments.end(); ++itr) { + //global_graphics->draw_edge((*itr)->curve(),QColor(0,255,0),true); + } + + //global_graphics->display(); +#endif + removeHalfedgesSet(arr, edges_set, temp_segments); + nextLoop(temp_segments, arr, edges_set, curr_halfedge, start_halfedge, isOrientable, loop_counter); + } + } + } + + + + } + + //printHe(curr_halfedge); + + } + + void nextLoop(std::list &temp_segments, Arrangement_history_2 &arr, Edges_set &edges_set, Halfedge_iterator &curr_halfedge, Halfedge_iterator &start_halfedge, bool &isOrientable, int &loop_counter) const { + temp_segments.clear(); + + if (edges_set.size() > 0) { + ++loop_counter; + curr_halfedge = (*edges_set.begin()); + + while (curr_halfedge->visited && edges_set.size() > 0) { + typename Edges_set::iterator testItem = edges_set.find(curr_halfedge); + + if (testItem == edges_set.end()) { + testItem = edges_set.find(((curr_halfedge)->twin())); + + if (testItem != edges_set.end()) { + edges_set.erase(testItem); + } + } else { + edges_set.erase(testItem); + } + + curr_halfedge = (*edges_set.begin()); + } + + if (!checkTripSameDirWithSegment(arr, curr_halfedge)) { + curr_halfedge = curr_halfedge->twin(); + } + + setEdgeVisited(*curr_halfedge, true, loop_counter); + temp_segments.push_back(curr_halfedge); + start_halfedge = curr_halfedge; + } else { + isOrientable = false; + } + } + + void setEdgeVisited(Halfedge &he, bool value, int id) const { + he.visited = value; + he.twin()->visited = value; + he.loopNumber = id; + he.twin()->loopNumber = id; + } + + void setEdgeDegenerate(Halfedge &he, bool value) const { + he.isDegenerate = value; + he.twin()->isDegenerate = value; + } + + bool getEdgeDegenerate(Halfedge_handle &he) const { + return he.isDegenerate; + } + + bool getEdgeVisited(Halfedge_handle &he) const { + return he.visited; + } + + + + // Removes the edges matching to halfedges from the set + void removeHalfedgesSet(Arrangement_history_2 &arr, Edges_set &edges_set, std::list &temp_segments) const { + removeHalfEdgesInner(arr, edges_set, temp_segments, false, false, false, *(temp_segments.begin()), *(temp_segments.begin())); + } + + // Removes the edges matching to halfedges from the set and arrangment + void removeHalfEdgesArr(Arrangement_history_2 &arr, Edges_set &edges_set, std::list &temp_segments) const { + removeHalfEdgesInner(arr, edges_set, temp_segments, true, false, false, *(temp_segments.begin()), *(temp_segments.begin())); + } + + // Remove edges before loop and keep loop + void removeHalfEdgesArrPart(Arrangement_history_2 &arr, Edges_set &edges_set, std::list &temp_segments, Halfedge_handle &partition) const { + removeHalfEdgesInner(arr, edges_set, temp_segments, false, true, false, partition, *(temp_segments.begin())); + } + + // Remove edges before loop and keep loop and remove edges after loop. + void removeHalfEdgesArrPartEnd(Arrangement_history_2 &arr, Edges_set &edges_set, std::list &temp_segments, Halfedge_handle &partition, Halfedge_handle &end_partition) const { + removeHalfEdgesInner(arr, edges_set, temp_segments, false, true, true, partition, end_partition); + } + + // remove half edges from set or set and arrangment. + void removeHalfEdgesInner(Arrangement_history_2 &arr, Edges_set &edges_set, std::list &temp_segments, bool remove_arr, bool range, bool end_range, Halfedge_handle &partition_itr, Halfedge_handle &partition_end_itr) const { + bool part_reached = false; + + typename Edges_set::iterator partItem = edges_set.find(partition_itr); + + if (partItem == edges_set.end()) { + partItem = edges_set.find(((*partition_itr).twin())); + } + + typename Edges_set::iterator part_item_end = edges_set.find(partition_end_itr); + + if (part_item_end == edges_set.end()) { + part_item_end = edges_set.find(((*partition_end_itr).twin())); + } + + Halfedge_handle h_e_start; + + if (partItem != edges_set.end()) { + h_e_start = *partItem; + } + + Halfedge_handle h_e_finish; + + if (part_item_end != edges_set.end()) { + h_e_finish = *part_item_end; + } + + printHe(h_e_start); + + bool mark_change_part = false; + + for (typename std::list::iterator itr = temp_segments.begin(); itr != temp_segments.end(); ++itr) { + //int a = edges_set.size(); + //int b = temp_segments.size(); + //Halfedge_handle h1 = *itr; + //Halfedge_handle h2 = *partItem; + printHe(*itr); + + if (range && !part_reached && ((*itr == h_e_start) || (*itr == h_e_start->twin()))) { + part_reached = true; + } + + // If we have to close the loop check if range end has arrived + if (range && end_range && part_reached && (((*itr) == h_e_finish) || (*itr == h_e_finish->twin()))) { + mark_change_part = true; + } + + + + typename Edges_set::iterator testItem = edges_set.find(*itr); + + if (testItem == edges_set.end()) { + testItem = edges_set.find(((*itr)->twin())); + + if (testItem != edges_set.end()) { + edges_set.erase(testItem); + + if (remove_arr || (range && !part_reached)) { + arr.remove_edge(*itr); + } + } + } else { + edges_set.erase(testItem); + + if (remove_arr || (range && !part_reached)) { + arr.remove_edge(*itr); + } + } + + if (mark_change_part) { + part_reached = false; + } + } + } + + + Halfedge_handle getLargestExitingClockwiseEdge(Arrangement_history_2 &arr, Halfedge_iterator &curr_halfedge, Vertex &v_target, bool &next_edge_found, int loop_number, bool &close_loop_found, Halfedge_handle &handle_close_loop) const { + Point_2 p_source = v_target.point(); + double x1 = CGAL::to_double(p_source.x()); + double y1 = CGAL::to_double(p_source.y()); + Halfedge_around_vertex_circulator itr = v_target.incident_halfedges(); + Halfedge_around_vertex_circulator start = itr; + Halfedge_around_vertex_circulator tmp = itr; + ++itr; + + //unsigned int number_of_incident_edges = itr.size(); + if (itr == tmp) { + next_edge_found = false; + return itr; + } + +// --itr; + bool found = false; + Direction_2 entering_dir = f_direction((f_vector(curr_halfedge->source()->point(), curr_halfedge->target()->point()))); + + // find first edge which is valid in direction with respect to original edges. + // + int count = 0; + bool res; + + while ((!(res = checkTripSameDirWithSegment(arr, ((itr->twin())))) || (curr_halfedge == itr) || (itr->visited)) && (itr != start)) { + ++itr; + ++ count; + } + + Halfedge_handle maybe_visited; + + if (count == 1) { + + close_loop_found = false; + + if (!checkOutgoingNotVisited(arr, v_target, maybe_visited, loop_number)) { + close_loop_found = true; + handle_close_loop = maybe_visited; + } + } + + if (!res || itr->visited) { + next_edge_found = false; + return itr->twin(); + } + + if (count != 1) { + //Halfedge_handle maybe_visited; + close_loop_found = false; + + if (!checkOutgoingNotVisited(arr, v_target, maybe_visited, loop_number)) { + close_loop_found = true; + handle_close_loop = maybe_visited; + } + } + + //Halfedge& min_he = itr->twin(); + + // Now we have the first edge, check if we can improve + Halfedge_around_vertex_circulator next_edge_itr = itr; + ++next_edge_itr; + //Halfedge_iterator best_he = + count = 0; + Direction_2 min_edge_dir = f_direction((f_vector(itr->twin()->source()->point(), itr->twin()->target()->point()))); + + while (next_edge_itr != itr) { + if (checkTripSameDirWithSegment(arr, ((next_edge_itr->twin())))) { + Direction_2 new_edge_dir = f_direction((f_vector(next_edge_itr->twin()->source()->point(), next_edge_itr->twin()->target()->point()))); + + // If the new edge improves the old one, ie it is larger and satisfies the improvment rule, which is under consideration. + // currently, being the anticlocwise most if we are in right halfplane of the entering direction, and then choose anti clockwise most from left plane. + if (isDirImproving(min_edge_dir, entering_dir, new_edge_dir) && + (!next_edge_itr->visited) + ) { + //(f_ccw_in_between(new_edge_dir,-entering_dir,min_edge_dir) && f_ccw_in_between(new_edge_dir,min_edge_dir,entering_dir))){ + itr = next_edge_itr; + min_edge_dir = f_direction((f_vector(itr->twin()->source()->point(), itr->twin()->target()->point()))); + } + } + + ++count; + ++next_edge_itr; + } + + if (close_loop_found) { + Direction_2 new_edge_dir = f_direction((f_vector(maybe_visited->twin()->source()->point(), maybe_visited->twin()->target()->point()))); + + if (isDirImproving(min_edge_dir, entering_dir, new_edge_dir)) { + next_edge_found = true; + return maybe_visited->twin(); + } + } + + next_edge_found = true; + return itr->twin(); + + + } + + //bool isDirImproving(Direction_2& min_edge_dir,Direction_2& entering_dir,Direction_2& new_edge_dir) const + //{ + ///* return (( ((entering_dir == new_edge_dir ) || (f_ccw_in_between(entering_dir,new_edge_dir,min_edge_dir) || (min_edge_dir == entering_dir) )) && (!f_ccw_in_between(min_edge_dir,-entering_dir,new_edge_dir))) || + // (f_ccw_in_between(min_edge_dir,new_edge_dir,-entering_dir) && !f_ccw_in_between(entering_dir,min_edge_dir,new_edge_dir) && (min_edge_dir!=entering_dir)));*/ + // // + // if ((entering_dir == min_edge_dir ) || f_ccw_in_between(min_edge_dir,-entering_dir,entering_dir)) // if minimal dir is to the right + // { + // return f_ccw_in_between(new_edge_dir,-entering_dir,min_edge_dir); + // } + // else // min dir is to the left. + // { + // if (f_ccw_in_between(new_edge_dir,-entering_dir,entering_dir) || (entering_dir == new_edge_dir ) ) // if new dir is to the right it is better. + // return true; + // return f_ccw_in_between(new_edge_dir,min_edge_dir,-entering_dir); // else check improvment on left side. + // } + //} + + bool isDirImproving(Direction_2 &min_edge_dir, Direction_2 &entering_dir, Direction_2 &new_edge_dir) const { + /* return (( ((entering_dir == new_edge_dir ) || (f_ccw_in_between(entering_dir,new_edge_dir,min_edge_dir) || (min_edge_dir == entering_dir) )) && (!f_ccw_in_between(min_edge_dir,-entering_dir,new_edge_dir))) || + (f_ccw_in_between(min_edge_dir,new_edge_dir,-entering_dir) && !f_ccw_in_between(entering_dir,min_edge_dir,new_edge_dir) && (min_edge_dir!=entering_dir)));*/ + // + Direction_2 opp_enter = -entering_dir; + + if ((opp_enter == min_edge_dir)) { // if minimal dir equals -entering dir + return true; + } else { // + return f_ccw_in_between(new_edge_dir, opp_enter, min_edge_dir); + /* if (f_ccw_in_between(new_edge_dir,-entering_dir,entering_dir) || (entering_dir == new_edge_dir ) ) // if new dir is to the right it is better. + return true; + return f_ccw_in_between(new_edge_dir,min_edge_dir,-entering_dir); // else check improvment on left side.*/ + } + } + + + /* + Checks that the edge leads to a vertex which an outgoing visited edge has been ie returns false if we close a loop. + h returns the edge which begins the loop + */ + bool checkOutgoingNotVisited(Arrangement_history_2 &arr, Vertex &v_target, Halfedge_handle &h, int loop_number) const { + Point_2 p_source = v_target.point(); + + Halfedge_around_vertex_circulator itr = v_target.incident_halfedges(); + Halfedge_around_vertex_circulator start = itr; + + do { + if (checkTripSameDirWithSegment(arr, ((itr->twin()))) && itr->visited && itr->loopNumber == loop_number) { + h = itr; + return false; + } + } while (++itr != start); + + return true; + } + + bool checkTripSameDirWithSegment_bak(Arrangement_history_2 &arr, Halfedge_handle he) const { + Originating_curve_iterator segment_itr;// = arr.originating_curves_begin ( *he); + //bool found = false; + //segment = NULL; + Direction_2 start_he_dir = f_direction((f_vector(he->source()->point(), he->target()->point()))); + + for (segment_itr = arr.originating_curves_begin(he); segment_itr != arr.originating_curves_end(he); ++segment_itr) { + Segment_2 segment = *segment_itr; + /*std::cout << "checktrip: " << std::endl; + printSegment(segment); + printHe(he);*/ + Direction_2 start_seg_dir = f_direction(f_vector(segment.source(), segment.target())); + + + if (start_seg_dir == start_he_dir) { + return true; + + } + } + + return false; + } + + bool checkTripSameDirWithSegment(Arrangement_history_2 &arr, Halfedge_handle he) const { + Originating_curve_iterator segment_itr;// = arr.originating_curves_begin ( *he); + //bool found = false; + //segment = NULL; + //Vector_2 start_he_dir = (f_vector(he->source()->point(),he->target()->point())); + + for (segment_itr = arr.originating_curves_begin(he); segment_itr != arr.originating_curves_end(he); ++segment_itr) { + Segment_2 segment = *segment_itr; + /*std::cout << "checktrip: " << std::endl; + printSegment(segment); + printHe(he);*/ + //Vector_2 start_seg_dir = f_vector(segment.source(),segment.target()); + + + //if (CGAL::angle(start_he_dir,start_seg_dir)==CGAL::ACUTE){ + //if (f_angle(start_he_dir,start_seg_dir)==CGAL::ACUTE){ + + /* + if (CGAL::collinear_are_ordered_along_line(segment.source(),he->source()->point(),he->target()->point())){ + return true;} + */ + + + CGAL::Comparison_result c1 = f_compare_endpoints_xy(segment); + CGAL::Comparison_result c2 = (CGAL::Comparison_result)he->direction();//f_compare_xy(he->source()->point(),he->target()->point()); + bool same_dir = (c1 == c2); + + if (same_dir) { + return true; + } + + + } + + return false; + } + + bool checkTripNotSameDirWithSegment(Arrangement_history_2 &arr, Halfedge_handle he) const { + Originating_curve_iterator segment_itr;// = arr.originating_curves_begin ( *he); + //bool found = false; + //segment = NULL; + //Vector_2 start_he_dir = (f_vector(he->source()->point(),he->target()->point())); + + for (segment_itr = arr.originating_curves_begin(he); segment_itr != arr.originating_curves_end(he); ++segment_itr) { + Segment_2 segment = *segment_itr; + /*std::cout << "checktrip: " << std::endl; + printSegment(segment); + printHe(he);*/ + //Vector_2 start_seg_dir = f_vector(segment.source(),segment.target()); + + + //if (CGAL::angle(start_he_dir,start_seg_dir)==CGAL::ACUTE){ + //if (f_angle(start_he_dir,start_seg_dir)==CGAL::ACUTE){ + + /* + if (CGAL::collinear_are_ordered_along_line(segment.source(),he->source()->point(),he->target()->point())){ + return true;} + */ + + + CGAL::Comparison_result c1 = segment.label()._orientation;//f_compare_endpoints_xy(segment); + //CGAL::Comparison_result c1 = segment.data();//f_compare_endpoints_xy(segment); + CGAL::Comparison_result c2 = (CGAL::Comparison_result)he->direction();//f_compare_xy(he->source()->point(),he->target()->point()); + bool same_dir = (c1 != c2); + + if (same_dir) { + return true; + } + + + } + + return false; + } + + + + bool checkReflex(const Point_2 &prev, const Point_2 &curr, const Point_2 &next) const { + CGAL::Orientation res_ori = f_orientation(prev, curr, next); + //if (f_orientation (prev, curr, next) == COLLINEAR) + + return ((res_ori == RIGHT_TURN) || (res_ori == COLLINEAR)); + } + + /*bool checkSwept(const Point_2& prev,const Point_2& curr,const Point_2& next,const Point_2& start,const Point_2& end) const + { + Direction_2 dir_start = f_direction(f_vector(prev,curr)); + Direction_2 dir_end = f_direction(f_vector(curr,next)); + Direction_2 dir_new = f_direction(f_vector(start,end)); + return (dir_new == dir_start) || f_ccw_in_between(dir_new,dir_start,dir_end) || (dir_end == dir_new); + }*/ + + bool checkSwept(const Point_2 &prev, const Point_2 &curr, const Point_2 &next, const Point_2 &start, const Point_2 &end, bool &isStartConcide, bool &isEndConcide) const { + Direction_2 dir_start = f_direction(f_vector(prev, curr)); + Direction_2 dir_end = f_direction(f_vector(curr, next)); + Direction_2 dir_new = f_direction(f_vector(start, end)); + isStartConcide = dir_new == dir_start; + isEndConcide = dir_end == dir_new; + + return isStartConcide || f_ccw_in_between(dir_new, dir_start, dir_end) || isEndConcide; + } + + bool checkSwept(Direction_2 &dir_start, Direction_2 &dir_end, Direction_2 &dir_new, bool &isStartConcide, bool &isEndConcide) const { + /* Direction_2 dir_start = f_direction(f_vector(prev,curr)); + Direction_2 dir_end = f_direction(f_vector(curr,next)); + Direction_2 dir_new = f_direction(f_vector(start,end));*/ + isStartConcide = dir_new == dir_start; + isEndConcide = dir_end == dir_new; + + return isStartConcide || f_ccw_in_between(dir_new, dir_start, dir_end) || isEndConcide; + } + + void printHe(Halfedge_handle he) const { + //Segment_2 temp = he->curve(); + if (!HE_WRITE) { + return; + } + + Point_2 p_source = he->source()->point(); + Point_2 p_end = he->target()->point(); + double x1 = CGAL::to_double(p_source.x()); + double y1 = CGAL::to_double(p_source.y()); + double x2 = CGAL::to_double(p_end.x()); + double y2 = CGAL::to_double(p_end.y()); + + std::cout << x1 << "," << y1 << "," << x2 << "," << y2 << std::endl; + } + + void printSegment(Segment_2 &seg) const { + //Segment_2 temp = he->curve(); + if (!HE_WRITE) { + return; + } + + Point_2 p_source = seg.source(); + Point_2 p_end = seg.target(); + double x1 = CGAL::to_double(p_source.x()); + double y1 = CGAL::to_double(p_source.y()); + double x2 = CGAL::to_double(p_end.x()); + double y2 = CGAL::to_double(p_end.y()); + + std::cout << x1 << "," << y1 << "," << x2 << "," << y2 << std::endl; + } + + void draw_arr(Arrangement_history_2 &arr) const { + //QColor c(0,255,0); + for (Edge_iterator itr = arr.edges_begin(); itr != arr.edges_end(); ++itr) { + printSegment(itr->curve()); + //global_graphics->draw_edge(itr->curve(),c,true); + + } + + // draw isolated vertices + /* Face_handle unbounded_face = arr.unbounded_face(); + + Hole_iterator hi; + Ccb_halfedge_circulator perimiterFace; + for (hi = unbounded_face->holes_begin(); hi != unbounded_face->holes_end(); ++hi) { + perimiterFace = *hi; + } + hi->*/ + Vertex_iterator vit; + + //QColor c2(0,255,255); + for (vit = arr.vertices_begin(); vit != arr.vertices_end(); ++vit) { + + if (vit->is_isolated()) { + //global_graphics->draw_cross(vit->point(),c2,0.1); + } + + } + + + } + + }; template -Polygon_with_holes_2 -minkowski_sum_2_ (const Polygon_2& pgn1, - const Polygon_2& pgn2) -{ - Minkowski_sum_by_convolution_lien_2 mink_sum; - Polygon_2 sum_bound; - std::list > sum_holes; +Polygon_with_holes_2 +minkowski_sum_2_(const Polygon_2 &pgn1, + const Polygon_2 &pgn2) { + Minkowski_sum_by_convolution_lien_2 mink_sum; + Polygon_2 sum_bound; + std::list > sum_holes; - if (pgn1.size() > pgn2.size()) - mink_sum (pgn1, pgn2, sum_bound, std::back_inserter(sum_holes)); - else - mink_sum (pgn2, pgn1, sum_bound, std::back_inserter(sum_holes)); + if (pgn1.size() > pgn2.size()) { + mink_sum(pgn1, pgn2, sum_bound, std::back_inserter(sum_holes)); + } else { + mink_sum(pgn2, pgn1, sum_bound, std::back_inserter(sum_holes)); + } - return (Polygon_with_holes_2 (sum_bound, - sum_holes.begin(), - sum_holes.end())); + return (Polygon_with_holes_2 (sum_bound, + sum_holes.begin(), + sum_holes.end())); } }; diff --git a/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/NaiveCollisionDetector.h b/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/NaiveCollisionDetector.h index 5c3263961a4..b303411c1aa 100644 --- a/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/NaiveCollisionDetector.h +++ b/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/NaiveCollisionDetector.h @@ -1,60 +1,61 @@ #ifndef NAIVECOLLISIONDETECTOR_HEADER #define NAIVECOLLISIONDETECTOR_HEADER #include "ICollisionDetector.h" -#include +#include #include -template class NaiveCollisionDetector : public ICollisionDetector< Kernel_, Container_> -{ +template class NaiveCollisionDetector : public ICollisionDetector< Kernel_, Container_> { public: - NaiveCollisionDetector(){} + NaiveCollisionDetector() {} typedef CGAL::Polygon_2 Polygon_2; - typedef typename Polygon_2::Edge_const_iterator Edge_iterator ; - typedef typename Polygon_2::Traits::Segment_2 Segment_2 ; - //typedef typename Polygon_2::Vertex_circulator Vertex_circulator; - //typedef typename - virtual bool checkCollision(const Polygon_2& p,const Polygon_2& q) - { - bool intersect = false; - if (CGAL::do_intersect(p,q)) - return true; - else return false; + typedef typename Polygon_2::Edge_const_iterator Edge_iterator ; + typedef typename Polygon_2::Traits::Segment_2 Segment_2 ; + //typedef typename Polygon_2::Vertex_circulator Vertex_circulator; + //typedef typename + virtual bool checkCollision(const Polygon_2 &p, const Polygon_2 &q) { + bool intersect = false; - /* - for (Edge_iterator itr1 = p.edges_begin();itr1!=p.edges_end();++itr1) - { - for (Edge_iterator itr2 = q.edges_begin();itr2!=q.edges_end();++itr2) - { - //intersect = intersect CGAL::Do_intersect(*itr1,*itr2); - CGAL::Object result = CGAL::intersection(*itr1,*itr2); - if (const CGAL::Point_2 *ipoint = CGAL::object_cast >(&result)) { - // handle the point intersection case with *ipoint. - // check if the intersection point is the vertex of one of the edges - if (((*ipoint)==itr1->source()) || ((*ipoint)==itr1->target()) - ||((*ipoint)==itr2->source()) || ((*ipoint)==itr2->target())) - intersect = false; - else - intersect = true; - } else - if (const CGAL::Segment_2 *iseg = CGAL::object_cast >(&result)) { - // handle the segment intersection case with *iseg. this is the case where the edges are touching - intersect = false; - } else { - // handle the no intersection case. - } + if (CGAL::do_intersect(p, q)) { + return true; + } else { + return false; + } - if (intersect) - return intersect; - } + /* + for (Edge_iterator itr1 = p.edges_begin();itr1!=p.edges_end();++itr1) + { + for (Edge_iterator itr2 = q.edges_begin();itr2!=q.edges_end();++itr2) + { + //intersect = intersect CGAL::Do_intersect(*itr1,*itr2); + CGAL::Object result = CGAL::intersection(*itr1,*itr2); + if (const CGAL::Point_2 *ipoint = CGAL::object_cast >(&result)) { + // handle the point intersection case with *ipoint. + // check if the intersection point is the vertex of one of the edges + if (((*ipoint)==itr1->source()) || ((*ipoint)==itr1->target()) + ||((*ipoint)==itr2->source()) || ((*ipoint)==itr2->target())) + intersect = false; + else + intersect = true; + } else + if (const CGAL::Segment_2 *iseg = CGAL::object_cast >(&result)) { + // handle the segment intersection case with *iseg. this is the case where the edges are touching + intersect = false; + } else { + // handle the no intersection case. + } - } + if (intersect) + return intersect; + } - if (p.bounded_side(*q.vertices_begin())== CGAL::ON_BOUNDED_SIDE || q.bounded_side(*p.vertices_begin())== CGAL::ON_BOUNDED_SIDE) - return true; - return intersect; - */ - - } + } + + if (p.bounded_side(*q.vertices_begin())== CGAL::ON_BOUNDED_SIDE || q.bounded_side(*p.vertices_begin())== CGAL::ON_BOUNDED_SIDE) + return true; + return intersect; + */ + + } }; diff --git a/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/SweepCollisionDetection.h b/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/SweepCollisionDetection.h index 07157048b40..dd5edf6f890 100644 --- a/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/SweepCollisionDetection.h +++ b/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/new/SweepCollisionDetection.h @@ -1,7 +1,7 @@ #ifndef SWEEPCOLLISIONDETECTOR_HEADER #define SWEEPCOLLISIONDETECTOR_HEADER #include "ICollisionDetector.h" -#include +#include #include #include @@ -18,651 +18,640 @@ #include #include - /* A simple sweep-line visitor that determines if there are intersections - * in the interiors of the given curve set. - */ -namespace CGAL{ +/* A simple sweep-line visitor that determines if there are intersections +* in the interiors of the given curve set. +*/ +namespace CGAL { - enum Segment_color {MY_RED,MY_BLUE}; - struct Segment_Data{ - Segment_Data(Segment_color color,int min_id,int max_id):_color(color),_min_id(min_id),_max_id(max_id){} - Segment_color _color; - int _min_id,_max_id; - bool operator==(const Segment_Data& rhs) const - { - //return _color == rhs._color; - return (this == &rhs); - } - }; +enum Segment_color {MY_RED, MY_BLUE}; +struct Segment_Data { + Segment_Data(Segment_color color, int min_id, int max_id): _color(color), _min_id(min_id), _max_id(max_id) {} + Segment_color _color; + int _min_id, _max_id; + bool operator==(const Segment_Data &rhs) const { + //return _color == rhs._color; + return (this == &rhs); + } +}; -template class Sweep_line_do_curves_x_visitor_ : public Sweep_line_empty_visitor -{ - typedef Traits_ Traits_2; - typedef Sweep_line_do_curves_x_visitor_ Self; +template class Sweep_line_do_curves_x_visitor_ : public Sweep_line_empty_visitor { + typedef Traits_ Traits_2; + typedef Sweep_line_do_curves_x_visitor_ Self; - typedef typename Traits_2::X_monotone_curve_2 X_monotone_curve_2; - typedef typename Traits_2::Point_2 Point_2; + typedef typename Traits_2::X_monotone_curve_2 X_monotone_curve_2; + typedef typename Traits_2::Point_2 Point_2; - typedef Sweep_line_empty_visitor Base; - typedef typename Base::Event Event; - typedef typename Base::Subcurve Subcurve; - typedef typename Base::Status_line_iterator Status_line_iterator; + typedef Sweep_line_empty_visitor Base; + typedef typename Base::Event Event; + typedef typename Base::Subcurve Subcurve; + typedef typename Base::Status_line_iterator Status_line_iterator; - typedef CGAL::Sweep_line_2 Sweep_line_2; + typedef CGAL::Sweep_line_2 Sweep_line_2; protected: - // Data members: - bool m_found_x; // Have we found an intersection so far. - bool m_had_overlap_no_cross; + // Data members: + bool m_found_x; // Have we found an intersection so far. + bool m_had_overlap_no_cross; public: - Sweep_line_do_curves_x_visitor_() : - m_found_x(false),m_had_overlap_no_cross(false) - {} + Sweep_line_do_curves_x_visitor_() : + m_found_x(false), m_had_overlap_no_cross(false) { + } - template - void sweep(CurveIterator begin, CurveIterator end) - { - std::vector curves_vec; - std::vector points_vec; + template + void sweep(CurveIterator begin, CurveIterator end) { + std::vector curves_vec; + std::vector points_vec; - curves_vec.reserve (std::distance (begin,end)); - make_x_monotone (begin, - end, - std::back_inserter(curves_vec), - std::back_inserter(points_vec), - this-> traits()); - - // Perform the sweep. - Sweep_line_2 *sl = reinterpret_cast (this->sweep_line()); + curves_vec.reserve(std::distance(begin, end)); + make_x_monotone(begin, + end, + std::back_inserter(curves_vec), + std::back_inserter(points_vec), + this-> traits()); - sl->sweep (curves_vec.begin(), - curves_vec.end(), - points_vec.begin(), - points_vec.end()); - } + // Perform the sweep. + Sweep_line_2 *sl = reinterpret_cast(this->sweep_line()); - void update_event (Event* e , - Subcurve* sc1 , - Subcurve* sc2 , - bool is_new ) - { - //m_found_x = true; - } + sl->sweep(curves_vec.begin(), + curves_vec.end(), + points_vec.begin(), + points_vec.end()); + } - void update_event (Event* /* e */, - Subcurve* /* sc1 */) - { - // m_found_x = true; - } + void update_event(Event *e , + Subcurve *sc1 , + Subcurve *sc2 , + bool is_new) { + //m_found_x = true; + } - void update_event (Event* /* e */, - const Point_2& /* end_point */, - const X_monotone_curve_2& /* cv */, - Arr_curve_end /* cv_end */, - bool /* is_new */) - {} + void update_event(Event * /* e */, + Subcurve * /* sc1 */) { + // m_found_x = true; + } - void update_event (Event* /* e */, - const Point_2& /* pt */, - bool /* is_new */) - {} + void update_event(Event * /* e */, + const Point_2 & /* end_point */, + const X_monotone_curve_2 & /* cv */, + Arr_curve_end /* cv_end */, + bool /* is_new */) { + } - template - void sweep_xcurves (XCurveIterator begin, XCurveIterator end) - { - // Perform the sweep. - Sweep_line_2 *sl = reinterpret_cast (this->sweep_line()); + void update_event(Event * /* e */, + const Point_2 & /* pt */, + bool /* is_new */) { + } - sl->sweep(begin, end); - } + template + void sweep_xcurves(XCurveIterator begin, XCurveIterator end) { + // Perform the sweep. + Sweep_line_2 *sl = reinterpret_cast(this->sweep_line()); - void found_overlap (Subcurve* sc1 , - Subcurve* sc2 , - Subcurve* ov_sc ) - { - - if (sc1->last_curve().data().front()._color != sc2->last_curve().data().front()._color) - { - Sweep_line_2* sl = reinterpret_cast (this->sweep_line()); - const Traits_2* traits = sl->traits(); - - typename Traits_2::Compare_endpoints_xy_2 t_compare_endpoints_xy_2_obj = traits->compare_endpoints_xy_2_object(); - CGAL::Comparison_result c1 =t_compare_endpoints_xy_2_obj(sc1->last_curve()); - CGAL::Comparison_result c2 = t_compare_endpoints_xy_2_obj(sc2->last_curve()); - bool same_dir = (c1==c2); - m_found_x = same_dir; - m_had_overlap_no_cross = !same_dir; - } - + sl->sweep(begin, end); + } - //m_found_x = true; - - } + void found_overlap(Subcurve *sc1 , + Subcurve *sc2 , + Subcurve *ov_sc) { - bool after_handle_event (Event* event , - Status_line_iterator iter, - bool flag ) - { - Sweep_line_2 *sl = reinterpret_cast (this->sweep_line()); - if(m_found_x) - { - sl->stop_sweep(); - return true; - } - // check if there was an intersection event: - if (((event->is_intersection() || event->is_weak_intersection() || (event->is_left_end() && event->is_right_end() )))&& (event->number_of_left_curves()+event->number_of_right_curves()==4) ){ - Sweep_line_2* sl = reinterpret_cast (this->sweep_line()); - const Traits_2* traits = sl->traits(); - typename Traits_2::Compare_endpoints_xy_2 t_compare_endpoints_xy_2_obj = traits->compare_endpoints_xy_2_object(); + if (sc1->last_curve().data().front()._color != sc2->last_curve().data().front()._color) { + Sweep_line_2 *sl = reinterpret_cast(this->sweep_line()); + const Traits_2 *traits = sl->traits(); - // get all curves ordered by cyclic order. from left top counter clockwise. - std::list ordered_list; - ordered_list.insert(ordered_list.begin(),event->left_curves_begin(),event->left_curves_end()); - ordered_list.insert(ordered_list.begin(),event->right_curves_rbegin(),event->right_curves_rend()); - - // mark for each edge whether it's incoming or outgoing. - std::vector incoming_edges(ordered_list.size(),false); - typename std::list::iterator itr = ordered_list.begin(); - int i=0; - for (;itr!= ordered_list.end();++itr){ - if (inumber_of_left_curves()) - { - if (t_compare_endpoints_xy_2_obj((*itr)->last_curve())==CGAL::SMALLER) - incoming_edges[i] = true; - } - else - { - if (t_compare_endpoints_xy_2_obj((*itr)->last_curve())==CGAL::LARGER) - incoming_edges[i] = true; - } - ++i; - } - - if (ordered_list.size() == 4) - { // normal intersection case - // check for alterations - typename std::list::iterator itr1,itr2,itr3; - itr1 = ordered_list.begin(); - itr2 = itr1; ++itr2; - itr3 = itr2; ++itr3; - bool c = ((*itr1)->last_curve().data().front()._color != (*itr2)->last_curve().data().front()._color); - if (((*itr1)->last_curve().data().front()._color != (*itr2)->last_curve().data().front()._color) && - ((*itr2)->last_curve().data().front()._color != (*itr3)->last_curve().data().front()._color)) { - // we have alternating edges - m_found_x = true; - sl->stop_sweep(); - return true; - } - else - { // either 1 and 2 are the same or 1 and for are the same colors. - //Subcurve* r1,r2,b1,b2; - if ((*itr1)->last_curve().data().front()._color == (*itr2)->last_curve().data().front()._color){ - // 1==2 - /* std::list::iterator itr =ordered_list.front(); - r1 = itr; r2 = ++itr; b1 = ++itr; b2 = ++itr;*/ - if (incoming_edges[0] || incoming_edges[2] ) - { - m_found_x = true; - sl->stop_sweep(); - return true; - } - }else {// 1 == 4 - /* std::list::iterator itr =ordered_list.front(); - r2 = itr; b1 = ++itr; b2 = ++itr; r1 = ++itr;*/ - if (incoming_edges[1] || incoming_edges[3] ) - { - m_found_x = true; - sl->stop_sweep(); - return true; - } - } + typename Traits_2::Compare_endpoints_xy_2 t_compare_endpoints_xy_2_obj = traits->compare_endpoints_xy_2_object(); + CGAL::Comparison_result c1 = t_compare_endpoints_xy_2_obj(sc1->last_curve()); + CGAL::Comparison_result c2 = t_compare_endpoints_xy_2_obj(sc2->last_curve()); + bool same_dir = (c1 == c2); + m_found_x = same_dir; + m_had_overlap_no_cross = !same_dir; + } - } - } - else - { - // Maybe a bug here when we have 2 overlap not overlapping and two outgoing which cause overlap. - // this case needs to be studied and handled here. - // / - // ---- - // \ - // - /* int k=7; - ++k; - */ - } + //m_found_x = true; - } + } - - return true; - } + bool after_handle_event(Event *event , + Status_line_iterator iter, + bool flag) { + Sweep_line_2 *sl = reinterpret_cast(this->sweep_line()); - bool found_intersection () - { - return (m_found_x); - } + if (m_found_x) { + sl->stop_sweep(); + return true; + } - bool had_overlap_no_cross() - { - return m_had_overlap_no_cross; - } + // check if there was an intersection event: + if (((event->is_intersection() || event->is_weak_intersection() || (event->is_left_end() && event->is_right_end()))) && (event->number_of_left_curves() + event->number_of_right_curves() == 4)) { + Sweep_line_2 *sl = reinterpret_cast(this->sweep_line()); + const Traits_2 *traits = sl->traits(); + typename Traits_2::Compare_endpoints_xy_2 t_compare_endpoints_xy_2_obj = traits->compare_endpoints_xy_2_object(); + + // get all curves ordered by cyclic order. from left top counter clockwise. + std::list ordered_list; + ordered_list.insert(ordered_list.begin(), event->left_curves_begin(), event->left_curves_end()); + ordered_list.insert(ordered_list.begin(), event->right_curves_rbegin(), event->right_curves_rend()); + + // mark for each edge whether it's incoming or outgoing. + std::vector incoming_edges(ordered_list.size(), false); + typename std::list::iterator itr = ordered_list.begin(); + int i = 0; + + for (; itr != ordered_list.end(); ++itr) { + if (i < event->number_of_left_curves()) { + if (t_compare_endpoints_xy_2_obj((*itr)->last_curve()) == CGAL::SMALLER) { + incoming_edges[i] = true; + } + } else { + if (t_compare_endpoints_xy_2_obj((*itr)->last_curve()) == CGAL::LARGER) { + incoming_edges[i] = true; + } + } + + ++i; + } + + if (ordered_list.size() == 4) { + // normal intersection case + // check for alterations + typename std::list::iterator itr1, itr2, itr3; + itr1 = ordered_list.begin(); + itr2 = itr1; + ++itr2; + itr3 = itr2; + ++itr3; + bool c = ((*itr1)->last_curve().data().front()._color != (*itr2)->last_curve().data().front()._color); + + if (((*itr1)->last_curve().data().front()._color != (*itr2)->last_curve().data().front()._color) && + ((*itr2)->last_curve().data().front()._color != (*itr3)->last_curve().data().front()._color)) { + // we have alternating edges + m_found_x = true; + sl->stop_sweep(); + return true; + } else { + // either 1 and 2 are the same or 1 and for are the same colors. + //Subcurve* r1,r2,b1,b2; + if ((*itr1)->last_curve().data().front()._color == (*itr2)->last_curve().data().front()._color) { + // 1==2 + /* std::list::iterator itr =ordered_list.front(); + r1 = itr; r2 = ++itr; b1 = ++itr; b2 = ++itr;*/ + if (incoming_edges[0] || incoming_edges[2]) { + m_found_x = true; + sl->stop_sweep(); + return true; + } + } else {// 1 == 4 + /* std::list::iterator itr =ordered_list.front(); + r2 = itr; b1 = ++itr; b2 = ++itr; r1 = ++itr;*/ + if (incoming_edges[1] || incoming_edges[3]) { + m_found_x = true; + sl->stop_sweep(); + return true; + } + } + + + } + } else { + // Maybe a bug here when we have 2 overlap not overlapping and two outgoing which cause overlap. + // this case needs to be studied and handled here. + // / + // ---- + // \ + // + /* int k=7; + ++k; + */ + } + + } + + + return true; + } + + bool found_intersection() { + return (m_found_x); + } + + bool had_overlap_no_cross() { + return m_had_overlap_no_cross; + } }; -template class Colored_traits : public Arr_consolidated_curve_data_traits_2 -{ - +template class Colored_traits : public Arr_consolidated_curve_data_traits_2 { + public: - typedef Arr_consolidated_curve_data_traits_2 Base; - typedef typename Base::Intersect_2 Base_intersect_2; - //typedef CGAL::Arr_consolidated_curve_data_traits_2 Data_traits_2; - typedef typename Colored_traits::Curve_2 Colored_segment_2; - typedef typename Colored_traits::X_monotone_curve_2 X_monotone_colored_segment_2; - typedef typename Base::Compare_xy_2 Base_compare_xy_2; - typedef typename Base::Construct_min_vertex_2 Base_construct_min_vertex_2; - typedef typename Base::Construct_max_vertex_2 Base_construct_max_vertex_2; - typedef typename Base::Point_2 Base_point_2; + typedef Arr_consolidated_curve_data_traits_2 Base; + typedef typename Base::Intersect_2 Base_intersect_2; + //typedef CGAL::Arr_consolidated_curve_data_traits_2 Data_traits_2; + typedef typename Colored_traits::Curve_2 Colored_segment_2; + typedef typename Colored_traits::X_monotone_curve_2 X_monotone_colored_segment_2; + typedef typename Base::Compare_xy_2 Base_compare_xy_2; + typedef typename Base::Construct_min_vertex_2 Base_construct_min_vertex_2; + typedef typename Base::Construct_max_vertex_2 Base_construct_max_vertex_2; + typedef typename Base::Point_2 Base_point_2; - class Intersect_2 { - protected: - //! The base traits. - const Arr_consolidated_curve_data_traits_2* m_traits; + class Intersect_2 { + protected: + //! The base traits. + const Arr_consolidated_curve_data_traits_2 *m_traits; - /*! Constructor. - * The constructor is declared protected to allow only the functor - * obtaining function, which is a member of the nesting class, - * constructing it. - */ - Intersect_2(const Arr_consolidated_curve_data_traits_2* traits) : m_traits(traits) {} + /*! Constructor. + * The constructor is declared protected to allow only the functor + * obtaining function, which is a member of the nesting class, + * constructing it. + */ + Intersect_2(const Arr_consolidated_curve_data_traits_2 *traits) : m_traits(traits) {} - //! Allow its functor obtaining function calling the protected constructor. - friend class Colored_traits; - - public: - template - OutputIterator operator() (const X_monotone_colored_segment_2 & xcv1, - const X_monotone_colored_segment_2 & xcv2, - OutputIterator oi) - { - // In case the curves originate from the same arrangement, they are - // obviously interior-disjoint. - //if (xcv1.data().front() == xcv2.data().front()) - if (xcv1.data().front()._color == xcv2.data().front()._color) - return (oi); - typename Base::Intersect_2 int_obj = typename Base::Intersect_2(m_traits); - //OutputIterator oi_temp; - OutputIterator oi_end = int_obj(xcv1,xcv2,oi); - if (oi == oi_end) - return oi_end; - const std::pair *xp_point; - for (;oi!=oi_end;++oi) - { - xp_point = object_cast > (&(*oi)); - if (xp_point!=NULL) - { - *oi = CGAL::make_object(std::make_pair (Point_2(xp_point->first), - xp_point->second)); - } - } - - //if (xcv1.color() == RB_OVERLAP || xcv2.color() == RB_OVERLAP) - return (oi); - } - - }; + //! Allow its functor obtaining function calling the protected constructor. + friend class Colored_traits; - /*! Obtain an Intersect_2 functor object. */ - Intersect_2 intersect_2_object () const - { - return Intersect_2(this); - } + public: + template + OutputIterator operator()(const X_monotone_colored_segment_2 &xcv1, + const X_monotone_colored_segment_2 &xcv2, + OutputIterator oi) { + // In case the curves originate from the same arrangement, they are + // obviously interior-disjoint. + //if (xcv1.data().front() == xcv2.data().front()) + if (xcv1.data().front()._color == xcv2.data().front()._color) { + return (oi); + } - class Ex_point_2 - { - public: + typename Base::Intersect_2 int_obj = typename Base::Intersect_2(m_traits); + //OutputIterator oi_temp; + OutputIterator oi_end = int_obj(xcv1, xcv2, oi); - typedef Base_point_2 Base_p; + if (oi == oi_end) { + return oi_end; + } - protected: + const std::pair *xp_point; - Base_p m_base_pt; // The base point. + for (; oi != oi_end; ++oi) { + xp_point = object_cast > (&(*oi)); - public: - int id; - /*! Default constructor. */ - Ex_point_2() : - m_base_pt(),id(-1) + if (xp_point != NULL) { + *oi = CGAL::make_object(std::make_pair(Point_2(xp_point->first), + xp_point->second)); + } + } - {} + //if (xcv1.color() == RB_OVERLAP || xcv2.color() == RB_OVERLAP) + return (oi); + } - /*! Constructor from a base point. */ - Ex_point_2 (const Base_p& pt) : - m_base_pt (pt),id(-1) + }; - {} - - - /*! Get the base point (const version). */ - const Base_p& base () const - { - return (m_base_pt); + /*! Obtain an Intersect_2 functor object. */ + Intersect_2 intersect_2_object() const { + return Intersect_2(this); } - /*! Get the base point (non-const version). */ - Base_p& base () - { - return (m_base_pt); + class Ex_point_2 { + public: + + typedef Base_point_2 Base_p; + + protected: + + Base_p m_base_pt; // The base point. + + public: + int id; + /*! Default constructor. */ + Ex_point_2() : + m_base_pt(), id(-1) + + {} + + /*! Constructor from a base point. */ + Ex_point_2(const Base_p &pt) : + m_base_pt(pt), id(-1) + + {} + + + /*! Get the base point (const version). */ + const Base_p &base() const { + return (m_base_pt); + } + + /*! Get the base point (non-const version). */ + Base_p &base() { + return (m_base_pt); + } + + /*! Casting to a base point (const version). */ + operator const Base_p &() const { + return (m_base_pt); + } + + /*! Casting to a base point (non-const version). */ + operator Base_p &() { + return (m_base_pt); + } + + + }; + + typedef Ex_point_2 Point_2; + + + //class Ex_point_2 : public Point_2 + //{ + //public: + // Ex_point_2(Point_2& p) + // { + + // } + // int id; + //}; + + class Compare_xy_2 { + protected: + //! The base operator. + Base_compare_xy_2 m_base_cmp_xy; + + /*! Constructor. + * The constructor is declared protected to allow only the functor + * obtaining function, which is a member of the nesting class, + * constructing it. + */ + Compare_xy_2(const Base_compare_xy_2 &base) : + m_base_cmp_xy(base) { + } + + //! Allow its functor obtaining function calling the protected constructor. + friend class Colored_traits; + + public: + Comparison_result operator()(const Point_2 &p1, const Point_2 &p2) const { +// if (&p1 == &p2) + //Ex_point_2 p1_e,p2_e; + //p1_e = *dynamic_cast(&p1); + //p2_e = *dynamic_cast(&p2); + if ((p1.id == p2.id) && (p1.id != -1)) { + return EQUAL; + } + + return m_base_cmp_xy(p1, p2); + } + }; + + /*! Obtain a Construct_min_vertex_2 functor object. */ + Compare_xy_2 compare_xy_2_object() const { + //Base::Compare_xy_2 obj(); + return (Compare_xy_2(((Base *)this)->compare_xy_2_object())); } - /*! Casting to a base point (const version). */ - operator const Base_p& () const - { - return (m_base_pt); + + + /*! A functor that obtains the left endpoint of an x-monotone curve. */ + class Construct_min_vertex_2 { + protected: + //! The base operators. + Base_construct_min_vertex_2 m_base_min_v; + //Base_equal_2 m_base_equal; + + /*! Constructor. + * The constructor is declared protected to allow only the functor + * obtaining function, which is a member of the nesting class, + * constructing it. + */ + Construct_min_vertex_2(const Base_construct_min_vertex_2 &base_min_v + ) : + m_base_min_v(base_min_v) { + } + + //! Allow its functor obtaining function calling the protected constructor. + friend class Colored_traits; + typedef typename Colored_traits::X_monotone_curve_2 X_monotone_curve_2; + + public: + Point_2 operator()(const X_monotone_curve_2 &xcv) { + Point_2 min_p = m_base_min_v(xcv); + + if (xcv.data().size() > 1) { + min_p.id = -1; + } else { + min_p.id = xcv.data().front()._min_id; + } + + return (min_p); + } + }; + + /*! Obtain a Construct_min_vertex_2 functor object. */ + Construct_min_vertex_2 construct_min_vertex_2_object() const { + return + (Construct_min_vertex_2(((Base *)this)->construct_min_vertex_2_object())); } - /*! Casting to a base point (non-const version). */ - operator Base_p& () - { - return (m_base_pt); + /*! A functor that obtains the right endpoint of an x-monotone curve. */ + class Construct_max_vertex_2 { + protected: + //! The base operators. + Base_construct_max_vertex_2 m_base_max_v; + + + /*! Constructor. + * The constructor is declared protected to allow only the functor + * obtaining function, which is a member of the nesting class, + * constructing it. + */ + Construct_max_vertex_2(const Base_construct_max_vertex_2 &base_max_v) : + m_base_max_v(base_max_v) + + {} + + //! Allow its functor obtaining function calling the protected constructor. + friend class Colored_traits; + typedef typename Colored_traits::X_monotone_curve_2 X_monotone_curve_2; + + public: + Point_2 operator()(const X_monotone_curve_2 &xcv) const { + Point_2 max_p = m_base_max_v(xcv); + + if (xcv.data().size() > 1) { + max_p.id = -1; + } else { + max_p.id = xcv.data().front()._max_id; + } + + return (max_p); + } + }; + + /*! Obtain a Construct_min_vertex_2 functor object. */ + Construct_max_vertex_2 construct_max_vertex_2_object() const { + return + (Construct_max_vertex_2(((Base *)this)->construct_max_vertex_2_object())); } - - }; - - typedef Ex_point_2 Point_2; - - - //class Ex_point_2 : public Point_2 - //{ - //public: - // Ex_point_2(Point_2& p) - // { - - // } - // int id; - //}; - - class Compare_xy_2 { - protected: - //! The base operator. - Base_compare_xy_2 m_base_cmp_xy; - - /*! Constructor. - * The constructor is declared protected to allow only the functor - * obtaining function, which is a member of the nesting class, - * constructing it. - */ - Compare_xy_2(const Base_compare_xy_2& base) : - m_base_cmp_xy(base) - {} - - //! Allow its functor obtaining function calling the protected constructor. - friend class Colored_traits; - - public: - Comparison_result operator() (const Point_2& p1, const Point_2& p2) const - { -// if (&p1 == &p2) - //Ex_point_2 p1_e,p2_e; - //p1_e = *dynamic_cast(&p1); - //p2_e = *dynamic_cast(&p2); - if ((p1.id == p2.id) && (p1.id != -1)) - return EQUAL; - - return m_base_cmp_xy(p1,p2); - } - }; - - /*! Obtain a Construct_min_vertex_2 functor object. */ - Compare_xy_2 compare_xy_2_object () const - { - //Base::Compare_xy_2 obj(); - return (Compare_xy_2(((Base*)this)->compare_xy_2_object())); - } - - - - /*! A functor that obtains the left endpoint of an x-monotone curve. */ - class Construct_min_vertex_2 { - protected: - //! The base operators. - Base_construct_min_vertex_2 m_base_min_v; - //Base_equal_2 m_base_equal; - - /*! Constructor. - * The constructor is declared protected to allow only the functor - * obtaining function, which is a member of the nesting class, - * constructing it. - */ - Construct_min_vertex_2 (const Base_construct_min_vertex_2& base_min_v - ) : - m_base_min_v (base_min_v) - {} - - //! Allow its functor obtaining function calling the protected constructor. - friend class Colored_traits; - typedef typename Colored_traits::X_monotone_curve_2 X_monotone_curve_2; - - public: - Point_2 operator() (const X_monotone_curve_2& xcv) - { - Point_2 min_p = m_base_min_v (xcv); - if (xcv.data().size()>1) - min_p.id = -1; - else - min_p.id = xcv.data().front()._min_id; - return (min_p); - } - }; - - /*! Obtain a Construct_min_vertex_2 functor object. */ - Construct_min_vertex_2 construct_min_vertex_2_object () const - { - return - (Construct_min_vertex_2 (((Base*)this)->construct_min_vertex_2_object())); - } - - /*! A functor that obtains the right endpoint of an x-monotone curve. */ - class Construct_max_vertex_2 { - protected: - //! The base operators. - Base_construct_max_vertex_2 m_base_max_v; - - - /*! Constructor. - * The constructor is declared protected to allow only the functor - * obtaining function, which is a member of the nesting class, - * constructing it. - */ - Construct_max_vertex_2 (const Base_construct_max_vertex_2& base_max_v) : - m_base_max_v (base_max_v) - - {} - - //! Allow its functor obtaining function calling the protected constructor. - friend class Colored_traits; - typedef typename Colored_traits::X_monotone_curve_2 X_monotone_curve_2; - - public: - Point_2 operator() (const X_monotone_curve_2 & xcv) const - { - Point_2 max_p = m_base_max_v (xcv); - if (xcv.data().size()>1) - max_p.id = -1; - else - max_p.id = xcv.data().front()._max_id; - return (max_p); - } - }; - - /*! Obtain a Construct_min_vertex_2 functor object. */ - Construct_max_vertex_2 construct_max_vertex_2_object () const - { - return - (Construct_max_vertex_2 (((Base*)this)->construct_max_vertex_2_object())); - } - }; -template class SweepCollisionDetector : public ICollisionDetector< Kernel_, Container_> -{ +template class SweepCollisionDetector : public ICollisionDetector< Kernel_, Container_> { + - public: - SweepCollisionDetector(){} - //typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; - typedef CGAL::Arr_segment_traits_2 Traits_2; - typedef Colored_traits Data_traits_2; - //typedef CGAL::Arr_consolidated_curve_data_traits_2 Data_traits_2; + SweepCollisionDetector() {} + //typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; + typedef CGAL::Arr_segment_traits_2 Traits_2; + typedef Colored_traits Data_traits_2; + //typedef CGAL::Arr_consolidated_curve_data_traits_2 Data_traits_2; - typedef typename Data_traits_2::Curve_2 Colored_segment_2; - typedef Arrangement_2 Colored_arr_2; - typedef typename CGAL::Polygon_2::Edge_const_iterator Edge_iterator ; - typedef typename CGAL::Polygon_2::Traits::Segment_2 Segment_2 ; - //typedef typename Polygon_2::Vertex_circulator Vertex_circulator; - //typedef typename + typedef typename Data_traits_2::Curve_2 Colored_segment_2; + typedef Arrangement_2 Colored_arr_2; + typedef typename CGAL::Polygon_2::Edge_const_iterator Edge_iterator ; + typedef typename CGAL::Polygon_2::Traits::Segment_2 Segment_2 ; + //typedef typename Polygon_2::Vertex_circulator Vertex_circulator; + //typedef typename - protected: - Traits_2 m_traits; +protected: + Traits_2 m_traits; public: - virtual bool checkCollision(const typename CGAL::Polygon_2& p,const typename CGAL::Polygon_2& q) - { - typename Traits_2::Compare_endpoints_xy_2 cmp_obj = m_traits.compare_endpoints_xy_2_object(); - if (p.has_on_bounded_side(*(q.vertices_begin())) || q.has_on_bounded_side(*(p.vertices_begin()))) - return true; + virtual bool checkCollision(const typename CGAL::Polygon_2 &p, const typename CGAL::Polygon_2 &q) { + typename Traits_2::Compare_endpoints_xy_2 cmp_obj = m_traits.compare_endpoints_xy_2_object(); - //std::list edges(p.edges_begin(),p.edges_end()); - std::list edges; - Edge_iterator itr = p.edges_begin(); - int i=0; - int n = p.size(); - for (;itr!=p.edges_end();++itr,++i) - { - //Traits_2:: - - //CGAL::Comparison_result res = CGAL::compare((itr)->source(),(itr)->target()); - CGAL::Comparison_result res = cmp_obj(*itr); - - if (res != CGAL::SMALLER) - { - if (i==n-1) - edges.push_back(Colored_segment_2(*itr,Segment_Data(MY_RED,0,i))); - else - edges.push_back(Colored_segment_2(*itr,Segment_Data(MY_RED,i+1,i))); - } - else - { - if (i==n-1) - edges.push_back(Colored_segment_2(*itr,Segment_Data(MY_RED,i,0))); - else - edges.push_back(Colored_segment_2(*itr,Segment_Data(MY_RED,i,i+1))); - } + if (p.has_on_bounded_side(*(q.vertices_begin())) || q.has_on_bounded_side(*(p.vertices_begin()))) { + return true; + } - } - itr = q.edges_begin(); - n= q.size(); - int j=0; - int q_first = i; - for (;itr!=q.edges_end();++itr,++i,++j) - { - //CGAL::Comparison_result res = CGAL::compare((itr)->source(),(itr)->target()); - CGAL::Comparison_result res = cmp_obj(*itr); - - if (res != CGAL::SMALLER) - { - if (j==n-1) - edges.push_back(Colored_segment_2(*itr,Segment_Data(MY_BLUE,q_first,i))); - else - edges.push_back(Colored_segment_2(*itr,Segment_Data(MY_BLUE,i+1,i))); - } - else - { - if (j==n-1) - edges.push_back(Colored_segment_2(*itr,Segment_Data(MY_BLUE,i,q_first))); - else - edges.push_back(Colored_segment_2(*itr,Segment_Data(MY_BLUE,i,i+1))); - } - + //std::list edges(p.edges_begin(),p.edges_end()); + std::list edges; + Edge_iterator itr = p.edges_begin(); + int i = 0; + int n = p.size(); - //edges.push_back(Colored_segment_2(*itr,Segment_Data(MY_BLUE,2*i,2*i+1))); - } + for (; itr != p.edges_end(); ++itr, ++i) { + //Traits_2:: - //edges.insert(edges.begin(),q.edges_begin(),q.edges_end()); - CGAL::Sweep_line_do_curves_x_visitor_ visitor; - Sweep_line_2 > sweep_line(&visitor); - visitor.attach((void*)&sweep_line); - visitor.sweep(edges.begin(),edges.end()); - if (visitor.found_intersection()) - return true; + //CGAL::Comparison_result res = CGAL::compare((itr)->source(),(itr)->target()); + CGAL::Comparison_result res = cmp_obj(*itr); - if (visitor.had_overlap_no_cross()) - return false; + if (res != CGAL::SMALLER) { + if (i == n - 1) { + edges.push_back(Colored_segment_2(*itr, Segment_Data(MY_RED, 0, i))); + } else { + edges.push_back(Colored_segment_2(*itr, Segment_Data(MY_RED, i + 1, i))); + } + } else { + if (i == n - 1) { + edges.push_back(Colored_segment_2(*itr, Segment_Data(MY_RED, i, 0))); + } else { + edges.push_back(Colored_segment_2(*itr, Segment_Data(MY_RED, i, i + 1))); + } + } - //else - //{ - // - // //if (CGAL::do_intersect(p,q)) - // // return true; - // //else return false; - // - //} - return false; - /*bool intersect = false; - if (CGAL::do_intersect(p,q)) - return true; - else return false;*/ + } - /* - for (Edge_iterator itr1 = p.edges_begin();itr1!=p.edges_end();++itr1) - { - for (Edge_iterator itr2 = q.edges_begin();itr2!=q.edges_end();++itr2) - { - //intersect = intersect CGAL::Do_intersect(*itr1,*itr2); - CGAL::Object result = CGAL::intersection(*itr1,*itr2); - if (const CGAL::Point_2 *ipoint = CGAL::object_cast >(&result)) { - // handle the point intersection case with *ipoint. - // check if the intersection point is the vertex of one of the edges - if (((*ipoint)==itr1->source()) || ((*ipoint)==itr1->target()) - ||((*ipoint)==itr2->source()) || ((*ipoint)==itr2->target())) - intersect = false; - else - intersect = true; - } else - if (const CGAL::Segment_2 *iseg = CGAL::object_cast >(&result)) { - // handle the segment intersection case with *iseg. this is the case where the edges are touching - intersect = false; - } else { - // handle the no intersection case. - } + itr = q.edges_begin(); + n = q.size(); + int j = 0; + int q_first = i; - if (intersect) - return intersect; - } + for (; itr != q.edges_end(); ++itr, ++i, ++j) { + //CGAL::Comparison_result res = CGAL::compare((itr)->source(),(itr)->target()); + CGAL::Comparison_result res = cmp_obj(*itr); - } + if (res != CGAL::SMALLER) { + if (j == n - 1) { + edges.push_back(Colored_segment_2(*itr, Segment_Data(MY_BLUE, q_first, i))); + } else { + edges.push_back(Colored_segment_2(*itr, Segment_Data(MY_BLUE, i + 1, i))); + } + } else { + if (j == n - 1) { + edges.push_back(Colored_segment_2(*itr, Segment_Data(MY_BLUE, i, q_first))); + } else { + edges.push_back(Colored_segment_2(*itr, Segment_Data(MY_BLUE, i, i + 1))); + } + } + + + //edges.push_back(Colored_segment_2(*itr,Segment_Data(MY_BLUE,2*i,2*i+1))); + } + + //edges.insert(edges.begin(),q.edges_begin(),q.edges_end()); + CGAL::Sweep_line_do_curves_x_visitor_ visitor; + Sweep_line_2 > sweep_line(&visitor); + visitor.attach((void *)&sweep_line); + visitor.sweep(edges.begin(), edges.end()); + + if (visitor.found_intersection()) { + return true; + } + + if (visitor.had_overlap_no_cross()) { + return false; + } + + //else + //{ + // + // //if (CGAL::do_intersect(p,q)) + // // return true; + // //else return false; + // + //} + return false; + /*bool intersect = false; + if (CGAL::do_intersect(p,q)) + return true; + else return false;*/ + + /* + for (Edge_iterator itr1 = p.edges_begin();itr1!=p.edges_end();++itr1) + { + for (Edge_iterator itr2 = q.edges_begin();itr2!=q.edges_end();++itr2) + { + //intersect = intersect CGAL::Do_intersect(*itr1,*itr2); + CGAL::Object result = CGAL::intersection(*itr1,*itr2); + if (const CGAL::Point_2 *ipoint = CGAL::object_cast >(&result)) { + // handle the point intersection case with *ipoint. + // check if the intersection point is the vertex of one of the edges + if (((*ipoint)==itr1->source()) || ((*ipoint)==itr1->target()) + ||((*ipoint)==itr2->source()) || ((*ipoint)==itr2->target())) + intersect = false; + else + intersect = true; + } else + if (const CGAL::Segment_2 *iseg = CGAL::object_cast >(&result)) { + // handle the segment intersection case with *iseg. this is the case where the edges are touching + intersect = false; + } else { + // handle the no intersection case. + } + + if (intersect) + return intersect; + } + + } + + if (p.bounded_side(*q.vertices_begin())== CGAL::ON_BOUNDED_SIDE || q.bounded_side(*p.vertices_begin())== CGAL::ON_BOUNDED_SIDE) + return true; + return intersect; + */ + + } - if (p.bounded_side(*q.vertices_begin())== CGAL::ON_BOUNDED_SIDE || q.bounded_side(*p.vertices_begin())== CGAL::ON_BOUNDED_SIDE) - return true; - return intersect; - */ - - } - };