@i cgal_util.fwi @B@ The intersection of two triangles can lead to a (convex) polygon of (at most) six sides. @O@<../include/CGAL/Triangle_2_Triangle_2_intersection.h@>==@{ @@(@- include/CGAL/Triangle_2_Triangle_2_intersection.h@,@- intersection_2_2.fw@,@- Geert-Jan Giezeman@,@- MPI, Saarbruecken@) #ifndef CGAL_TRIANGLE_2_TRIANGLE_2_INTERSECTION_H #define CGAL_TRIANGLE_2_TRIANGLE_2_INTERSECTION_H #include CGAL_BEGIN_NAMESPACE template Object intersection(const Triangle_2 &tr1, const Triangle_2&tr2); template bool do_intersect(const Triangle_2 &tr1, const Triangle_2&tr2); CGAL_END_NAMESPACE #ifdef CGAL_CFG_NO_AUTOMATIC_TEMPLATE_INCLUSION #include #endif #endif @} @O@<../include/CGAL/Triangle_2_Triangle_2_intersection.C@>==@{ @@(@- include/CGAL/Triangle_2_Triangle_2_intersection.C@,@- intersection_2_2.fw@,@- Geert-Jan Giezeman@,@- Saarbruecken@) #include #include CGAL_BEGIN_NAMESPACE template struct Pointlist_2_rec_ { Pointlist_2_rec_ *next; Point_2 point; Oriented_side side; }; template struct Pointlist_2_ { int size; Pointlist_2_rec_ *first; Pointlist_2_() ; ~Pointlist_2_() ; }; template class Triangle_2_Triangle_2_pair { public: enum Intersection_results {NO, POINT, SEGMENT, TRIANGLE, POLYGON}; Triangle_2_Triangle_2_pair() ; Triangle_2_Triangle_2_pair( Triangle_2 const *trian1, Triangle_2 const *trian2) ; ~Triangle_2_Triangle_2_pair() {} #ifdef 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(Triangle_2 &result) const; bool intersection(/*Polygon_2 &result*/) const; int vertex_count() const; Point_2 vertex(int i) const; protected: Triangle_2 const* _trian1; Triangle_2 const * _trian2; mutable bool _known; mutable Intersection_results _result; mutable Pointlist_2_ _pointlist; }; @@(Triangle_2@,Triangle_2@) CGAL_END_NAMESPACE @ CGAL_BEGIN_NAMESPACE template Object intersection(const Triangle_2 &tr1, const Triangle_2&tr2) { typedef Triangle_2_Triangle_2_pair is_t; is_t ispair(&tr1, &tr2); 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::TRIANGLE: { Triangle_2 itr; ispair.intersection(itr); return make_object(itr); } case is_t::POLYGON: { typedef CGAL_STD::vector > Container; Container points(ispair.vertex_count()); for (int i =0; i < ispair.vertex_count(); i++) { points[i] = ispair.vertex(i); } return make_object(points); } } } CGAL_END_NAMESPACE @} A triangle is a convex polygon. We maintain this convex polygon. Every edge of the other triangle can be extended to a line. We cut the maintained polygon consecutively with those three supporting lines. We direct the lines in such a way that the (second) triangle lies to the left of them. So, when we look at the maintained polygon, the vertices to the right should be discarded. The implementation does not make use of LEDA singly linked lists, which it should do, probably. @$@+=@{ #include #include #include #include CGAL_BEGIN_NAMESPACE template Pointlist_2_::Pointlist_2_() { size = 0; first = 0; } template Pointlist_2_::~Pointlist_2_() { Pointlist_2_rec_ *cur; for (int i=0; inext; delete cur; } } @} @$@+=@{ template void _init_list(Pointlist_2_ &list, const Triangle_2 &trian) { // check on degeneracies of trian. if (!trian.is_degenerate()) { list.size = 3; list.first = 0; for (int i=0; i<3; i++) { Pointlist_2_rec_ *newrec = new Pointlist_2_rec_; newrec->next = list.first; list.first = newrec; newrec->point = trian[i]; } } else { // _not_implemented(); CGAL_kernel_assertion(false); } } CGAL_END_NAMESPACE @} @$@+=@{ #include CGAL_BEGIN_NAMESPACE template void _cut_off(Pointlist_2_ &list, const Line_2 &cutter) { int i; int add = 0; Pointlist_2_rec_ *cur, *last=0, *newrec; for (i=0, cur = list.first; inext) { cur->side = cutter.oriented_side(cur->point); last = cur; } @} Add vertices on the cutter. @$@+=@{@- for (cur = list.first, i=0; inext) { if ((cur->side == ON_POSITIVE_SIDE && last->side == ON_NEGATIVE_SIDE) || (cur->side == ON_NEGATIVE_SIDE && last->side == ON_POSITIVE_SIDE)) { // add a vertex after cur add++; Line_2 l(cur->point, last->point); newrec = new Pointlist_2_rec_; newrec->next = last->next; last->next = newrec; newrec->side = ON_ORIENTED_BOUNDARY; Line_2_Line_2_pair linepair(&cutter, &l); typename Line_2_Line_2_pair::Intersection_results isr; isr = linepair.intersection_type(); CGAL_kernel_assertion(isr == Line_2_Line_2_pair::POINT); linepair.intersection(newrec->point); } last = cur; } CGAL_kernel_assertion(add <= 2); @} remove the vertices on the right side of the line. @$@+=@{@- Pointlist_2_rec_ **curpt; curpt = &list.first; while (*curpt != 0) { cur = *curpt; if (cur->side == ON_NEGATIVE_SIDE) { add--; *curpt = cur->next; delete cur; } else { curpt = &cur->next; } } @} We added two identical points if the original pointlist had two points and was cut by the cutter. Here we repair this. @$@+=@{@- if (list.size == 2 && add == 1) { add = 0; cur = list.first; if (cur->side == ON_ORIENTED_BOUNDARY) { list.first = cur->next; delete cur; } else { last = cur; cur = cur->next; last->next = cur->next; delete cur; } } list.size += add; } template Triangle_2_Triangle_2_pair:: Triangle_2_Triangle_2_pair() { _trian1 = 0; _trian2 = 0; _known = false; } template Triangle_2_Triangle_2_pair:: Triangle_2_Triangle_2_pair(Triangle_2 const *trian1, Triangle_2 const *trian2) { _trian1 = trian1; _trian2 = trian2; _known = false; } #ifndef CGAL_CFG_RETURN_TYPE_BUG_2 template typename Triangle_2_Triangle_2_pair::Intersection_results Triangle_2_Triangle_2_pair::intersection_type() const @ #endif template bool Triangle_2_Triangle_2_pair::intersection( /* Polygon_2 &result */) const { if (!_known) intersection_type(); if (_result != TRIANGLE && _result != POLYGON) return false; Pointlist_2_rec_ *cur; int i; for (i=0, cur = _pointlist.first; i<_pointlist.size; i++, cur = cur->next) { std::cout << to_double(cur->point.x()) << ' '; std::cout << to_double(cur->point.y()) << ' '; } std::cout << std::endl; return true; } template int Triangle_2_Triangle_2_pair::vertex_count() const { CGAL_kernel_assertion(_known); return _pointlist.size; } template Point_2 Triangle_2_Triangle_2_pair::vertex(int n) const { CGAL_kernel_assertion(_known); CGAL_kernel_assertion(n >= 0 && n < _pointlist.size); Pointlist_2_rec_ *cur; int k; for (k=0, cur = _pointlist.first; k < n; k++, cur = cur->next) { } return cur->point; } template bool Triangle_2_Triangle_2_pair::intersection( Triangle_2 &result) const { if (!_known) intersection_type(); if (_result != TRIANGLE) return false; result = Triangle_2(_pointlist.first->point, _pointlist.first->next->point, _pointlist.first->next->next->point); return true; } template bool Triangle_2_Triangle_2_pair::intersection( Segment_2 &seg) const { if (!_known) intersection_type(); if (_result != SEGMENT) return false; seg = Segment_2(_pointlist.first->point, _pointlist.first->next->point); return true; } template bool Triangle_2_Triangle_2_pair::intersection( Point_2 &pt) const { if (!_known) intersection_type(); if (_result != POINT) return false; pt = _pointlist.first->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(_trian1->bbox(), _trian2->bbox())) { _result = NO; return _result; } _init_list(_pointlist, *_trian1); if (_trian2->is_degenerate()) { // _not_implemented(); CGAL_kernel_assertion(false); } else { Line_2 l(_trian2->vertex(0), _trian2->vertex(1)); if (l.oriented_side(_trian2->vertex(2)) == ON_POSITIVE_SIDE) { // counterclockwise triangle _cut_off(_pointlist, l); l = Line_2(_trian2->vertex(1), _trian2->vertex(2)); _cut_off(_pointlist, l); l = Line_2(_trian2->vertex(2), _trian2->vertex(0)); _cut_off(_pointlist, l); } else { l = l.opposite(); _cut_off(_pointlist, l); l = Line_2(_trian2->vertex(0), _trian2->vertex(2)); _cut_off(_pointlist, l); l = Line_2(_trian2->vertex(2), _trian2->vertex(1)); _cut_off(_pointlist, l); } } switch (_pointlist.size) { case 0: _result = NO; break; case 1: _result = POINT; break; case 2: _result = SEGMENT; break; case 3: _result = TRIANGLE; break; default: _result = POLYGON; } return _result; } @} @B@ @O@<../include/CGAL/Triangle_2_Line_2_intersection.h@>==@{ @@(@- include/CGAL/Triangle_2_Line_2_intersection.h@,@- intersection_2_2.fw@,@- Geert-Jan Giezeman@,@- MPI, Saarbruecken@) #include @} @O@<../include/CGAL/Line_2_Triangle_2_intersection.h@>==@{ @@(@- include/CGAL/Line_2_Triangle_2_intersection.h@,@- intersection_2_2.fw@,@- Geert-Jan Giezeman@,@- Saarbruecken@) #ifndef CGAL_LINE_2_TRIANGLE_2_INTERSECTION_H #define CGAL_LINE_2_TRIANGLE_2_INTERSECTION_H #include #include #include #include CGAL_BEGIN_NAMESPACE template class Line_2_Triangle_2_pair { public: enum Intersection_results {NO, POINT, SEGMENT}; Line_2_Triangle_2_pair() ; Line_2_Triangle_2_pair(Line_2 const *line, Triangle_2 const *trian); ~Line_2_Triangle_2_pair() {} #ifdef 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: Line_2 const*_line; Triangle_2 const * _trian; mutable bool _known; mutable Intersection_results _result; mutable Point_2 _intersection_point; mutable Point_2 _other_point; }; @@(Line_2@,Triangle_2@) CGAL_END_NAMESPACE @ #include CGAL_BEGIN_NAMESPACE template Object intersection(const Line_2 &line, const Triangle_2&tr) { typedef Line_2_Triangle_2_pair is_t; is_t ispair(&line, &tr); 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 Triangle_2_Line_2_pair : public Line_2_Triangle_2_pair { public: Triangle_2_Line_2_pair( Triangle_2 const *trian, Line_2 const *line) : Line_2_Triangle_2_pair(line, trian) {} }; @@(Triangle_2@,Line_2@) template inline Object intersection(const Triangle_2 &tr, const Line_2 &line) { return intersection(line, tr); } CGAL_END_NAMESPACE #endif @} @$@==@{ #include #include #include CGAL_BEGIN_NAMESPACE template Line_2_Triangle_2_pair:: Line_2_Triangle_2_pair() { _known = false; _line = 0; _trian = 0; } template Line_2_Triangle_2_pair:: Line_2_Triangle_2_pair(Line_2 const *line, Triangle_2 const *trian) { _known = false; _line = line; _trian = trian; } #ifndef CGAL_CFG_RETURN_TYPE_BUG_2 template typename Line_2_Triangle_2_pair::Intersection_results Line_2_Triangle_2_pair::intersection_type() const @ #endif // CGAL_CFG_RETURN_TYPE_BUG_2 template bool Line_2_Triangle_2_pair:: intersection(Point_2 &result) const { if (!_known) intersection_type(); if (_result != POINT) return false; result = _intersection_point; return true; } template bool Line_2_Triangle_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; Straight_2_ straight(*_line); Line_2 l(_trian->vertex(0), _trian->vertex(1)); if (l.oriented_side(_trian->vertex(2)) == ON_POSITIVE_SIDE) { // if (_trian->is_counterclockwise()) { straight.cut_right_off( Line_2(_trian->vertex(0), _trian->vertex(1))); straight.cut_right_off( Line_2(_trian->vertex(1), _trian->vertex(2))); straight.cut_right_off( Line_2(_trian->vertex(2), _trian->vertex(0))); } else { straight.cut_right_off( Line_2(_trian->vertex(2), _trian->vertex(1))); straight.cut_right_off( Line_2(_trian->vertex(1), _trian->vertex(0))); straight.cut_right_off( Line_2(_trian->vertex(0), _trian->vertex(2))); } switch (straight.current_state()) { case Straight_2_::EMPTY: _result = NO; return _result; case Straight_2_::POINT: { straight.current(_intersection_point); _result = POINT; return _result; } case Straight_2_::SEGMENT: { Segment_2 seg; straight.current(seg); _intersection_point = seg.start(); _other_point = seg.end(); _result = SEGMENT; return _result; } default: // should not happen. CGAL_kernel_assertion_msg(false, "Internal CGAL error."); _result = NO; return _result; } } @} @O@<../include/CGAL/Triangle_2_Ray_2_intersection.h@>==@{ @@(@- include/CGAL/Triangle_2_Ray_2_intersection.h@,@- intersection_2_2.fw@,@- Geert-Jan Giezeman@,@- MPI, Saarbruecken@) #include @} @O@<../include/CGAL/Ray_2_Triangle_2_intersection.h@>==@{ @@(@- include/CGAL/Ray_2_Triangle_2_intersection.h@,@- intersection_2_2.fw@,@- Geert-Jan Giezeman@,@- Saarbruecken@) #ifndef CGAL_RAY_2_TRIANGLE_2_INTERSECTION_H #define CGAL_RAY_2_TRIANGLE_2_INTERSECTION_H #include #include #include #include CGAL_BEGIN_NAMESPACE template class Ray_2_Triangle_2_pair { public: enum Intersection_results {NO, POINT, SEGMENT}; Ray_2_Triangle_2_pair() ; Ray_2_Triangle_2_pair(Ray_2 const *ray, Triangle_2 const *trian); ~Ray_2_Triangle_2_pair() {} #ifdef 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; Triangle_2 const * _trian; mutable bool _known; mutable Intersection_results _result; mutable Point_2 _intersection_point; mutable Point_2 _other_point; }; @@(Ray_2@,Triangle_2@) CGAL_END_NAMESPACE @<2D Ray Triangle intersection implementation@> #include CGAL_BEGIN_NAMESPACE template Object intersection(const Ray_2 &ray, const Triangle_2&tr) { typedef Ray_2_Triangle_2_pair is_t; is_t ispair(&ray, &tr); 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 Triangle_2_Ray_2_pair : public Ray_2_Triangle_2_pair { public: Triangle_2_Ray_2_pair( Triangle_2 const *trian, Ray_2 const *ray) : Ray_2_Triangle_2_pair(ray, trian) {} }; @@(Triangle_2@,Ray_2@) template inline Object intersection(const Triangle_2 &tr, const Ray_2 &ray) { return intersection(ray, tr); } CGAL_END_NAMESPACE #endif @} @$@<2D Ray Triangle intersection implementation@>==@{ #include #include #include #include CGAL_BEGIN_NAMESPACE template Ray_2_Triangle_2_pair:: Ray_2_Triangle_2_pair() { _known = false; _ray = 0; _trian = 0; } template Ray_2_Triangle_2_pair:: Ray_2_Triangle_2_pair(Ray_2 const *ray, Triangle_2 const *trian) { _known = false; _ray = ray; _trian = trian; } #ifndef CGAL_CFG_RETURN_TYPE_BUG_2 template typename Ray_2_Triangle_2_pair::Intersection_results Ray_2_Triangle_2_pair::intersection_type() const @ #endif // CGAL_CFG_RETURN_TYPE_BUG_2 template bool Ray_2_Triangle_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_Triangle_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; Straight_2_ straight(*_ray); Line_2 l(_trian->vertex(0), _trian->vertex(1)); if (l.oriented_side(_trian->vertex(2)) == ON_POSITIVE_SIDE) { // if (_trian->is_counterclockwise()) { straight.cut_right_off( Line_2(_trian->vertex(0), _trian->vertex(1))); straight.cut_right_off( Line_2(_trian->vertex(1), _trian->vertex(2))); straight.cut_right_off( Line_2(_trian->vertex(2), _trian->vertex(0))); } else { straight.cut_right_off( Line_2(_trian->vertex(2), _trian->vertex(1))); straight.cut_right_off( Line_2(_trian->vertex(1), _trian->vertex(0))); straight.cut_right_off( Line_2(_trian->vertex(0), _trian->vertex(2))); } switch (straight.current_state()) { case Straight_2_::EMPTY: _result = NO; return _result; case Straight_2_::POINT: { straight.current(_intersection_point); _result = POINT; return _result; } case Straight_2_::SEGMENT: { Segment_2 seg; straight.current(seg); _intersection_point = seg.start(); _other_point = seg.end(); _result = SEGMENT; return _result; } default: // should not happen. CGAL_kernel_assertion_msg(false, "Internal CGAL error."); _result = NO; return _result; } } @} @O@<../include/CGAL/Triangle_2_Segment_2_intersection.h@>==@{ @@(@- include/CGAL/Triangle_2_Segment_2_intersection.h@,@- intersection_2_2.fw@,@- Geert-Jan Giezeman@,@- MPI, Saarbruecken@) #include @} @O@<../include/CGAL/Segment_2_Triangle_2_intersection.h@>==@{ @@(@- include/CGAL/Segment_2_Triangle_2_intersection.h@,@- intersection_2_2.fw@,@- Geert-Jan Giezeman@,@- Saarbruecken@) #ifndef CGAL_SEGMENT_2_TRIANGLE_2_INTERSECTION_H #define CGAL_SEGMENT_2_TRIANGLE_2_INTERSECTION_H #include #include #include CGAL_BEGIN_NAMESPACE template class Segment_2_Triangle_2_pair { public: enum Intersection_results {NO, POINT, SEGMENT}; Segment_2_Triangle_2_pair() ; Segment_2_Triangle_2_pair(Segment_2 const *seg, Triangle_2 const *trian); ~Segment_2_Triangle_2_pair() {} #ifdef 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; Triangle_2 const * _trian; mutable bool _known; mutable Intersection_results _result; mutable Point_2 _intersection_point; mutable Point_2 _other_point; }; @@(Segment_2@,Triangle_2@) CGAL_END_NAMESPACE @ #include CGAL_BEGIN_NAMESPACE template Object intersection(const Segment_2 &seg, const Triangle_2&tr) { typedef Segment_2_Triangle_2_pair is_t; is_t ispair(&seg, &tr); 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 Triangle_2_Segment_2_pair : public Segment_2_Triangle_2_pair { public: Triangle_2_Segment_2_pair( Triangle_2 const *trian, Segment_2 const *seg) : Segment_2_Triangle_2_pair(seg, trian) {} }; @@(Triangle_2@,Segment_2@) template inline Object intersection(const Triangle_2 &tr, const Segment_2 &seg) { return intersection(seg, tr); } CGAL_END_NAMESPACE #endif @} @$@==@{ #include #include #include #include CGAL_BEGIN_NAMESPACE template Segment_2_Triangle_2_pair:: Segment_2_Triangle_2_pair() { _known = false; _seg = 0; _trian = 0; } template Segment_2_Triangle_2_pair:: Segment_2_Triangle_2_pair(Segment_2 const *seg, Triangle_2 const *trian) { _known = false; _seg = seg; _trian = trian; } #ifndef CGAL_CFG_RETURN_TYPE_BUG_2 template typename Segment_2_Triangle_2_pair::Intersection_results Segment_2_Triangle_2_pair::intersection_type() const @ #endif // CGAL_CFG_RETURN_TYPE_BUG_2 template bool Segment_2_Triangle_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_Triangle_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; Straight_2_ straight(*_seg); Line_2 l(_trian->vertex(0), _trian->vertex(1)); if (l.oriented_side(_trian->vertex(2)) == ON_POSITIVE_SIDE) { straight.cut_right_off( Line_2(_trian->vertex(0), _trian->vertex(1))); straight.cut_right_off( Line_2(_trian->vertex(1), _trian->vertex(2))); straight.cut_right_off( Line_2(_trian->vertex(2), _trian->vertex(0))); } else { straight.cut_right_off( Line_2(_trian->vertex(2), _trian->vertex(1))); straight.cut_right_off( Line_2(_trian->vertex(1), _trian->vertex(0))); straight.cut_right_off( Line_2(_trian->vertex(0), _trian->vertex(2))); } switch (straight.current_state()) { case Straight_2_::EMPTY: _result = NO; return _result; case Straight_2_::POINT: { straight.current(_intersection_point); _result = POINT; return _result; } case Straight_2_::SEGMENT: { Segment_2 seg; straight.current(seg); _intersection_point = seg.start(); _other_point = seg.end(); _result = SEGMENT; return _result; } default: // should not happen. CGAL_kernel_assertion_msg(false, "Internal CGAL error."); _result = NO; return _result; } } @} @O@<../include/CGAL/Triangle_2_Point_2_intersection.h@>==@{ @@(@- include/CGAL/Triangle_2_Point_2_intersection.h@,@- intersection_2_2.fw@,@- Geert-Jan Giezeman@,@- MPI, Saarbruecken@) #include @} @O@<../include/CGAL/Point_2_Triangle_2_intersection.h@>==@{ @@(@- include/CGAL/Point_2_Triangle_2_intersection.h@,@- intersection_2_2.fw@,@- Geert-Jan Giezeman@,@- Saarbruecken@) #ifndef CGAL_POINT_2_TRIANGLE_2_INTERSECTION_H #define CGAL_POINT_2_TRIANGLE_2_INTERSECTION_H #include #include #include CGAL_BEGIN_NAMESPACE template class Point_2_Triangle_2_pair { public: enum Intersection_results {NO, POINT}; Point_2_Triangle_2_pair() ; Point_2_Triangle_2_pair(Point_2 const *pt, Triangle_2 const *trian); ~Point_2_Triangle_2_pair() {} #ifdef 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; protected: Point_2 const * _pt; Triangle_2 const * _trian; mutable bool _known; mutable Intersection_results _result; mutable Point_2 _intersection_point; mutable Point_2 _other_point; }; @@(Point_2@,Triangle_2@) CGAL_END_NAMESPACE @ #include CGAL_BEGIN_NAMESPACE template Object intersection(const Point_2 &pt, const Triangle_2&tr) { typedef Point_2_Triangle_2_pair is_t; is_t ispair(&pt, &tr); switch (ispair.intersection_type()) { case is_t::NO: default: return Object(); case is_t::POINT: { return make_object(pt); } } } template class Triangle_2_Point_2_pair : public Point_2_Triangle_2_pair { public: Triangle_2_Point_2_pair( Triangle_2 const *trian, Point_2 const *pt) : Point_2_Triangle_2_pair(pt, trian) {} }; @@(Triangle_2@,Point_2@) template inline Object intersection(const Triangle_2 &tr, const Point_2 &pt) { return intersection(pt, tr); } CGAL_END_NAMESPACE #endif @} @$@==@{ #include #include #include #include CGAL_BEGIN_NAMESPACE template Point_2_Triangle_2_pair:: Point_2_Triangle_2_pair() { _known = false; _pt = 0; _trian = 0; } template Point_2_Triangle_2_pair:: Point_2_Triangle_2_pair(Point_2 const *pt, Triangle_2 const *trian) { _known = false; _pt = pt; _trian = trian; } #ifndef CGAL_CFG_RETURN_TYPE_BUG_2 template typename Point_2_Triangle_2_pair::Intersection_results Point_2_Triangle_2_pair::intersection_type() const @ #endif // CGAL_CFG_RETURN_TYPE_BUG_2 template bool Point_2_Triangle_2_pair:: intersection(Point_2 &result) const { if (!_known) intersection_type(); if (_result != POINT) return false; result = *_pt; return true; } CGAL_END_NAMESPACE @} @$@@M==@{@- { typedef Line_2 line_t; if (_known) return _result; // The non const this pointer is used to cast away const. _known = true; if (_trian->has_on_unbounded_side(*_pt)) { _result = NO; } else { _result = POINT; } return _result; /* line_t l(_trian->vertex(0), _trian->vertex(1)); if (l.has_on_positive_side(_trian->vertex(2))) { for (int i=0; i<3; i++) { if (line_t(_trian->vertex(i), _trian->vertex(i+1)). has_on_negative_side(*_pt)) { _result = NO; return _result; } } } else { for (int i=0; i<3; i++) if(line_t(_trian->vertex(i), _trian->vertex(i-1)). has_on_negative_side(*_pt)){ _result = NO; return _result; } } */ } @} @B@ @O@<../include/CGAL/Iso_rectangle_2_Line_2_intersection.h@>==@{ @@(@- include/CGAL/Iso_rectangle_2_Line_2_intersection.h@,@- intersection_2_2.fw@,@- Geert-Jan Giezeman@,@- MPI, Saarbruecken@) #include @} @O@<../include/CGAL/Line_2_Iso_rectangle_2_intersection.h@>==@{ @@(@- include/CGAL/Line_2_Iso_rectangle_2_intersection.h@,@- intersection_2_2.fw@,@- Geert-Jan Giezeman@,@- Saarbruecken@) #ifndef CGAL_LINE_2_ISO_RECTANGLE_2_INTERSECTION_H #define CGAL_LINE_2_ISO_RECTANGLE_2_INTERSECTION_H #include #include CGAL_BEGIN_NAMESPACE template class Line_2_Iso_rectangle_2_pair { public: enum Intersection_results {NO, POINT, SEGMENT}; Line_2_Iso_rectangle_2_pair() ; Line_2_Iso_rectangle_2_pair(Line_2 const *pt, Iso_rectangle_2 const *iso); ~Line_2_Iso_rectangle_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: Point_2 _ref_point; Vector_2 _dir; Point_2 _isomin; Point_2 _isomax; mutable bool _known; mutable Intersection_results _result; mutable typename R::FT _min, _max; }; @@(Line_2@,Iso_rectangle_2@) CGAL_END_NAMESPACE @ #include CGAL_BEGIN_NAMESPACE template Object intersection(const Line_2 &line, const Iso_rectangle_2&iso) { typedef Line_2_Iso_rectangle_2_pair is_t; is_t ispair(&line, &iso); switch (ispair.intersection_type()) { case is_t::NO: default: return Object(); case is_t::POINT: { Point_2 ipt; ispair.intersection(ipt); return make_object(ipt); } case is_t::SEGMENT: { Segment_2 iseg; ispair.intersection(iseg); return make_object(iseg); } } } template class Iso_rectangle_2_Line_2_pair : public Line_2_Iso_rectangle_2_pair { public: Iso_rectangle_2_Line_2_pair( Iso_rectangle_2 const *iso, Line_2 const *line) : Line_2_Iso_rectangle_2_pair(line, iso) {} }; @@(Iso_rectangle_2@,Line_2@) template inline Object intersection(const Iso_rectangle_2&iso, const Line_2&line) { return intersection(line, iso); } CGAL_END_NAMESPACE #endif @} @$@==@{ #include #include #include CGAL_BEGIN_NAMESPACE template Line_2_Iso_rectangle_2_pair:: Line_2_Iso_rectangle_2_pair() { _known = false; } template Line_2_Iso_rectangle_2_pair:: Line_2_Iso_rectangle_2_pair(Line_2 const *line, Iso_rectangle_2 const *iso) { _known = false; _ref_point = line->point(); _dir = line->direction().to_vector(); _isomin = iso->min(); _isomax = iso->max(); } #ifndef CGAL_CFG_RETURN_TYPE_BUG_2 template typename Line_2_Iso_rectangle_2_pair::Intersection_results Line_2_Iso_rectangle_2_pair::intersection_type() const @ #endif template bool Line_2_Iso_rectangle_2_pair:: intersection(Point_2 &result) const { if (!_known) intersection_type(); if (_result != POINT) return false; result = _ref_point + _dir * _min; return true; } template bool Line_2_Iso_rectangle_2_pair:: intersection(Segment_2 &result) const { if (!_known) intersection_type(); if (_result != SEGMENT) return false; result = Segment_2(_ref_point + _dir*_min, _ref_point + _dir*_max); 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==@{@- { typedef Line_2 line_t; if (_known) return _result; // The non const this pointer is used to cast away const. _known = true; typedef typename R::FT FT; typedef typename R::RT RT; bool all_values = true; int i; for (i=0; i< _ref_point.dimension(); i++) { if (_dir.homogeneous(i) == RT(0)) { if (_ref_point.cartesian(i) < _isomin.cartesian(i)) { _result = NO; return NO; } if (_ref_point.cartesian(i) > _isomax.cartesian(i)) { _result = NO; return NO; } } else { FT newmin, newmax; if (_dir.homogeneous(i) > RT(0)) { newmin = (_isomin.cartesian(i) - _ref_point.cartesian(i)) / _dir.cartesian(i); newmax = (_isomax.cartesian(i) - _ref_point.cartesian(i)) / _dir.cartesian(i); } else { newmin = (_isomax.cartesian(i) - _ref_point.cartesian(i)) / _dir.cartesian(i); newmax = (_isomin.cartesian(i) - _ref_point.cartesian(i)) / _dir.cartesian(i); } if (all_values) { _min = newmin; _max = newmax; } else { if (newmin > _min) _min = newmin; if (newmax < _max) _max = newmax; if (_max < _min) { _result = NO; return NO; } } all_values = false; } } CGAL_kernel_assertion(!all_values); if (_max == _min) { _result = POINT; return POINT; } _result = SEGMENT; return SEGMENT; } @} @B@<2D Ray Iso_rectangle intersection@> @O@<../include/CGAL/Iso_rectangle_2_Ray_2_intersection.h@>==@{ @@(@- include/CGAL/Iso_rectangle_2_Ray_2_intersection.h@,@- intersection_2_2.fw@,@- Geert-Jan Giezeman@,@- MPI, Saarbruecken@) #include @} @O@<../include/CGAL/Ray_2_Iso_rectangle_2_intersection.h@>==@{ @@(@- include/CGAL/Ray_2_Iso_rectangle_2_intersection.h@,@- intersection_2_2.fw@,@- Geert-Jan Giezeman@,@- Saarbruecken@) #ifndef CGAL_RAY_2_ISO_RECTANGLE_2_INTERSECTION_H #define CGAL_RAY_2_ISO_RECTANGLE_2_INTERSECTION_H #include #include #include #include #include #include CGAL_BEGIN_NAMESPACE template class Ray_2_Iso_rectangle_2_pair { public: enum Intersection_results {NO, POINT, SEGMENT}; Ray_2_Iso_rectangle_2_pair() ; Ray_2_Iso_rectangle_2_pair(Ray_2 const *ray, Iso_rectangle_2 const *rect) ; #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: mutable bool _known; mutable Intersection_results _result; mutable Point_2 _ref_point; mutable Vector_2 _dir; mutable Point_2 _isomin; mutable Point_2 _isomax; mutable typename R::FT _min, _max; }; @@(Ray_2@,Iso_rectangle_2@) CGAL_END_NAMESPACE #include CGAL_BEGIN_NAMESPACE template Object intersection( const Ray_2 &ray, const Iso_rectangle_2 &iso) { typedef Ray_2_Iso_rectangle_2_pair is_t; is_t ispair(&ray, &iso); switch (ispair.intersection_type()) { case is_t::NO: default: return Object(); case is_t::POINT: { Point_2 ipt; ispair.intersection(ipt); return make_object(ipt); } case is_t::SEGMENT: { Segment_2 iseg; ispair.intersection(iseg); return make_object(iseg); } } } CGAL_END_NAMESPACE @ CGAL_BEGIN_NAMESPACE template class Iso_rectangle_2_Ray_2_pair: public Ray_2_Iso_rectangle_2_pair { public: Iso_rectangle_2_Ray_2_pair() {} Iso_rectangle_2_Ray_2_pair(Iso_rectangle_2 const *rect, Ray_2 const *ray) :Ray_2_Iso_rectangle_2_pair (ray, rect){} }; @@(Iso_rectangle_2@,Ray_2@) template inline Object intersection(const Iso_rectangle_2&iso, const Ray_2&ray) { return intersection(ray, iso); } CGAL_END_NAMESPACE #endif // CGAL_RAY_2_iSO_RECTANGLE_2_INTERSECTION_H @} @$@==@{ CGAL_BEGIN_NAMESPACE template Ray_2_Iso_rectangle_2_pair::Ray_2_Iso_rectangle_2_pair() { _known = false; } template Ray_2_Iso_rectangle_2_pair:: Ray_2_Iso_rectangle_2_pair( Ray_2 const *ray, Iso_rectangle_2 const *iso) { _known = false; _isomin = iso->min(); _isomax = iso->max(); _ref_point = ray->start(); _dir = ray->direction().to_vector(); _min = (typename R::FT)(0); } #ifndef CGAL_CFG_RETURN_TYPE_BUG_2 template typename Ray_2_Iso_rectangle_2_pair::Intersection_results Ray_2_Iso_rectangle_2_pair::intersection_type() const @ #endif // CGAL_CFG_RETURN_TYPE_BUG_2 template bool Ray_2_Iso_rectangle_2_pair:: intersection(Segment_2 &seg) const { if (!_known) intersection_type(); if (_result != SEGMENT) return false; Point_2 p1(_ref_point + _dir*_min); Point_2 p2(_ref_point + _dir*_max); seg = Segment_2(p1, p2); return true; } template bool Ray_2_Iso_rectangle_2_pair:: intersection(Point_2 &pt) const { if (!_known) intersection_type(); if (_result != POINT) return false; pt = Point_2(_ref_point + _dir*_min); return true; } CGAL_END_NAMESPACE @} @$@@M==@{@- { typedef typename R::RT RT; typedef typename R::FT FT; if (_known) return _result; _known = true; bool to_infinity = true; for (int i=0; i<_ref_point.dimension(); i++) { if (_dir.homogeneous(i) == RT(0)) { if (_ref_point.cartesian(i) < _isomin.cartesian(i)) { _result = NO; return _result; } if (_ref_point.cartesian(i) > _isomax.cartesian(i)) { _result = NO; return _result; } } else { FT newmin, newmax; if (_dir.homogeneous(i) > RT(0)) { newmin = (_isomin.cartesian(i)-_ref_point.cartesian(i)) / _dir.cartesian(i); newmax = (_isomax.cartesian(i)-_ref_point.cartesian(i)) / _dir.cartesian(i); } else { newmin = (_isomax.cartesian(i)-_ref_point.cartesian(i)) / _dir.cartesian(i); newmax = (_isomin.cartesian(i)-_ref_point.cartesian(i)) / _dir.cartesian(i); } if (newmin > _min) _min = newmin; if (to_infinity) { _max = newmax; } else { if (newmax < _max) _max = newmax; } if (_max < _min) { _result = NO; return _result; } to_infinity = false; } } CGAL_kernel_assertion(!to_infinity); if (_max == _min) { _result = POINT; return _result; } _result = SEGMENT; return _result; } @} @B@<2D Segment Iso_rectangle intersection@> @O@<../include/CGAL/Iso_rectangle_2_Segment_2_intersection.h@>==@{ @@(@- include/CGAL/Iso_rectangle_2_Segment_2_intersection.h@,@- intersection_2_2.fw@,@- Geert-Jan Giezeman@,@- MPI, Saarbruecken@) #include @} @O@<../include/CGAL/Segment_2_Iso_rectangle_2_intersection.h@>==@{ @@(@- include/CGAL/Segment_2_Iso_rectangle_2_intersection.h@,@- intersection_2_2.fw@,@- Geert-Jan Giezeman@,@- Saarbruecken@) #ifndef CGAL_SEGMENT_2_ISO_RECTANGLE_2_INTERSECTION_H #define CGAL_SEGMENT_2_ISO_RECTANGLE_2_INTERSECTION_H #include #include #include #include #include CGAL_BEGIN_NAMESPACE template class Segment_2_Iso_rectangle_2_pair { public: enum Intersection_results {NO, POINT, SEGMENT}; Segment_2_Iso_rectangle_2_pair() ; Segment_2_Iso_rectangle_2_pair(Segment_2 const *seg, Iso_rectangle_2 const *rect) ; #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: mutable bool _known; mutable Intersection_results _result; mutable Point_2 _ref_point; mutable Vector_2 _dir; mutable Point_2 _isomin; mutable Point_2 _isomax; mutable typename R::FT _min, _max; }; @@(Segment_2@,Iso_rectangle_2@) CGAL_END_NAMESPACE #include CGAL_BEGIN_NAMESPACE template Object intersection( const Segment_2 &seg, const Iso_rectangle_2 &iso) { typedef Segment_2_Iso_rectangle_2_pair is_t; is_t ispair(&seg, &iso); switch (ispair.intersection_type()) { case is_t::NO: default: return Object(); case is_t::POINT: { Point_2 ipt; ispair.intersection(ipt); return make_object(ipt); } case is_t::SEGMENT: { Segment_2 iseg; ispair.intersection(iseg); return make_object(iseg); } } } CGAL_END_NAMESPACE @ CGAL_BEGIN_NAMESPACE template class Iso_rectangle_2_Segment_2_pair: public Segment_2_Iso_rectangle_2_pair { public: Iso_rectangle_2_Segment_2_pair() {} Iso_rectangle_2_Segment_2_pair(Iso_rectangle_2 const *rect, Segment_2 const *seg) :Segment_2_Iso_rectangle_2_pair (seg, rect){} }; @@(Iso_rectangle_2@,Segment_2@) template inline Object intersection( const Iso_rectangle_2&iso, const Segment_2&seg) { return intersection(seg, iso); } CGAL_END_NAMESPACE #endif // CGAL_SEGMENT_2_ISO_RECTANGLE_2_INTERSECTION_H @} @$@==@{ CGAL_BEGIN_NAMESPACE template Segment_2_Iso_rectangle_2_pair::Segment_2_Iso_rectangle_2_pair() { _known = false; } template Segment_2_Iso_rectangle_2_pair:: Segment_2_Iso_rectangle_2_pair( Segment_2 const *seg, Iso_rectangle_2 const *iso) { _known = false; _isomin = iso->min(); _isomax = iso->max(); _ref_point = seg->source(); _dir = seg->direction().to_vector(); _min = (typename R::FT)(0); int main_dir = (CGAL_NTS abs(_dir.x()) > CGAL_NTS abs(_dir.y()) ) ? 0 : 1; _max = (seg->target().cartesian(main_dir)-_ref_point.cartesian(main_dir)) / _dir.cartesian(main_dir); } #ifndef CGAL_CFG_RETURN_TYPE_BUG_2 template typename Segment_2_Iso_rectangle_2_pair::Intersection_results Segment_2_Iso_rectangle_2_pair::intersection_type() const @ #endif // CGAL_CFG_RETURN_TYPE_BUG_2 template bool Segment_2_Iso_rectangle_2_pair:: intersection(Segment_2 &seg) const { if (!_known) intersection_type(); if (_result != SEGMENT) return false; Point_2 p1(_ref_point + _dir*_min); Point_2 p2(_ref_point + _dir*_max); seg = Segment_2(p1, p2); return true; } template bool Segment_2_Iso_rectangle_2_pair:: intersection(Point_2 &pt) const { if (!_known) intersection_type(); if (_result != POINT) return false; pt = Point_2(_ref_point + _dir*_min); return true; } CGAL_END_NAMESPACE @} @$@@M==@{@- { typedef typename R::RT RT; typedef typename R::FT FT; if (_known) return _result; _known = true; for (int i=0; i<_ref_point.dimension(); i++) { if (_dir.homogeneous(i) == RT(0)) { if (_ref_point.cartesian(i) < _isomin.cartesian(i)) { _result = NO; return _result; } if (_ref_point.cartesian(i) > _isomax.cartesian(i)) { _result = NO; return _result; } } else { FT newmin, newmax; if (_dir.homogeneous(i) > RT(0)) { newmin = (_isomin.cartesian(i)-_ref_point.cartesian(i)) / _dir.cartesian(i); newmax = (_isomax.cartesian(i)-_ref_point.cartesian(i)) / _dir.cartesian(i); } else { newmin = (_isomax.cartesian(i)-_ref_point.cartesian(i)) / _dir.cartesian(i); newmax = (_isomin.cartesian(i)-_ref_point.cartesian(i)) / _dir.cartesian(i); } if (newmin > _min) _min = newmin; if (newmax < _max) _max = newmax; if (_max < _min) { _result = NO; return _result; } } } if (_max == _min) { _result = POINT; return _result; } _result = SEGMENT; return _result; } @} @B@<2D Point Iso_rectangle intersection@> @O@<../include/CGAL/Iso_rectangle_2_Point_2_intersection.h@>==@{ @@(@- include/CGAL/Iso_rectangle_2_Point_2_intersection.h@,@- intersection_2_2.fw@,@- Geert-Jan Giezeman@,@- MPI, Saarbruecken@) #include @} @O@<../include/CGAL/Point_2_Iso_rectangle_2_intersection.h@>==@{ @@(@- include/CGAL/Point_2_Iso_rectangle_2_intersection.h@,@- intersection_2_2.fw@,@- Geert-Jan Giezeman@,@- Saarbruecken@) #ifndef CGAL_POINT_2_ISO_RECTANGLE_2_INTERSECTION_H #define CGAL_POINT_2_ISO_RECTANGLE_2_INTERSECTION_H #include #include CGAL_BEGIN_NAMESPACE template inline bool do_intersect( const Point_2 &pt, const Iso_rectangle_2 &iso) { return !iso.has_on_unbounded_side(pt); } CGAL_END_NAMESPACE #include CGAL_BEGIN_NAMESPACE template Object intersection( const Point_2 &pt, const Iso_rectangle_2 &iso) { if (do_intersect(pt,iso)) { return make_object(pt); } return Object(); } template inline bool do_intersect( const Iso_rectangle_2 &iso, const Point_2 &pt) { return !iso.has_on_unbounded_side(pt); } template inline Object intersection( const Iso_rectangle_2 &iso, const Point_2 &pt) { if (do_intersect(pt, iso)) { return make_object(pt); } return Object(); } CGAL_END_NAMESPACE #endif @} @O@<../include/CGAL/Iso_rectangle_2_Iso_rectangle_2_intersection.h@>==@{ @@(@- include/CGAL/Iso_rectangle_2_Iso_rectangle_2_intersection.h@,@- intersection_2_2.fw@,@- Geert-Jan Giezeman@,@- Saarbruecken@) #ifndef CGAL_ISO_RECTANGLE_2_ISO_RECTANGLE_2_INTERSECTION_H #define CGAL_ISO_RECTANGLE_2_ISO_RECTANGLE_2_INTERSECTION_H #include #include CGAL_BEGIN_NAMESPACE template Object intersection( const Iso_rectangle_2 &irect1, const Iso_rectangle_2 &irect2) { const Point_2 &min1 = irect1.min(); const Point_2 &min2 = irect2.min(); const Point_2 &max1 = irect1.max(); const Point_2 &max2 = irect2.max(); typename R::FT minx, miny, maxx, maxy; Point_2 newmin; Point_2 newmax; minx = (min1.x() >= min2.x()) ? min1.x() : min2.x(); maxx = (max1.x() <= max2.x()) ? max1.x() : max2.x(); if (maxx < minx) return Object(); miny = (min1.y() >= min2.y()) ? min1.y() : min2.y(); maxy = (max1.y() <= max2.y()) ? max1.y() : max2.y(); if (maxy < miny) return Object(); if (R::FT_denominator(minx) == R::FT_denominator(miny)) { newmin = Point_2(R::FT_numerator(minx), R::FT_numerator(miny), R::FT_denominator(minx)); } else { newmin = Point_2(R::FT_numerator(minx)*R::FT_denominator(miny), R::FT_numerator(miny)*R::FT_denominator(minx), R::FT_denominator(minx) * R::FT_denominator(miny)); } if (R::FT_denominator(maxx) == R::FT_denominator(maxy)) { newmax = Point_2(R::FT_numerator(maxx), R::FT_numerator(maxy), R::FT_denominator(maxx)); } else { newmax = Point_2(R::FT_numerator(maxx)*R::FT_denominator(maxy), R::FT_numerator(maxy)*R::FT_denominator(maxx), R::FT_denominator(maxx) * R::FT_denominator(maxy)); } return make_object(Iso_rectangle_2(newmin, newmax)); } template inline bool do_intersect( const Iso_rectangle_2 &irect1, const Iso_rectangle_2 &irect2) { Object obj(intersection(irect1, irect2)); Iso_rectangle_2 irect; return (assign(irect, obj)); } CGAL_END_NAMESPACE #endif @} @B@ @O@<../include/CGAL/intersection_2_2.h@>==@{@- @@(@- include/CGAL/intersection_2_2.h@,@- intersection_2_2.fw@,@- Geert-Jan Giezeman@,@- Saarbruecken@) #ifndef CGAL_INTERSECTION_2_2_H #define CGAL_INTERSECTION_2_2_H #include #include #include #include #include #include #include #include #include #endif @}