@i cgal_util.fwi Bbox_2_Line_2_pair::intersection @B@<2D Bbox Line intersection@> @O@<../include/CGAL/Line_2_Bbox_2_intersection.h@>==@{ @@(@- include/CGAL/Line_2_Bbox_2_intersection.h@,@- intersection_2_1.fw@,@- Geert-Jan Giezeman@,@- MPI, Saarbruecken@) #include @} @O@<../include/CGAL/Bbox_2_Line_2_intersection.h@>==@{ @@(@- include/CGAL/Bbox_2_Line_2_intersection.h@,@- intersection_2_1.fw@,@- Geert-Jan Giezeman@,@- MPI, Saarbruecken@) #ifndef CGAL_BBOX_2_LINE_2_INTERSECTION_H #define CGAL_BBOX_2_LINE_2_INTERSECTION_H #include #include //#include //#include #include #include CGAL_BEGIN_NAMESPACE class Bbox_2_Line_2_pair_impl; class Bbox_2_Line_2_pair { public: enum Intersection_results {NO, POINT, SEGMENT}; Bbox_2_Line_2_pair() ; Bbox_2_Line_2_pair(Bbox_2_Line_2_pair const &); Bbox_2_Line_2_pair(Bbox_2 const &bbox, double line_a, double line_b, double line_c); ~Bbox_2_Line_2_pair() ; Bbox_2_Line_2_pair &operator=(Bbox_2_Line_2_pair const &o); // set_bbox(Bbox_2 const &bbox); // set_line(double line_a, double line_b, double line_c); Intersection_results intersection_type() const; bool intersection(double &x, double &y) const; bool intersection(double &x1, double &y1, double &x2, double &y2) const; protected: Bbox_2_Line_2_pair_impl *pimpl; }; template Bbox_2_Line_2_pair intersection_computer_line_2( Bbox_2 const &bbox, Line const &line) { return Bbox_2_Line_2_pair(bbox, to_double(line->a()), to_double(line->b()), to_double(line->c())); } inline bool do_intersect_line_2( const Bbox_2 &box, double line_a, double line_b, double line_c) { Bbox_2_Line_2_pair pair(box, line_a, line_b, line_c); return pair.intersection_type() != Bbox_2_Line_2_pair::NO; } template bool do_intersect_line_2( Bbox_2 const &bbox, Line const &line) { return do_intersect_line_2(bbox, to_double(line->a()), to_double(line->b()), to_double(line->c())); } template bool do_intersect_line_2( Line const &line, Bbox_2 const &bbox) { return do_intersect_line_2(bbox, to_double(line->a()), to_double(line->b()), to_double(line->c())); } template inline bool do_intersect( const Line_2 &line, const Bbox_2 &box) { return do_intersect(box, line); } CGAL_END_NAMESPACE #endif @} @$@==@{ CGAL_BEGIN_NAMESPACE #ifndef CGAL_CFG_RETURN_TYPE_BUG_2 Bbox_2_Line_2_pair::Intersection_results Bbox_2_Line_2_pair::intersection_type() const @ #endif // CGAL_CFG_RETURN_TYPE_BUG_2 bool Bbox_2_Line_2_pair::intersection( double &x1, double &y1, double &x2, double &y2) const { if (!pimpl->_known) intersection_type(); if (pimpl->_result != SEGMENT) return false; Rcart::Point_2 p1(pimpl->_line.point() + pimpl->_min*pimpl->_line.direction().to_vector()); Rcart::Point_2 p2(pimpl->_line.point() + pimpl->_max*pimpl->_line.direction().to_vector()); x1 = p1.x(); y1 = p1.y(); x2 = p2.x(); y2 = p2.y(); return true; } bool Bbox_2_Line_2_pair::intersection( double &x, double &y) const { if (!pimpl->_known) intersection_type(); if (pimpl->_result != POINT) return false; Rcart::Point_2 pt(pimpl->_line.point() + pimpl->_min*pimpl->_line.direction().to_vector()); x = pt.x(); y = pt.y(); return true; } CGAL_END_NAMESPACE @} The following body of the intersection type member function is used twice. Once inline (which the g++ compiler wants because of a bug) and once outline. @$@@M==@{@- { if (pimpl->_known) return pimpl->_result; // The non const this pointer is used to cast away const. pimpl->_known = true; const Rcart::Point_2 &ref_point = pimpl->_line.point(); const Rcart::Vector_2 &dir = pimpl->_line.direction().to_vector(); bool to_infinity = true; // first on x value if (dir.x() == 0.0) { if (ref_point.x() < pimpl->_bbox.xmin()) { pimpl->_result = NO; return pimpl->_result; } if (ref_point.x() > pimpl->_bbox.xmax()) { pimpl->_result = NO; return pimpl->_result; } } else { double newmin, newmax; if (dir.x() > 0.0) { newmin = (pimpl->_bbox.xmin()-ref_point.x())/dir.x(); newmax = (pimpl->_bbox.xmax()-ref_point.x())/dir.x(); } else { newmin = (pimpl->_bbox.xmax()-ref_point.x())/dir.x(); newmax = (pimpl->_bbox.xmin()-ref_point.x())/dir.x(); } if (to_infinity) { pimpl->_min = newmin; pimpl->_max = newmax; } else { if (newmin > pimpl->_min) pimpl->_min = newmin; if (newmax < pimpl->_max) pimpl->_max = newmax; if (pimpl->_max < pimpl->_min) { pimpl->_result = NO; return pimpl->_result; } } to_infinity = false; } // now on y value if (dir.y() == 0.0) { if (ref_point.y() < pimpl->_bbox.ymin()) { pimpl->_result = NO; return pimpl->_result; } if (ref_point.y() > pimpl->_bbox.ymax()) { pimpl->_result = NO; return pimpl->_result; } } else { double newmin, newmax; if (dir.y() > 0.0) { newmin = (pimpl->_bbox.ymin()-ref_point.y())/dir.y(); newmax = (pimpl->_bbox.ymax()-ref_point.y())/dir.y(); } else { newmin = (pimpl->_bbox.ymax()-ref_point.y())/dir.y(); newmax = (pimpl->_bbox.ymin()-ref_point.y())/dir.y(); } if (to_infinity) { pimpl->_min = newmin; pimpl->_max = newmax; } else { if (newmin > pimpl->_min) pimpl->_min = newmin; if (newmax < pimpl->_max) pimpl->_max = newmax; if (pimpl->_max < pimpl->_min) { pimpl->_result = NO; return pimpl->_result; } } to_infinity = false; } CGAL_kernel_assertion(!to_infinity); if (pimpl->_max == pimpl->_min) { pimpl->_result = POINT; return pimpl->_result; } pimpl->_result = SEGMENT; return pimpl->_result; } @} @$@==@{ CGAL_BEGIN_NAMESPACE class Bbox_2_Line_2_pair_impl { public: Bbox_2_Line_2_pair_impl() {} Bbox_2_Line_2_pair_impl(Bbox_2 const &bb, Rcart::Line_2 const &line) : _bbox(bb), _line(line), _known(false) {} Bbox_2 _bbox; Rcart::Line_2 _line; mutable bool _known; mutable Bbox_2_Line_2_pair::Intersection_results _result; mutable double _min, _max; }; Bbox_2_Line_2_pair::~Bbox_2_Line_2_pair() { delete pimpl; } Bbox_2_Line_2_pair::Bbox_2_Line_2_pair() { pimpl = new Bbox_2_Line_2_pair_impl; pimpl->_known = false; } Bbox_2_Line_2_pair::Bbox_2_Line_2_pair(Bbox_2_Line_2_pair const &o) { pimpl = new Bbox_2_Line_2_pair_impl(*o.pimpl); } Bbox_2_Line_2_pair::Bbox_2_Line_2_pair( Bbox_2 const &bbox, double line_a, double line_b, double line_c) { pimpl = new Bbox_2_Line_2_pair_impl(bbox, Rcart::Line_2(line_a, line_b, line_c)); } Bbox_2_Line_2_pair & Bbox_2_Line_2_pair::operator=(Bbox_2_Line_2_pair const &o) { *pimpl = *o.pimpl; return *this; } CGAL_END_NAMESPACE @ @} @B@<2D Ray Bbox intersection@> @O@<../include/CGAL/Bbox_2_Ray_2_intersection.h@>==@{ @@(@- include/CGAL/Bbox_2_Ray_2_intersection.h@,@- intersection_2_1.fw@,@- Geert-Jan Giezeman@,@- MPI, Saarbruecken@) #include @} @O@<../include/CGAL/Ray_2_Bbox_2_intersection.h@>==@{ @@(@- include/CGAL/Ray_2_Bbox_2_intersection.h@,@- intersection_2_1.fw@,@- Geert-Jan Giezeman@,@- Saarbruecken@) #ifndef CGAL_RAY_2_BBOX_2_INTERSECTION_H #define CGAL_RAY_2_BBOX_2_INTERSECTION_H #include #include #include #include CGAL_BEGIN_NAMESPACE class Bbox_2_Ray_2_pair_impl; class Bbox_2_Ray_2_pair { public: enum Intersection_results {NO, POINT, SEGMENT}; ~Bbox_2_Ray_2_pair() ; Bbox_2_Ray_2_pair() ; Bbox_2_Ray_2_pair(Bbox_2_Ray_2_pair const &o) ; Bbox_2_Ray_2_pair(Bbox_2 const &box, double x, double y, double dx, double dy) ; Bbox_2_Ray_2_pair& operator=(Bbox_2_Ray_2_pair const &o) ; Intersection_results intersection_type() const; bool intersection(double &x, double &y) const; bool intersection(double &x1, double &y1, double &x2, double &y2) const; protected: Bbox_2_Ray_2_pair_impl *pimpl; }; bool do_intersect_ray_2( const Bbox_2 &box, double x, double y, double dx, double dy); template bool do_intersect_ray_2( const Bbox_2 &box, const Ray &ray) { double startx = to_double(ray->start().x()); double starty = to_double(ray->start().y()); double dx = to_double(ray->direction().to_vector().x()); double dy = to_double(ray->direction().to_vector().y()); return do_intersect_ray_2(box, startx, starty, dx, dy); } template inline bool do_intersect_ray_2( const Ray &ray, const Bbox_2 &box) { return do_intersect_ray_2(box, ray); } CGAL_END_NAMESPACE #endif @} @$@==@{ CGAL_BEGIN_NAMESPACE Bbox_2_Ray_2_pair::Intersection_results Bbox_2_Ray_2_pair::intersection_type() const @ bool Bbox_2_Ray_2_pair:: intersection(double &x1, double &y1, double &x2, double &y2) const { if (!pimpl->_known) intersection_type(); if (pimpl->_result != SEGMENT) return false; Rcart::Point_2 p1(pimpl->_ref_point + pimpl->_min*pimpl->_dir); Rcart::Point_2 p2(pimpl->_ref_point + pimpl->_max*pimpl->_dir); x1 = p1.x(); y1 = p1.y(); x2 = p2.x(); y2 = p2.y(); return true; } bool Bbox_2_Ray_2_pair::intersection(double &x, double &y) const { if (!pimpl->_known) intersection_type(); if (pimpl->_result != POINT) return false; Rcart::Point_2 pt = pimpl->_ref_point + pimpl->_min*pimpl->_dir; x = pt.x(); y = pt.y(); return true; } bool do_intersect_ray_2( const Bbox_2 &box, double x, double y, double dx, double dy) { Bbox_2_Ray_2_pair pair(box, x, y, dx, dy); return pair.intersection_type() != Bbox_2_Ray_2_pair::NO; } CGAL_END_NAMESPACE @} @$@@M==@{@- { if (pimpl->_known) return pimpl->_result; pimpl->_known = true; bool to_infinity = true; // first on x value if (pimpl->_dir.x() == 0.0) { if (pimpl->_ref_point.x() < pimpl->_box.xmin()) { pimpl->_result = NO; return pimpl->_result; } if (pimpl->_ref_point.x() > pimpl->_box.xmax()) { pimpl->_result = NO; return pimpl->_result; } } else { double newmin, newmax; if (pimpl->_dir.x() > 0.0) { newmin =(pimpl->_box.xmin()-pimpl->_ref_point.x())/pimpl->_dir.x(); newmax =(pimpl->_box.xmax()-pimpl->_ref_point.x())/pimpl->_dir.x(); } else { newmin =(pimpl->_box.xmax()-pimpl->_ref_point.x())/pimpl->_dir.x(); newmax =(pimpl->_box.xmin()-pimpl->_ref_point.x())/pimpl->_dir.x(); } if (newmin > pimpl->_min) pimpl->_min = newmin; if (to_infinity) { pimpl->_max = newmax; } else { if (newmax < pimpl->_max) pimpl->_max = newmax; } if (pimpl->_max < pimpl->_min){ pimpl->_result = NO; return pimpl->_result; } to_infinity = false; } // now on y value if (pimpl->_dir.y() == 0.0) { if (pimpl->_ref_point.y() < pimpl->_box.ymin()) { pimpl->_result = NO; return pimpl->_result; } if (pimpl->_ref_point.y() > pimpl->_box.ymax()) { pimpl->_result = NO; return pimpl->_result; } } else { double newmin, newmax; if (pimpl->_dir.y() > 0.0) { newmin =(pimpl->_box.ymin()-pimpl->_ref_point.y())/pimpl->_dir.y(); newmax =(pimpl->_box.ymax()-pimpl->_ref_point.y())/pimpl->_dir.y(); } else { newmin =(pimpl->_box.ymax()-pimpl->_ref_point.y())/pimpl->_dir.y(); newmax =(pimpl->_box.ymin()-pimpl->_ref_point.y())/pimpl->_dir.y(); } if (newmin > pimpl->_min) pimpl->_min = newmin; if (to_infinity) { pimpl->_max = newmax; } else { if (newmax < pimpl->_max) pimpl->_max = newmax; } if (pimpl->_max < pimpl->_min) { pimpl->_result = NO; return pimpl->_result; } to_infinity = false; } CGAL_kernel_assertion(!to_infinity); if (pimpl->_max == pimpl->_min) { pimpl->_result = POINT; return pimpl->_result; } pimpl->_result = SEGMENT; return pimpl->_result; } @} @$@==@{ CGAL_BEGIN_NAMESPACE class Bbox_2_Ray_2_pair_impl { public: Bbox_2_Ray_2_pair_impl():_known(false) {} Bbox_2_Ray_2_pair_impl(Bbox_2 const &bbox, Rcart::Point_2 const &pt, Rcart::Vector_2 const &dir) :_box(bbox), _known(false), _ref_point(pt), _dir(dir), _min(0.0) {} Ray_2< Rcart > _ray; Bbox_2 _box; bool _known; Bbox_2_Ray_2_pair::Intersection_results _result; Rcart::Point_2 _ref_point; Rcart::Vector_2 _dir; double _min, _max; }; Bbox_2_Ray_2_pair::~Bbox_2_Ray_2_pair() { delete pimpl; } Bbox_2_Ray_2_pair::Bbox_2_Ray_2_pair() { pimpl = new Bbox_2_Ray_2_pair_impl; } Bbox_2_Ray_2_pair::Bbox_2_Ray_2_pair(Bbox_2_Ray_2_pair const &o) { pimpl = new Bbox_2_Ray_2_pair_impl(*o.pimpl); } Bbox_2_Ray_2_pair::Bbox_2_Ray_2_pair( Bbox_2 const &bbox, double x, double y, double dx, double dy) { pimpl = new Bbox_2_Ray_2_pair_impl(bbox, Rcart::Point_2(x,y), Rcart::Vector_2(dx,dy)); } Bbox_2_Ray_2_pair & Bbox_2_Ray_2_pair::operator=(Bbox_2_Ray_2_pair const &o) { *pimpl = *o.pimpl; return *this; } CGAL_END_NAMESPACE @ @} @O@<../include/CGAL/Line_2_Line_2_intersection.h@>==@{ @@(@- include/CGAL/Line_2_Line_2_intersection.h@,@- intersection_2_1.fw@,@- Geert-Jan Giezeman@,@- Saarbruecken@) #ifndef CGAL_LINE_2_LINE_2_INTERSECTION_H #define CGAL_LINE_2_LINE_2_INTERSECTION_H #include #include #include #include CGAL_BEGIN_NAMESPACE template class Line_2_Line_2_pair { public: enum Intersection_results {NO, POINT, LINE}; Line_2_Line_2_pair() ; Line_2_Line_2_pair(Line_2 const *line1, Line_2 const *line2); ~Line_2_Line_2_pair() {} #ifndef CGAL_CFG_RETURN_TYPE_BUG_2 Intersection_results intersection_type() const; #else Intersection_results intersection_type() const @ #endif // CGAL_CFG_RETURN_TYPE_BUG_2 bool intersection(Point_2 &result) const; bool intersection(Line_2 &result) const; protected: Line_2 const* _line1; Line_2 const * _line2; mutable bool _known; mutable Intersection_results _result; mutable Point_2 _intersection_point; }; @@(Line_2@,Line_2@) CGAL_END_NAMESPACE #include CGAL_BEGIN_NAMESPACE template Object intersection(const Line_2 &line1, const Line_2 &line2) { typedef Line_2_Line_2_pair is_t; is_t linepair(&line1, &line2); switch (linepair.intersection_type()) { case is_t::NO: default: return Object(); case is_t::POINT: { Point_2 pt; linepair.intersection(pt); return make_object(pt); } case is_t::LINE: return make_object(line1); } } CGAL_END_NAMESPACE @ #endif @} Momentarily, we use a help function to construct the intersection point and check whether this point is valid. Because the template mechanism of the compilers do not yet comply to the (proposed) standard, we use the following implementation. Note that @{R::FT@} should actually be @{typename R::FT@}. @$@+=@{ CGAL_BEGIN_NAMESPACE template bool construct_if_finite(POINT &pt, RT x, RT y, RT w, R &) { typedef typename R::FT FT; CGAL_kernel_precondition(::CGAL::is_finite(x) && ::CGAL::is_finite(y) && w != RT(0)); FT xw = FT(x)/FT(w); FT yw = FT(y)/FT(w); if (!::CGAL::is_finite(xw) || !::CGAL::is_finite(yw)) return false; pt = POINT(x, y, w); return true; } CGAL_END_NAMESPACE @} A not working, but conformant implementation is the following. Note that this function should be called with an explicit template argument specified: @{construct_if_finite(pt, x, y, w);@}. @$@@Z+=@{ CGAL_BEGIN_NAMESPACE template bool construct_if_finite(Point_2 &pt, typename R::RT x, typename R::RT y, typename R::RT w) { typedef typename R::FT FT; typedef typename R::RT RT; CGAL_kernel_precondition(::CGAL::is_finite(x) && ::CGAL::is_finite(y) && w != (RT) 0); FT xw = FT(x)/FT(w); FT yw = FT(y)/FT(w); if (!::CGAL::is_finite(xw) || !::CGAL::is_finite(yw)) return false; pt = Point_2(x, y, w); return true; } CGAL_END_NAMESPACE @} @$@+=@{@- CGAL_BEGIN_NAMESPACE template Line_2_Line_2_pair::Line_2_Line_2_pair() { _line1 = 0; _line2 = 0; _known = false; } template Line_2_Line_2_pair::Line_2_Line_2_pair( Line_2 const *line1, Line_2 const *line2) { _line1 = line1; _line2 = line2; _known = false; } #ifndef CGAL_CFG_RETURN_TYPE_BUG_2 template typename Line_2_Line_2_pair::Intersection_results Line_2_Line_2_pair::intersection_type() const @ #endif // CGAL_CFG_RETURN_TYPE_BUG_2 template bool Line_2_Line_2_pair::intersection(Point_2 &pt) const { if (!_known) intersection_type(); if (_result != POINT) return false; pt = _intersection_point; return true; } template bool Line_2_Line_2_pair::intersection(Line_2 &l) const { if (!_known) intersection_type(); if (_result != LINE) return false; l = *_line1; return true; } CGAL_END_NAMESPACE @} @$@@M==@{@- { typedef typename R::RT RT; if (_known) return _result; RT nom1, nom2, denom; // The non const this pointer is used to cast away const. _known = true; denom = _line1->a()*_line2->b() - _line2->a()*_line1->b(); if (denom == RT(0)) { if (RT(0) == (_line1->a()*_line2->c() - _line2->a()*_line1->c()) && RT(0) == (_line1->b()*_line2->c() - _line2->b()*_line1->c())) _result = LINE; else _result = NO; return _result; } nom1 = (_line1->b()*_line2->c() - _line2->b()*_line1->c()); if (!::CGAL::is_finite(nom1)) { _result = NO; return _result; } nom2 = (_line2->a()*_line1->c() - _line1->a()*_line2->c()); if (!::CGAL::is_finite(nom2)) { _result = NO; return _result; } R dummyR; if (!construct_if_finite(_intersection_point, nom1, nom2, denom, dummyR)){ _result = NO; return _result; } _result = POINT; return _result; } @} @B@<2D Segment Line intersection@> @O@<../include/CGAL/Line_2_Segment_2_intersection.h@>==@{ @@(@- include/CGAL/Line_2_Segment_2_intersection.h@,@- intersection_2_1.fw@,@- Geert-Jan Giezeman@,@- MPI, Saarbruecken@) #include @} @O@<../include/CGAL/Segment_2_Line_2_intersection.h@>==@{ @@(@- include/CGAL/Segment_2_Line_2_intersection.h@,@- intersection_2_1.fw@,@- Geert-Jan Giezeman@,@- Saarbruecken@) #ifndef CGAL_SEGMENT_2_LINE_2_INTERSECTION_H #define CGAL_SEGMENT_2_LINE_2_INTERSECTION_H #include #include #include #include #include CGAL_BEGIN_NAMESPACE template class Segment_2_Line_2_pair { public: enum Intersection_results {NO, POINT, SEGMENT}; Segment_2_Line_2_pair() ; Segment_2_Line_2_pair(Segment_2 const *seg, Line_2 const *line); ~Segment_2_Line_2_pair() {} #ifndef CGAL_CFG_RETURN_TYPE_BUG_2 Intersection_results intersection_type() const; #else Intersection_results intersection_type() const @ #endif // CGAL_CFG_RETURN_TYPE_BUG_2 bool intersection(Point_2 &result) const; bool intersection(Segment_2 &result) const; protected: Segment_2 const*_seg; Line_2 const * _line; mutable bool _known; mutable Intersection_results _result; mutable Point_2 _intersection_point; }; @@(Segment_2@,Line_2@) CGAL_END_NAMESPACE #include CGAL_BEGIN_NAMESPACE template Object intersection(const Segment_2 &seg, const Line_2 &line) { typedef Segment_2_Line_2_pair is_t; is_t ispair(&seg, &line); switch (ispair.intersection_type()) { case is_t::NO: default: return Object(); case is_t::POINT: { Point_2 pt; ispair.intersection(pt); return make_object(pt); } case is_t::SEGMENT: return make_object(seg); } } template class Line_2_Segment_2_pair: public Segment_2_Line_2_pair { public: Line_2_Segment_2_pair( Line_2 const *line, Segment_2 const *seg) : Segment_2_Line_2_pair(seg, line) {} }; @@(Line_2@,Segment_2@) template inline Object intersection(const Line_2 &line, const Segment_2 &seg) { return intersection(seg, line); } CGAL_END_NAMESPACE @ #endif @} @$@==@{ #include CGAL_BEGIN_NAMESPACE template Segment_2_Line_2_pair::Segment_2_Line_2_pair() { _seg = 0; _line = 0; _known = false; } template Segment_2_Line_2_pair::Segment_2_Line_2_pair( Segment_2 const *seg, Line_2 const *line) { _seg = seg; _line = line; _known = false; } #ifndef CGAL_CFG_RETURN_TYPE_BUG_2 template typename Segment_2_Line_2_pair::Intersection_results Segment_2_Line_2_pair::intersection_type() const @ #endif // CGAL_CFG_RETURN_TYPE_BUG_2 template bool Segment_2_Line_2_pair::intersection(Point_2 &result) const { if (!_known) intersection_type(); if (_result != POINT) return false; result = _intersection_point; return true; } template bool Segment_2_Line_2_pair::intersection(Segment_2 &result) const { if (!_known) intersection_type(); if (_result != SEGMENT) return false; result = *_seg; return true; } CGAL_END_NAMESPACE @} @$@@M==@{@- { if (_known) return _result; // The non const this pointer is used to cast away const. _known = true; const Line_2 &l1 = _seg->supporting_line(); Line_2_Line_2_pair linepair(&l1, _line); switch ( linepair.intersection_type()) { case Line_2_Line_2_pair::NO: _result = NO; break; case Line_2_Line_2_pair::POINT: linepair.intersection(_intersection_point); _result = (_seg->collinear_has_on(_intersection_point) ) ? POINT : NO; break; case Line_2_Line_2_pair::LINE: _result = SEGMENT; break; } return _result; } @} @B@<2D Segment Segment intersection@> @O@<../include/CGAL/Segment_2_Segment_2_intersection.h@>==@{ @@(@- include/CGAL/Segment_2_Segment_2_intersection.h@,@- intersection_2_1.fw@,@- Geert-Jan Giezeman@,@- Saarbruecken@) #ifndef CGAL_SEGMENT_2_SEGMENT_2_INTERSECTION_H #define CGAL_SEGMENT_2_SEGMENT_2_INTERSECTION_H #include #include #include #include CGAL_BEGIN_NAMESPACE template class Segment_2_Segment_2_pair { public: enum Intersection_results {NO, POINT, SEGMENT}; Segment_2_Segment_2_pair() ; Segment_2_Segment_2_pair(Segment_2 const *seg1, Segment_2 const *seg2); ~Segment_2_Segment_2_pair() {} #ifndef CGAL_CFG_RETURN_TYPE_BUG_2 Intersection_results intersection_type() const; #else Intersection_results intersection_type() const @ #endif // CGAL_CFG_RETURN_TYPE_BUG_2 bool intersection(Point_2 &result) const; bool intersection(Segment_2 &result) const; protected: Segment_2 const* _seg1; Segment_2 const * _seg2; mutable bool _known; mutable Intersection_results _result; mutable Point_2 _intersection_point, _other_point; }; template inline bool do_intersect(const Segment_2 &seg1, const Segment_2 &seg2); CGAL_END_NAMESPACE @ @ #include CGAL_BEGIN_NAMESPACE template Object intersection(const Segment_2 &seg1, const Segment_2&seg2) { typedef Segment_2_Segment_2_pair is_t; is_t ispair(&seg1, &seg2); switch (ispair.intersection_type()) { case is_t::NO: default: return Object(); case is_t::POINT: { Point_2 pt; ispair.intersection(pt); return make_object(pt); } case is_t::SEGMENT: { Segment_2 iseg; ispair.intersection(iseg); return make_object(iseg); } } } CGAL_END_NAMESPACE #endif @} The segment segment intersection test implementation can best be understood as a line sweep algorithm. The endpoints of the segments are sorted (lexicographically, first along x then along y coordinate). In the sweep, the first two point that are inserted second should be from different segments (otherwise, the segments don't intersect because they can be separated by a vertical line). We check for the second and third inserted point on which side of the line through the other segment they lie. (The other segment can be the same for both points -the contained case- or different -the crossing case). @$@==@{ #include #include namespace CGAL { @ @ template bool do_intersect(const Segment_2 &seg1, const Segment_2 &seg2) { typename R::Point_2 const & A1 = seg1.source(); typename R::Point_2 const & A2 = seg1.target(); typename R::Point_2 const & B1 = seg2.source(); typename R::Point_2 const & B2 = seg2.target(); @ if (lexicographically_xy_smaller(A1,A2)) { @@(A1@,A2@,B1@,B2@) } else { @@(A2@,A1@,B1@,B2@) } CGAL_kernel_assertion(false); return false; } } // end namespace CGAL @} At step 1 we know that argument 2 is not lexicograpically smaller than argument 1. @$@@(@4@)@M==@{@- if (lexicographically_xy_smaller(@3,@4)) { @@(@1@,@2@,@3@,@4@) } else { @@(@1@,@2@,@4@,@3@) }@- @} At step 2 we know that argument 1 lexicograpically smaller than (or equal to) argument 2 and argument 3 is smaller than (or equal to) argument 4. @$@@(@4@)@M==@{@- switch(compare_lexicographically_xy(@1,@3)) { case SMALLER: @@(@1@,@2@,@3@,@4@) case EQUAL: return true; case LARGER: @@(@3@,@4@,@1@,@2@) }@- @} At step 3 we know that argument 1 lexicograpically smaller than argument 3. @$@@(@4@)@M==@{@- switch(compare_lexicographically_xy(@2,@3)) { case SMALLER: return false; case EQUAL: return true; case LARGER: @@(@1@,@2@,@3@,@4@) }@- @} At step 4 we know that argument 1 < argument 3 < argument 2 and that argument 3 <= argument 4 @$@@(@4@)@M==@{@- switch(compare_lexicographically_xy(@2,@4)) { case SMALLER: return seg_seg_do_intersect_crossing(@1,@2,@3,@4); case EQUAL: return true; case LARGER: return seg_seg_do_intersect_contained(@1,@2,@3,@4); }@- @} // precondition: p1==@{ template bool seg_seg_do_intersect_crossing( PT const &p1, PT const &p2, PT const &p3, PT const &p4) { switch (orientation(p1,p2,p3)) { case LEFT_TURN: return !right_turn(p3,p4,p2); case RIGHT_TURN: return !left_turn(p3,p4,p2); case COLLINEAR: return true; } CGAL_kernel_assertion(false); return false; } @} // precondition: p1==@{ template bool seg_seg_do_intersect_contained( PT const &p1, PT const &p2, PT const &p3, PT const &p4) { switch (orientation(p1,p2,p3)) { case LEFT_TURN: return !left_turn(p1,p2,p4); case RIGHT_TURN: return !right_turn(p1,p2,p4); case COLLINEAR: return true; } CGAL_kernel_assertion(false); return false; } @} The y-test tests if the segments have an interval in common in the y-direction. This is not necessary for the correctness of the computation, but it leads to a similar computation time for symmetric cases. Together with the tests on x coordinates this is effectively a bounding box test. Comparing coordinates is usually cheaper than orientation tests, so I expect that this test will help efficiency on average. @$@==@{@- if (lexicographically_yx_smaller(A1,A2)) { if (lexicographically_yx_smaller(B1,B2)) { if (lexicographically_yx_smaller(A2,B1) || lexicographically_yx_smaller(B2,A1)) return false; } else { if (lexicographically_yx_smaller(A2,B2) || lexicographically_yx_smaller(B1,A1)) return false; } } else { if (lexicographically_yx_smaller(B1,B2)) { if (lexicographically_yx_smaller(A1,B1) || lexicographically_yx_smaller(B2,A2)) return false; } else { if (lexicographically_yx_smaller(A1,B2) || lexicographically_yx_smaller(B1,A2)) return false; } }@- @} @$@==@{ #include #include CGAL_BEGIN_NAMESPACE template Segment_2_Segment_2_pair::Segment_2_Segment_2_pair() { _seg1 = 0; _seg2 = 0; _known = false; } template Segment_2_Segment_2_pair::Segment_2_Segment_2_pair( Segment_2 const *seg1, Segment_2 const *seg2) { _seg1 = seg1; _seg2 = seg2; _known = false; } #ifndef CGAL_CFG_RETURN_TYPE_BUG_2 template typename Segment_2_Segment_2_pair::Intersection_results Segment_2_Segment_2_pair::intersection_type() const @ #endif // CGAL_CFG_RETURN_TYPE_BUG_2 template bool Segment_2_Segment_2_pair::intersection(Point_2 &result) const { if (!_known) intersection_type(); if (_result != POINT) return false; result = _intersection_point; return true; } template bool Segment_2_Segment_2_pair::intersection(Segment_2 &result) const { if (!_known) intersection_type(); if (_result != SEGMENT) return false; result = Segment_2(_intersection_point, _other_point); return true; } CGAL_END_NAMESPACE @} @$@@M==@{@- { if (_known) return _result; _known = true; if (!do_intersect(*_seg1, *_seg2)) { _result = NO; return _result; } Line_2 const &l1 = _seg1->supporting_line(); Line_2 const &l2 = _seg2->supporting_line(); Line_2_Line_2_pair linepair(&l1, &l2); switch ( linepair.intersection_type()) { case Line_2_Line_2_pair::NO: _result = NO; break; case Line_2_Line_2_pair::POINT: linepair.intersection(_intersection_point); _result = POINT; break; case Line_2_Line_2_pair::LINE: @ } return _result; } @} @C@ We decide on a main direction (x or y) in which the segment changes the fastest. @$@==@{@- { typedef typename R::RT RT; Point_2 const &start1 = _seg1->start(); Point_2 const &end1 = _seg1->end(); Point_2 const &start2 = _seg2->start(); Point_2 const &end2 = _seg2->end(); Vector_2 diff1 = end1-start1; Point_2 const *minpt; Point_2 const *maxpt; if (CGAL_NTS abs(diff1.x()) > CGAL_NTS abs(diff1.y())) { @@(x@) } else { @@(y@) } } @- @} The first parameter in the following macro should either be x or y. The macro sorts the four endpoints of the two segments according to this parameter. Then a check is made to see if there is an overlapping interval. @$@@(@1@)@M==@{@- if (start1.@1() < end1.@1()) { minpt = &start1; maxpt = &end1; } else { minpt = &end1; maxpt = &start1; } if (start2.@1() < end2.@1()) { if (start2.@1() > minpt->@1()) { minpt = &start2; } if (end2.@1() < maxpt->@1()) { maxpt = &end2; } } else { if (end2.@1() > minpt->@1()) { minpt = &end2; } if (start2.@1() < maxpt->@1()) { maxpt = &start2; } } if (maxpt->@1() < minpt->@1()) { _result = NO; return _result; } if (maxpt->@1() == minpt->@1()) { _intersection_point = *minpt; _result = POINT; return _result; } _intersection_point = *minpt; _other_point = *maxpt; _result = SEGMENT; return _result; @- @} @B@<2D Ray Line intersection@> @O@<../include/CGAL/Line_2_Ray_2_intersection.h@>==@{ @@(@- include/CGAL/Line_2_Ray_2_intersection.h@,@- intersection_2_1.fw@,@- Geert-Jan Giezeman@,@- MPI, Saarbruecken@) #include @} @O@<../include/CGAL/Ray_2_Line_2_intersection.h@>==@{ @@(@- include/CGAL/Ray_2_Line_2_intersection.h@,@- intersection_2_1.fw@,@- Geert-Jan Giezeman@,@- Saarbruecken@) #ifndef CGAL_RAY_2_LINE_2_INTERSECTION_H #define CGAL_RAY_2_LINE_2_INTERSECTION_H #include #include #include #include #include CGAL_BEGIN_NAMESPACE template class Ray_2_Line_2_pair { public: enum Intersection_results {NO, POINT, RAY}; Ray_2_Line_2_pair() ; Ray_2_Line_2_pair(Ray_2 const *ray, Line_2 const *line); ~Ray_2_Line_2_pair() {} #ifndef CGAL_CFG_RETURN_TYPE_BUG_2 Intersection_results intersection_type() const; #else Intersection_results intersection_type() const @ #endif // CGAL_CFG_RETURN_TYPE_BUG_2 bool intersection(Point_2 &result) const; bool intersection(Ray_2 &result) const; protected: Ray_2 const * _ray; Line_2 const * _line; mutable bool _known; mutable Intersection_results _result; mutable Point_2 _intersection_point; }; @@(Ray_2@,Line_2@) CGAL_END_NAMESPACE #include CGAL_BEGIN_NAMESPACE template Object intersection(const Ray_2 &ray, const Line_2&line) { typedef Ray_2_Line_2_pair is_t; is_t ispair(&ray, &line); switch (ispair.intersection_type()) { case is_t::NO: default: return Object(); case is_t::POINT: { Point_2 pt; ispair.intersection(pt); return make_object(pt); } case is_t::RAY: { return make_object(ray); } } } template class Line_2_Ray_2_pair: public Ray_2_Line_2_pair { public: Line_2_Ray_2_pair( Line_2 const *line, Ray_2 const *ray) : Ray_2_Line_2_pair(ray, line) {} }; @@(Line_2@,Ray_2@) template inline Object intersection(const Line_2 &line, const Ray_2 &ray) { return intersection(ray, line); } CGAL_END_NAMESPACE @ #endif @} @$@==@{ #include CGAL_BEGIN_NAMESPACE template Ray_2_Line_2_pair::Ray_2_Line_2_pair() { _ray = 0; _line = 0; _known = false; } template Ray_2_Line_2_pair::Ray_2_Line_2_pair( Ray_2 const *ray, Line_2 const *line) { _ray = ray; _line = line; _known = false; } #ifndef CGAL_CFG_RETURN_TYPE_BUG_2 template typename Ray_2_Line_2_pair::Intersection_results Ray_2_Line_2_pair::intersection_type() const @ #endif // CGAL_CFG_RETURN_TYPE_BUG_2 template bool Ray_2_Line_2_pair::intersection(Point_2 &result) const { if (!_known) intersection_type(); if (_result != POINT) return false; result = _intersection_point; return true; } template bool Ray_2_Line_2_pair::intersection(Ray_2 &result) const { if (!_known) intersection_type(); if (_result != RAY) return false; result = *_ray; return true; } CGAL_END_NAMESPACE @} @$@@M==@{@- { if (_known) return _result; // The non const this pointer is used to cast away const. _known = true; const Line_2 &l1 = _ray->supporting_line(); Line_2_Line_2_pair linepair(&l1, _line); switch ( linepair.intersection_type()) { case Line_2_Line_2_pair::NO: _result = NO; break; case Line_2_Line_2_pair::POINT: linepair.intersection(_intersection_point); _result = (_ray->collinear_has_on(_intersection_point) ) ? POINT : NO; break; case Line_2_Line_2_pair::LINE: _result = RAY; break; } return _result; } @} @B@<2D Ray Segment intersection@> @O@<../include/CGAL/Segment_2_Ray_2_intersection.h@>==@{ @@(@- include/CGAL/Segment_2_Ray_2_intersection.h@,@- intersection_2_1.fw@,@- Geert-Jan Giezeman@,@- MPI, Saarbruecken@) #include @} @O@<../include/CGAL/Ray_2_Segment_2_intersection.h@>==@{ @@(@- include/CGAL/Ray_2_Segment_2_intersection.h@,@- intersection_2_1.fw@,@- Geert-Jan Giezeman@,@- Saarbruecken@) #ifndef CGAL_RAY_2_SEGMENT_2_INTERSECTION_H #define CGAL_RAY_2_SEGMENT_2_INTERSECTION_H #include #include #include #include #include CGAL_BEGIN_NAMESPACE template class Ray_2_Segment_2_pair { public: enum Intersection_results {NO, POINT, SEGMENT}; Ray_2_Segment_2_pair() ; Ray_2_Segment_2_pair(Ray_2 const *ray, Segment_2 const *line); ~Ray_2_Segment_2_pair() {} #ifndef CGAL_CFG_RETURN_TYPE_BUG_2 Intersection_results intersection_type() const; #else Intersection_results intersection_type() const @ #endif // CGAL_CFG_RETURN_TYPE_BUG_2 bool intersection(Point_2 &result) const; bool intersection(Segment_2 &result) const; protected: Ray_2 const * _ray; Segment_2 const * _seg; mutable bool _known; mutable Intersection_results _result; mutable Point_2 _intersection_point, _other_point; }; @@(Ray_2@,Segment_2@) CGAL_END_NAMESPACE @ #include CGAL_BEGIN_NAMESPACE template Object intersection(const Ray_2 &ray, const Segment_2&seg) { typedef Ray_2_Segment_2_pair is_t; is_t ispair(&ray, &seg); switch (ispair.intersection_type()) { case is_t::NO: default: return Object(); case is_t::POINT: { Point_2 pt; ispair.intersection(pt); return make_object(pt); } case is_t::SEGMENT: { Segment_2 iseg; ispair.intersection(iseg); return make_object(iseg); } } } template class Segment_2_Ray_2_pair: public Ray_2_Segment_2_pair { public: Segment_2_Ray_2_pair( Segment_2 const *seg, Ray_2 const *ray) : Ray_2_Segment_2_pair(ray, seg) {} }; @@(Segment_2@,Ray_2@) template inline Object intersection(const Segment_2 &seg, const Ray_2 &ray) { return intersection(ray, seg); } CGAL_END_NAMESPACE #endif @} @$@==@{ #include #include CGAL_BEGIN_NAMESPACE template Ray_2_Segment_2_pair::Ray_2_Segment_2_pair() { _ray = 0; _seg = 0; _known = false; } template Ray_2_Segment_2_pair::Ray_2_Segment_2_pair( Ray_2 const *ray, Segment_2 const *seg) { _ray = ray; _seg = seg; _known = false; } #ifndef CGAL_CFG_RETURN_TYPE_BUG_2 template typename Ray_2_Segment_2_pair::Intersection_results Ray_2_Segment_2_pair::intersection_type() const @ #endif // CGAL_CFG_RETURN_TYPE_BUG_2 template bool Ray_2_Segment_2_pair::intersection(Point_2 &result) const { if (!_known) intersection_type(); if (_result != POINT) return false; result = _intersection_point; return true; } template bool Ray_2_Segment_2_pair::intersection(Segment_2 &result) const { if (!_known) intersection_type(); if (_result != SEGMENT) return false; result = Segment_2(_intersection_point, _other_point); return true; } CGAL_END_NAMESPACE @} @$@@M==@{@- { if (_known) return _result; // The non const this pointer is used to cast away const. _known = true; // if (!do_overlap(_ray->bbox(), _seg->bbox())) // return NO; const Line_2 &l1 = _ray->supporting_line(); const Line_2 &l2 = _seg->supporting_line(); Line_2_Line_2_pair linepair(&l1, &l2); switch ( linepair.intersection_type()) { case Line_2_Line_2_pair::NO: _result = NO; return _result; case Line_2_Line_2_pair::POINT: linepair.intersection(_intersection_point); _result = (_ray->collinear_has_on(_intersection_point) && _seg->collinear_has_on(_intersection_point) ) ? POINT : NO; return _result; case Line_2_Line_2_pair::LINE: { @ } default: CGAL_kernel_assertion(false); // should not be reached: return _result; } } @} @C@ We decide on a main direction (x or y) in which the segment changes the fastest. @$@==@{@- typedef typename R::RT RT; const Point_2 &start1 = _seg->start(); const Point_2 &end1 = _seg->end(); const Point_2 &start2 = _ray->start(); const Point_2 *minpt, *maxpt; Vector_2 diff1 = end1-start1; if (CGAL_NTS abs(diff1.x()) > CGAL_NTS abs(diff1.y())) { @@(x@) } else { @@(y@) } @- @} The first parameter in the following macro should either be x or y. The macro sorts the endpoints of the segment according to this parameter. Then a check is made to see if there is an overlapping interval. @$@@(@1@)@M==@{@- typedef typename R::FT FT; if (start1.@1() < end1.@1()) { minpt = &start1; maxpt = &end1; } else { minpt = &end1; maxpt = &start1; } if (_ray->direction().to_vector().@1() > FT(0)) { if (maxpt->@1() < start2.@1()) { _result = NO; return _result; } if (maxpt->@1() == start2.@1()) { _intersection_point = *maxpt; _result = POINT; return _result; } if (minpt->@1() < start2.@1()) { _intersection_point = start2; _other_point = *maxpt; } else { _intersection_point = _seg->start(); _other_point = _seg->end(); } _result = SEGMENT; return _result; } else { if (minpt->@1() > start2.@1()) { _result = NO; return _result; } if (minpt->@1() == start2.@1()) { _intersection_point = *minpt; _result = POINT; return _result; } if (maxpt->@1() > start2.@1()) { _intersection_point = start2; _other_point = *maxpt; } else { _intersection_point = _seg->start(); _other_point = _seg->end(); } _result = SEGMENT; return _result; }@- @} @B@<2D Ray Ray intersection@> @O@<../include/CGAL/Ray_2_Ray_2_intersection.h@>==@{ @@(@- include/CGAL/Ray_2_Ray_2_intersection.h@,@- intersection_2_1.fw@,@- Geert-Jan Giezeman@,@- Saarbruecken@) #ifndef CGAL_RAY_2_RAY_2_INTERSECTION_H #define CGAL_RAY_2_RAY_2_INTERSECTION_H #include #include #include #include #include CGAL_BEGIN_NAMESPACE template class Ray_2_Ray_2_pair { public: enum Intersection_results {NO, POINT, SEGMENT, RAY}; Ray_2_Ray_2_pair() ; Ray_2_Ray_2_pair(Ray_2 const *ray1, Ray_2 const *ray2); ~Ray_2_Ray_2_pair() {} #ifndef CGAL_CFG_RETURN_TYPE_BUG_2 Intersection_results intersection_type() const; #else Intersection_results intersection_type() const @ #endif // CGAL_CFG_RETURN_TYPE_BUG_2 bool intersection(Point_2 &result) const; bool intersection(Segment_2 &result) const; bool intersection(Ray_2 &result) const; protected: Ray_2 const* _ray1; Ray_2 const * _ray2; mutable bool _known; mutable Intersection_results _result; mutable Point_2 _intersection_point, _other_point; }; @@(Ray_2@,Ray_2@) CGAL_END_NAMESPACE @ #include CGAL_BEGIN_NAMESPACE template Object intersection(const Ray_2 &ray1, const Ray_2&ray2) { typedef Ray_2_Ray_2_pair is_t; is_t ispair(&ray1, &ray2); switch (ispair.intersection_type()) { case is_t::NO: default: return Object(); case is_t::POINT: { Point_2 pt; ispair.intersection(pt); return make_object(pt); } case is_t::SEGMENT: { Segment_2 iseg; ispair.intersection(iseg); return make_object(iseg); } case is_t::RAY: { Ray_2 iray; ispair.intersection(iray); return make_object(iray); } } } CGAL_END_NAMESPACE #endif @} @$@==@{ #include #include CGAL_BEGIN_NAMESPACE template Ray_2_Ray_2_pair::Ray_2_Ray_2_pair() { _ray1 = 0; _ray2 = 0; _known = false; } template Ray_2_Ray_2_pair::Ray_2_Ray_2_pair( Ray_2 const *ray1, Ray_2 const *ray2) { _ray1 = ray1; _ray2 = ray2; _known = false; } #ifndef CGAL_CFG_RETURN_TYPE_BUG_2 template typename Ray_2_Ray_2_pair::Intersection_results Ray_2_Ray_2_pair::intersection_type() const @ #endif // CGAL_CFG_RETURN_TYPE_BUG_2 template bool Ray_2_Ray_2_pair::intersection(Point_2 &result) const { if (!_known) intersection_type(); if (_result != POINT) return false; result = _intersection_point; return true; } template bool Ray_2_Ray_2_pair::intersection(Segment_2 &result) const { if (!_known) intersection_type(); if (_result != SEGMENT) return false; result = Segment_2(_ray1->start(), _ray2->start()); return true; } template bool Ray_2_Ray_2_pair::intersection(Ray_2 &result) const { if (!_known) intersection_type(); if (_result != RAY) return false; result = Ray_2(_intersection_point, _ray1->direction()); return true; } CGAL_END_NAMESPACE @} @$@@M==@{@- { if (_known) return _result; // The non const this pointer is used to cast away const. _known = true; // if (!do_overlap(_ray1->bbox(), _ray2->bbox())) // return NO; const Line_2 &l1 = _ray1->supporting_line(); const Line_2 &l2 = _ray2->supporting_line(); Line_2_Line_2_pair linepair(&l1, &l2); switch ( linepair.intersection_type()) { case Line_2_Line_2_pair::NO: _result = NO; return _result; case Line_2_Line_2_pair::POINT: linepair.intersection(_intersection_point); _result = (_ray1->collinear_has_on(_intersection_point) && _ray2->collinear_has_on(_intersection_point) ) ? POINT : NO; return _result; case Line_2_Line_2_pair::LINE: @ default: CGAL_kernel_assertion(false); // should not be reached: return _result; } } @} @C@ We decide on a main direction (x or y) in which the segment changes the fastest. @$@==@{@- { typedef typename R::RT RT; const Vector_2 &dir1 = _ray1->direction().to_vector(); const Vector_2 &dir2 = _ray2->direction().to_vector(); if (CGAL_NTS abs(dir1.x()) > CGAL_NTS abs(dir1.y())) { @@(x@) } else { @@(y@) } } @- @} The first parameter in the following macro should either be x or y. The macro sorts the four endpoints of the two segments according to this parameter. Then a check is made to see if there is an overlapping interval. @$@@(@1@)@M==@{@- typedef typename R::FT FT; if (dir1.@1() > FT(0)) { if (dir2.@1() > FT(0)) { _intersection_point = (_ray1->start().@1() < _ray2->start().@1()) ? _ray2->start() : _ray1->start(); _result = RAY; return _result; } else { if (_ray1->start().@1() > _ray2->start().@1()) { _result = NO; return _result; } if (_ray1->start().@1() == _ray2->start().@1()) { _intersection_point = _ray1->start(); _result = POINT; return _result; } _result = SEGMENT; return _result; } } else { if (dir2.@1() < FT(0)) { _intersection_point = (_ray1->start().@1() > _ray2->start().@1()) ? _ray2->start() : _ray1->start(); _result = RAY; return _result; } else { if (_ray1->start().@1() < _ray2->start().@1()) { _result = NO; return _result; } if (_ray1->start().@1() == _ray2->start().@1()) { _intersection_point = _ray1->start(); _result = POINT; return _result; } _result = SEGMENT; return _result; } } @} @B@<2D Point Line intersection@> @O@<../include/CGAL/Line_2_Point_2_intersection.h@>==@{ @@(@- include/CGAL/Line_2_Point_2_intersection.h@,@- intersection_2_1.fw@,@- Geert-Jan Giezeman@,@- MPI, Saarbruecken@) #include @} @O@<../include/CGAL/Point_2_Line_2_intersection.h@>==@{ @@(@- include/CGAL/Point_2_Line_2_intersection.h@,@- intersection_2_1.fw@,@- Geert-Jan Giezeman@,@- Saarbruecken@) #ifndef CGAL_POINT_2_LINE_2_INTERSECTION_H #define CGAL_POINT_2_LINE_2_INTERSECTION_H #include #include CGAL_BEGIN_NAMESPACE template inline bool do_intersect(const Point_2 &pt, const Line_2 &line) { return line.has_on(pt); } CGAL_END_NAMESPACE #include CGAL_BEGIN_NAMESPACE template Object intersection(const Point_2 &pt, const Line_2 &line) { if (do_intersect(pt,line)) { return make_object(pt); } return Object(); } template inline bool do_intersect(const Line_2 &line, const Point_2 &pt) { return line.has_on(pt); } template inline Object intersection(const Line_2 &line, const Point_2 &pt) { if (do_intersect(pt,line)) { return make_object(pt); } return Object(); } CGAL_END_NAMESPACE #endif @} @B@<2D Point Ray intersection@> @O@<../include/CGAL/Ray_2_Point_2_intersection.h@>==@{ @@(@- include/CGAL/Ray_2_Point_2_intersection.h@,@- intersection_2_1.fw@,@- Geert-Jan Giezeman@,@- MPI, Saarbruecken@) #include @} @O@<../include/CGAL/Point_2_Ray_2_intersection.h@>==@{ @@(@- include/CGAL/Point_2_Ray_2_intersection.h@,@- intersection_2_1.fw@,@- Geert-Jan Giezeman@,@- Saarbruecken@) #ifndef CGAL_POINT_2_RAY_2_INTERSECTION_H #define CGAL_POINT_2_RAY_2_INTERSECTION_H #include #include CGAL_BEGIN_NAMESPACE template inline bool do_intersect(const Point_2 &pt, const Ray_2 &ray) { return ray.has_on(pt); } CGAL_END_NAMESPACE #include CGAL_BEGIN_NAMESPACE template Object intersection(const Point_2 &pt, const Ray_2 &ray) { if (do_intersect(pt,ray)) { return make_object(pt); } return Object(); } template inline bool do_intersect(const Ray_2 &ray, const Point_2 &pt) { return ray.has_on(pt); } template inline Object intersection(const Ray_2 &ray, const Point_2 &pt) { if (do_intersect(pt,ray)) { return make_object(pt); } return Object(); } CGAL_END_NAMESPACE #endif @} @B@<2D Point Segment intersection@> @O@<../include/CGAL/Segment_2_Point_2_intersection.h@>==@{ @@(@- include/CGAL/Segment_2_Point_2_intersection.h@,@- intersection_2_1.fw@,@- Geert-Jan Giezeman@,@- MPI, Saarbruecken@) #include @} @O@<../include/CGAL/Point_2_Segment_2_intersection.h@>==@{ @@(@- include/CGAL/Point_2_Segment_2_intersection.h@,@- intersection_2_1.fw@,@- Geert-Jan Giezeman@,@- Saarbruecken@) #ifndef CGAL_POINT_2_SEGMENT_2_INTERSECTION_H #define CGAL_POINT_2_SEGMENT_2_INTERSECTION_H #include #include CGAL_BEGIN_NAMESPACE template inline bool do_intersect(const Point_2 &pt, const Segment_2 &seg) { return seg.has_on(pt); } CGAL_END_NAMESPACE #include CGAL_BEGIN_NAMESPACE template Object intersection(const Point_2 &pt, const Segment_2 &seg) { if (do_intersect(pt,seg)) { return make_object(pt); } return Object(); } template inline bool do_intersect(const Segment_2 &seg, const Point_2 &pt) { return seg.has_on(pt); } template inline Object intersection(const Segment_2 &seg, const Point_2 &pt) { if (do_intersect(pt,seg)) { return make_object(pt); } return Object(); } CGAL_END_NAMESPACE #endif @} @B@<2D Point Point intersection@> @O@<../include/CGAL/Point_2_Point_2_intersection.h@>==@{ @@(@- include/CGAL/Point_2_Point_2_intersection.h@,@- intersection_2_1.fw@,@- Geert-Jan Giezeman@,@- Saarbruecken@) #ifndef CGAL_POINT_2_POINT_2_INTERSECTION_H #define CGAL_POINT_2_POINT_2_INTERSECTION_H #include CGAL_BEGIN_NAMESPACE template inline bool do_intersect(const Point_2 &pt1, const Point_2 &pt2) { return pt1 == pt2; } CGAL_END_NAMESPACE #include CGAL_BEGIN_NAMESPACE template Object intersection(const Point_2 &pt1, const Point_2 &pt2) { if (pt1 == pt2) { return make_object(pt1); } return Object(); } CGAL_END_NAMESPACE #endif @} @B@ @O@<../include/CGAL/Bbox_2_intersection.h@>==@{@- @@(@- include/CGAL/Bbox_2_intersection.h@,@- intersection_2_1.fw@,@- Geert-Jan Giezeman@,@- Saarbruecken@) #ifndef CGAL_BBOX_2_INTERSECTIONS_H #define CGAL_BBOX_2_INTERSECTIONS_H #include #include #endif // CGAL_BBOX_2_INTERSECTIONS_H @} @O@<../include/CGAL/intersection_2_1.h@>==@{@- @@(@- include/CGAL/intersection_2_1.h@,@- intersection_2_1.fw@,@- Geert-Jan Giezeman@,@- Saarbruecken@) #ifndef CGAL_INTERSECTION_2_1_H #define CGAL_INTERSECTION_2_1_H #include #include #include #include #include #include #include #include #include #include #endif @} @O@<../src/Bbox_2_intersections.C@>==@{@- @@(@- src/Bbox_2_intersections.C@,@- intersection_2_1.fw@,@- Geert-Jan Giezeman@,@- Saarbruecken@) #include #include #include typedef CGAL::Simple_cartesian Rcart; @ @ @}