/// Returns true if the segment crosses a boundary line of the polygon. /// It is not enough for the segment to simply intersect the boundary /// line -- it must cross it such that the segment extends to both inside /// and outside of the boundary of the polygon. bool intersects_proper(const Segment_2& segment, const Polygon_2& polygon) { static log4cplus::Logger logger = log4cplus::Logger::getInstance("tiler.intersects_proper"); Point_2 seg_pts[] = { segment.source(), segment.target() }; // Get intersection points between segment and polygon LOG4CPLUS_TRACE(logger, "Doing a line sweep: " << pp(segment)); list<Segment_2> segments(polygon.edges_begin(), polygon.edges_end()); segments.push_back(segment); list<Point_2> points; get_intersection_points(segments.begin(), segments.end(), back_inserter(points), true, false); CGAL::Bounded_side side1 = polygon.bounded_side(seg_pts[0]); CGAL::Bounded_side side2 = polygon.bounded_side(seg_pts[1]); LOG4CPLUS_TRACE(logger, "Checking with cross checker"); if (points.size() == 0) return false; Cross_checker checker; checker.add(side1); checker.add(side2); if (checker.crosses()) return true; if (points.size() == 1) return false; points.push_back(seg_pts[0]); points.push_back(seg_pts[1]); points.sort(); list<Point_2>::iterator it0 = points.begin(); list<Point_2>::iterator it1 = it0; ++it1; while (it1 != points.end()) { const Point_2& p0 = *it0; const Point_2& p1 = *it1; // find an intermediate point and test for where it is Point_2 midpoint((p0.x()+p1.x())/2.0, (p0.y()+p1.y())/2.0); checker.add(polygon.bounded_side(midpoint)); if (checker.crosses()) return true; ++it0; ++it1; } return false; }