// ============================================================================ // // Copyright (c) 2000 The CGAL Consortium // // This software and related documentation is part of an INTERNAL release // of the Computational Geometry Algorithms Library (CGAL). It is not // intended for general use. // // ---------------------------------------------------------------------------- // // release : $CGAL_Revision $ // release_date : $CGAL_Date $ // // file : include/CGAL/Simplicity_sweep_2.h // package : $CGAL_Package: Generator 2.12 (28 Jul 1999) $ // chapter : Geometric Object Generators // // revision : $Revision$ // revision_date : $Date$ // // author(s) : Susan Hert // // coordinator : ETH Zurich (Bernd Gaertner ) // // implementation: Simplicity Sweep for generating random simple polygons // ============================================================================ #ifndef CGAL_SIMPLICITY_SWEEP_2_H #define CGAL_SIMPLICITY_SWEEP_2_H #include #include #include #include namespace CGAL { template class Simplicity_test_2; } #include #include #include namespace CGAL { //-----------------------------------------------------------------------// // Simplicity_sweep_2 //-----------------------------------------------------------------------// template class Simplicity_sweep_2 : public Simplicity_test_2 { typedef Simplicity_test_2 Simplicity_test; public: Simplicity_sweep_2(const Traits& tr): Simplicity_test(tr) {} bool sweep(ForwardIterator first, ForwardIterator last, std::pair& reverse_range); // tests if the polygon with points in the range [first,last) is simple // and, if not, returns a pair of iterators that correspond to endpoints // of a randomly chosen pair of intersecting edges. The vertices spanned // by this range of iterators should be reversed to eliminate the // intersection. }; // returns true if a change was made during the sweep (so the polygon // was not simple) and false otherwise (indicating a simple polygon) template bool Simplicity_sweep_2::sweep( ForwardIterator first, ForwardIterator last, std::pair& reverse_range) { int n = 0; std::vector< std::pair > intersections; typename Simplicity_test::EventQueue events(this); d_index.clear(); while (first != last) { d_index.push_back(first); events.insert(n++); ++first; } if (n < 3) return false; typename Simplicity_test::SweepStatus status(this,n); while (!events.empty()) { int i = events.pop(); d_eventpoint = i; int prev = (i>0) ? i-1 : i-1+n; int next = (i= 0) && (EdgesDoIntersect(left,e))) { assert(left != e); intersections.push_back(std::pair(left,e)); } int right = status.right(e); if ((right >= 0) && (EdgesDoIntersect(e,right))) { assert(e != right); intersections.push_back(std::pair(e,right)); } } else if (prev_less_than_i) { int e1 = prev; int e2 = i; status.insert(e1); status.insert(e2); CGAL_polygon_assertion(status.is_valid()); // check for intersections of newly inserted edges e1 and e2 with // neighbors int left, right; left = status.left(e1); if ((left >= 0) && (EdgesDoIntersect(left,e1))) { assert(left != e1); intersections.push_back(std::pair(left,e1)); } right = status.right(e1); if ((right >= 0) && (EdgesDoIntersect(e1,right))) { assert(e1 != right); intersections.push_back(std::pair(e1,right)); } left = status.left(e2); if ((left >= 0) && (left != e1) && (EdgesDoIntersect(left,e2))) { assert(left != e2); intersections.push_back(std::pair(left,e2)); } right = status.right(e2); if ((right >= 0) && (right != e1) && (EdgesDoIntersect(e2,right))) { assert(e2 != right); intersections.push_back(std::pair(e2,right)); } } else { if (status.left(prev) == i) { int left = status.left(i); int right = status.right(prev); status.erase(prev); status.erase(i); if (left >=0 && right >=0 && EdgesDoIntersect(left, right)) { assert(left != right); intersections.push_back(std::pair(left, right)); } } else if (status.left(i) == prev) { int left = status.left(prev); int right = status.right(i); status.erase(prev); status.erase(i); if (left >=0 && right >=0 && EdgesDoIntersect(left, right)) { assert(left != right); intersections.push_back(std::pair(left, right)); } } else { int left1 = status.left(i); int right1 = status.right(i); status.erase(i); if (left1 >=0 && right1 >=0 && EdgesDoIntersect(left1, right1)) { assert(left1 != right1); intersections.push_back(std::pair(left1, right1)); } int left2 = status.left(prev); int right2 = status.right(prev); status.erase(prev); if (left2 >=0 && right2 >=0 && EdgesDoIntersect(left2, right2)) { assert(left2 != right2); intersections.push_back(std::pair(left2, right2)); } } CGAL_polygon_assertion(status.is_valid()); } } if (intersections.empty()) { return false; } else { int i = CGAL::Random().get_int(0,intersections.size()); if (intersections[i].first < intersections[i].second) { reverse_range.first = d_index[intersections[i].first]; reverse_range.first++; // must be possible since second is larger reverse_range.second = d_index[intersections[i].second]; } else { reverse_range.first = d_index[intersections[i].second]; reverse_range.first++; // must be possible since first is larger reverse_range.second = d_index[intersections[i].first]; } return true; } } } #endif // CGAL_SIMPLICITY_SWEEP_2_H