// ====================================================================== // // Copyright (c) 1997 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 : // release_date : 1999, October 01 // // file : include/CGAL/intersecting_polygons.h // package : bops (2.2) // source : include/CGAL/intersecting_polygons.h // revision : $Revision$ // revision_date : $Date$ // author(s) : Carl Van Geem // // coordinator : RISC Linz // (Wolfgang Freiseisen ) // // // ====================================================================== #ifndef CGAL_INTERSECTING_POLYGONS_H #define CGAL_INTERSECTING_POLYGONS_H #include #include #ifndef CGAL_POINT_2_H #include #endif #ifndef CGAL_SEGMENT_2_H #include #endif #ifndef CGAL_POLYGON_2_H #include #endif #include #ifndef CGAL_NSQUARE_INTERSECTING_H #include #endif CGAL_BEGIN_NAMESPACE struct _intersecting_polygons_myhelpelement { int _endpointleft; int _endpointright; std::list _cutpoints; }; template < class R, class Container > class _intersecting_polygons { public: typedef Polygon_2, Container> Polygon; typedef typename Polygon::Vertex_const_iterator Polygon_vertex_const_iterator; typedef std::list > Intersectionresult; typedef typename Intersectionresult::const_iterator Intersectionresult_iterator; typedef Point_2 Point; typedef Segment_2 Segment; typedef std::vector Point_list; typedef typename Point_list::iterator Point_list_iterator; typedef std::list< std::pair > Edge_list; typedef typename Edge_list::iterator Edge_list_iterator; private: Polygon _polyA, _polyB; Intersectionresult _intersection_result; public: _intersecting_polygons () {} _intersecting_polygons (const Polygon& pA, const Polygon& pB) { nsquareintersection nsquareintersection; _intersection_result=nsquareintersection(pA.edges_begin(), pA.edges_end(), pB.edges_begin(), pB.edges_end()); _polyA = pA; _polyB = pB; } ~_intersecting_polygons() {} Polygon A() const { return _polyA;} Polygon B() const { return _polyB;} Intersectionresult intersection_result() const { return _intersection_result; } int size() const { return _intersection_result.size(); } void get_graph_information(Point_list& a_ptlst, Edge_list& an_edlst){ get_graph_information_code(_intersection_result, _polyA, _polyB, a_ptlst, an_edlst); } std::list > get_color_informationA() { return get_color_information_code( _intersection_result, _polyA, 1); } std::list > get_color_informationB() { return get_color_information_code( _intersection_result, _polyB, 2); } protected: void get_graph_information_code( const Intersectionresult& lresult, const Polygon& polyA, const Polygon& polyB, Point_list& ptlst, Edge_list& edlst) { /* built up the graph (step 2 in README) */ typedef _intersecting_polygons_myhelpelement myhelpelement; std::list myhelpstructure; myhelpelement edgetosplitel ; Intersectionresult_iterator lrit; Point pt; Segment sm; Segment edgetosplit; Point_list_iterator ptlstit, ptlstit2; std::pair apair; std::pair newpair; Edge_list_iterator edlstit, edlstit2, tobeerased; int asize; Polygon_vertex_const_iterator ait; int minnr; int maxnr; int i; int j; int pointnr = 0; int count = 0; int sourceofedge = 0; int targetofedge = 0; int firstbpoint = 0; int nrofvertices = 0; bool inlist; bool inedgelist; bool added; std::list edgestosplitlst; std::list::iterator splitit; std::list::iterator intit, intit2; /* put vertices of A in, add all segments of A (step A in README) */ asize = polyA.size(); i=0; for (ait = polyA.vertices_begin(); ait != polyA.vertices_end(); ait++) { ptlst.push_back(*ait); sourceofedge = i; targetofedge = (i+1)%asize; if (sourceofedge < targetofedge) edlst.push_back( std::make_pair(sourceofedge, targetofedge)); else edlst.push_back( std::make_pair(targetofedge, sourceofedge)); i++; } /* put vertices of B in, except those that are already there, add all segments of B (step B in README) */ //bsize = polyB.size(); i=0; for (ait = polyB.vertices_begin(); ait != polyB.vertices_end(); ait++) {/* check whether or not polyB[i] is in the list */ ptlstit = ptlst.begin(); inlist = false; sourceofedge = targetofedge; for (j=0; j 1) { #ifdef CGAL__INTERSECTING_POLYGONS_DEBUG_ON /* test:*/ cout << "1: geometrical error, too many segments" << endl; #endif /* end test */ } else { edgetosplit = *((*lrit).segments_poly1()).begin(); ptlstit2 = ptlst.begin(); for (i=0; i 1) { #ifdef CGAL__INTERSECTING_POLYGONS_DEBUG_ON /* test:*/ cout << "2: geometrical error, too many segments" << endl; #endif /* end test */ } else { ptlstit2 = ptlst.begin(); edgetosplit = *(((*lrit).segments_poly2()).begin()); for (i=0; i< nrofvertices; i++) { if (edgetosplit.min() == *ptlstit2) { minnr = i; } if (edgetosplit.max() == *ptlstit2) { maxnr = i; } ptlstit2++; } /* add the edge to the list of edges which have to be split */ added = false; for(splitit=edgestosplitlst.begin(); (!added) && ( splitit!=edgestosplitlst.end()); splitit++ ) { if ( ((*splitit)._endpointleft == minnr) &&((*splitit)._endpointright == maxnr) ) { /*2*/ intit = (*splitit)._cutpoints.begin(); while ( (intit!= (*splitit)._cutpoints.end()) && (compare_lexicographically_xy( ptlst[(*intit)], ptlst[pointnr]) == SMALLER)) { intit++; } (*splitit)._cutpoints.insert(intit,1,pointnr); #ifdef CGAL__INTERSECTING_POLYGONS_DEBUG_ON /* test: */ cout << "added:" << pointnr; cout << "to:" << minnr << "," << maxnr << endl; #endif /* end test */ added = true; } } if (!added) { edgetosplitel._endpointleft = minnr; edgetosplitel._endpointright = maxnr; edgetosplitel._cutpoints.push_back(pointnr); edgestosplitlst.push_back(edgetosplitel); added = true; edgetosplitel._cutpoints.pop_back(); #ifdef CGAL__INTERSECTING_POLYGONS_DEBUG_ON /* test: */ cout << "added:" << pointnr; cout << "to:" << minnr << "," << maxnr << endl; #endif /* end test */ } } } } } /* cut some segments into pieces now: (step D in README) */ #ifdef CGAL__INTERSECTING_POLYGONS_DEBUG_ON /* test: */ for(splitit=edgestosplitlst.begin(); splitit!=edgestosplitlst.end(); splitit++ ) { cout << "edge: " << (*splitit)._endpointleft << "'" << (*splitit)._endpointright << endl; cout << "its cutpoints: "; for (intit = ((*splitit)._cutpoints).begin(); intit != ((*splitit)._cutpoints).end(); intit++) cout << (*intit) << "," << endl; cout << "." << endl; } #endif /* end test */ /* go through edgestosplitlst */ for(splitit=edgestosplitlst.begin(); splitit!=edgestosplitlst.end(); splitit++ ) { /* for each edge (a,b,...) in that list, look for edge (a,b) and cut it into pieces */ if ((*splitit)._endpointleft < (*splitit)._endpointright) apair = std::make_pair((*splitit)._endpointleft,(*splitit)._endpointright); else apair = std::make_pair((*splitit)._endpointright,(*splitit)._endpointleft); edlstit= edlst.begin(); while(edlstit!= edlst.end()) { if ((*edlstit)==apair) { tobeerased = edlstit; edlstit++; #ifdef CGAL__INTERSECTING_POLYGONS_DEBUG_ON /*test */ cout << "added also:" << (*splitit)._endpointleft << "," << (*splitit)._endpointright << endl; #endif /* end test */ ((*splitit)._cutpoints).push_front((*splitit)._endpointleft); ((*splitit)._cutpoints).push_back((*splitit)._endpointright); if (((*splitit)._cutpoints).size() != 0) { #ifdef CGAL__INTERSECTING_POLYGONS_DEBUG_ON /* test: */ cout << apair.first << "," << apair.second << "boe: " << ((*splitit)._cutpoints).size() << endl; #endif /* end test */ intit = ((*splitit)._cutpoints).begin(); intit2 = --((*splitit)._cutpoints).end(); while(intit != intit2) { sourceofedge = *intit ; targetofedge = *++intit ; if (sourceofedge < targetofedge) newpair = std::make_pair(sourceofedge,targetofedge); else newpair = std::make_pair(targetofedge,sourceofedge); #ifdef CGAL__INTERSECTING_POLYGONS_DEBUG_ON /* test: */ cout << newpair.first << "," << newpair.second << endl; #endif /* end test */ /* pair already in the list? */ inlist = false; for(edlstit2=edlst.begin(); edlstit2!=edlst.end(); edlstit2++) inlist = inlist || ((*edlstit2) == newpair); if (!inlist) edlst.push_back(newpair); } } edlst.erase(tobeerased); } else edlstit++; } } #ifdef CGAL__INTERSECTING_POLYGONS_DEBUG_ON /*test */ int k=0; for(ptlstit = ptlst.begin();ptlstit != ptlst.end(); ptlstit++) cout << "ptlst[" << k++ << "] = " << (*ptlstit).x() << "," << (*ptlstit).y() << endl; k=0; for(edlstit = edlst.begin();edlstit != edlst.end(); edlstit++) cout << "edlst[" << k++ << "] = " << (*edlstit).first << "," << (*edlstit).second << endl; #endif /* end test */ } std::list > get_color_information_code( const Intersectionresult& lresult, const Polygon& polyA, int nr_of_poly ){ bool added; Intersectionresult_iterator lrit; Point pt, edgevertex1, edgevertex2; std::list pts_on_A; std::list::iterator end1, end2; /* put vertices of A in */ std::copy(polyA.vertices_begin(), polyA.vertices_end(), std::back_inserter(pts_on_A)); pts_on_A.push_back(*(polyA.vertices_begin())); /* add intersection points */ for (lrit = lresult.begin(); lrit != lresult.end(); lrit++) { if(assign(pt, (*lrit).intersection_object())) { /* IT'S A POINT ! */ /* treat poly1, i.e. A */ if (( (nr_of_poly == 1) && !((*lrit).is_vertex_of_poly1() )) || ( (nr_of_poly == 2) && !((*lrit).is_vertex_of_poly2() )) ) { if ( (*lrit).segments_poly1().size() > 1) { #ifdef CGAL__INTERSECTING_POLYGONS_DEBUG_ON /* test:*/ cout << "3: geometrical error, too many segments" << endl; #endif /* end test */ } else { if (nr_of_poly == 1) { edgevertex1= (*((*lrit).segments_poly1()).begin()).source(); edgevertex2= (*((*lrit).segments_poly1()).begin()).target(); } else { edgevertex1= (*((*lrit).segments_poly2()).begin()).source(); edgevertex2= (*((*lrit).segments_poly2()).begin()).target(); } /* look for vertices in the list of A and add intersection point in between */ /* if source and target are not consecutive entries in the list, then we have to work harder: collinear_between or so */ end1 = std::find(pts_on_A.begin(),pts_on_A.end(),edgevertex1); end2 = end1; end2++; #ifdef CGAL__INTERSECTING_POLYGONS_DEBUG_ON /* test */ cout << "end1 enzo" << endl; std::list >::iterator pts_on_A_it; for (pts_on_A_it =pts_on_A.begin() ; pts_on_A_it !=pts_on_A.end();pts_on_A_it++) cout << "(" << (*pts_on_A_it).x() << "," << (*pts_on_A_it).y() << "),"; cout << endl; cout << "end1 =" << (*end1).x() << "," << (*end1).y() << endl; cout << "end2 =" << (*end2).x() << "," << (*end2).y() << endl; cout << "edgevertex1 =" << edgevertex1.x() << "," << edgevertex1.y() << endl; cout << "edgevertex2 =" << edgevertex2.x() << "," << edgevertex2.y() << endl; cout << "pt = " << pt.x() << "," << pt.y() << endl; #endif /* end test */ if((*end2) == edgevertex2) pts_on_A.insert(end2,1,pt); else { added = false; while( (!added) && ((*end1)!=edgevertex2) ) { if (collinear_are_ordered_along_line((*end1),pt,(*end2))) { pts_on_A.insert(end2,1,pt); added = true; } else { end1++; end2++; } } #ifdef CGAL__INTERSECTING_POLYGONS_DEBUG_ON /* test:*/ if (!added) cout << "error: intersection point not inserted" << " in color list for A" << endl; #endif /* end test */ } } } } } #ifdef CGAL__INTERSECTING_POLYGONS_DEBUG_ON /* test of step PI*/ cout << "the vectors for dcel.color: " << endl; int i=0; for (end1 = pts_on_A.begin(); end1 != pts_on_A.end(); end1++) cout << "A["<< i++ << "]=" << (*end1).x() << "," << (*end1).y() << endl; #endif /* end of test*/ if(pts_on_A.size() > 0) pts_on_A.pop_back(); return pts_on_A; } }; CGAL_END_NAMESPACE #ifdef CGAL_CFG_NO_AUTOMATIC_TEMPLATE_INCLUSION #endif #endif // CGAL_INTERSECTING_POLYGONS_H