@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 #ifndef CGAL_OBJECT_H #include #endif // CGAL_OBJECT_H template CGAL_Object CGAL_intersection(const CGAL_Triangle_2 &tr1, const CGAL_Triangle_2&tr2); template bool CGAL_do_intersect(const CGAL_Triangle_2 &tr1, const CGAL_Triangle_2&tr2); #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@) #ifndef CGAL_SEGMENT_2_H #include #endif // CGAL_SEGMENT_2_H #ifndef CGAL_TRIANGLE_2_H #include #endif // CGAL_TRIANGLE_2_H template struct CGAL__Pointlist_2_rec { CGAL__Pointlist_2_rec *next; CGAL_Point_2 point; CGAL_Oriented_side side; }; template struct CGAL__Pointlist_2 { int size; CGAL__Pointlist_2_rec *first; CGAL__Pointlist_2() ; ~CGAL__Pointlist_2() ; }; template class CGAL_Triangle_2_Triangle_2_pair { public: enum Intersection_results {NO, POINT, SEGMENT, TRIANGLE, POLYGON}; CGAL_Triangle_2_Triangle_2_pair() ; CGAL_Triangle_2_Triangle_2_pair( CGAL_Triangle_2 const *trian1, CGAL_Triangle_2 const *trian2) ; ~CGAL_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(CGAL_Point_2 &result) const; bool intersection(CGAL_Segment_2 &result) const; bool intersection(CGAL_Triangle_2 &result) const; bool intersection(/*CGAL_Polygon_2 &result*/) const; int vertex_count() const; CGAL_Point_2 vertex(int i) const; protected: CGAL_Triangle_2 const* _trian1; CGAL_Triangle_2 const * _trian2; bool _known; Intersection_results _result; CGAL__Pointlist_2 _pointlist; }; @@(Triangle_2@,Triangle_2@) @ template CGAL_Object CGAL_intersection(const CGAL_Triangle_2 &tr1, const CGAL_Triangle_2&tr2) { typedef CGAL_Triangle_2_Triangle_2_pair is_t; is_t ispair(&tr1, &tr2); switch (ispair.intersection_type()) { case is_t::NO: default: return CGAL_Object(); case is_t::POINT: { CGAL_Point_2 pt; ispair.intersection(pt); return CGAL_Object(new CGAL_Wrapper< CGAL_Point_2 >(pt)); } case is_t::SEGMENT: { CGAL_Segment_2 iseg; ispair.intersection(iseg); return CGAL_Object(new CGAL_Wrapper< CGAL_Segment_2 >(iseg)); } case is_t::TRIANGLE: { CGAL_Triangle_2 itr; ispair.intersection(itr); return CGAL_Object(new CGAL_Wrapper< CGAL_Triangle_2 >(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 CGAL_Object(new CGAL_Wrapper< Container >(points)); } } } @} 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. @$@+=@{ #ifndef CGAL_LINE_2_H #include #endif // CGAL_LINE_2_H #ifndef CGAL_UTILS_H #include #endif // CGAL_UTILS_H #ifndef CGAL_NUMBER_UTILS_H #include #endif // CGAL_NUMBER_UTILS_H #ifndef CGAL_STD_VECTOR_H #include #endif template CGAL__Pointlist_2::CGAL__Pointlist_2() { size = 0; first = 0; } template CGAL__Pointlist_2::~CGAL__Pointlist_2() { CGAL__Pointlist_2_rec *cur; for (int i=0; inext; delete cur; } } @} @$@+=@{ template void CGAL__init_list(CGAL__Pointlist_2 &list, const CGAL_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++) { CGAL__Pointlist_2_rec *newrec = new CGAL__Pointlist_2_rec; newrec->next = list.first; list.first = newrec; newrec->point = trian[i]; } } else { // CGAL__not_implemented(); CGAL_kernel_assertion(false); } } @} @$@+=@{ #ifndef CGAL_LINE_2_LINE_2_INTERSECTION_H #include #endif // CGAL_LINE_2_LINE_2_INTERSECTION_H template void CGAL__cut_off(CGAL__Pointlist_2 &list, const CGAL_Line_2 &cutter) { int i; int add = 0; CGAL__Pointlist_2_rec *cur, *last, *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 == CGAL_ON_POSITIVE_SIDE && last->side == CGAL_ON_NEGATIVE_SIDE) || (cur->side == CGAL_ON_NEGATIVE_SIDE && last->side == CGAL_ON_POSITIVE_SIDE)) { // add a vertex after cur add++; CGAL_Line_2 l(cur->point, last->point); newrec = new CGAL__Pointlist_2_rec; newrec->next = last->next; last->next = newrec; newrec->side = CGAL_ON_ORIENTED_BOUNDARY; CGAL_Line_2_Line_2_pair linepair(&cutter, &l); CGAL_Line_2_Line_2_pair::Intersection_results isr; isr = linepair.intersection_type(); CGAL_kernel_assertion(isr == CGAL_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. @$@+=@{@- CGAL__Pointlist_2_rec **curpt; curpt = &list.first; while (*curpt != 0) { cur = *curpt; if (cur->side == CGAL_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 == CGAL_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 CGAL_Triangle_2_Triangle_2_pair:: CGAL_Triangle_2_Triangle_2_pair() { _trian1 = 0; _trian2 = 0; _known = false; } template CGAL_Triangle_2_Triangle_2_pair:: CGAL_Triangle_2_Triangle_2_pair(CGAL_Triangle_2 const *trian1, CGAL_Triangle_2 const *trian2) { _trian1 = trian1; _trian2 = trian2; _known = false; } #ifndef CGAL_CFG_RETURN_TYPE_BUG_2 template CGAL_Triangle_2_Triangle_2_pair::Intersection_results CGAL_Triangle_2_Triangle_2_pair::intersection_type() const @ #endif template bool CGAL_Triangle_2_Triangle_2_pair::intersection( /* CGAL_Polygon_2 &result */) const { if (!_known) intersection_type(); if (_result != TRIANGLE && _result != POLYGON) return false; CGAL__Pointlist_2_rec *cur; int i; for (i=0, cur = _pointlist.first; i<_pointlist.size; i++, cur = cur->next) { cout << CGAL_to_double(cur->point.x()) << ' '; cout << CGAL_to_double(cur->point.y()) << ' '; } cout << endl; return true; } template int CGAL_Triangle_2_Triangle_2_pair::vertex_count() const { CGAL_kernel_assertion(_known); return _pointlist.size; } template CGAL_Point_2 CGAL_Triangle_2_Triangle_2_pair::vertex(int n) const { CGAL_kernel_assertion(_known); CGAL_kernel_assertion(n >= 0 && n < _pointlist.size); CGAL__Pointlist_2_rec *cur; int k; for (k=0, cur = _pointlist.first; k < n; k++, cur = cur->next) { } return cur->point; } template bool CGAL_Triangle_2_Triangle_2_pair::intersection( CGAL_Triangle_2 &result) const { if (!_known) intersection_type(); if (_result != TRIANGLE) return false; result = CGAL_Triangle_2(_pointlist.first->point, _pointlist.first->next->point, _pointlist.first->next->next->point); return true; } template bool CGAL_Triangle_2_Triangle_2_pair::intersection( CGAL_Segment_2 &seg) const { if (!_known) intersection_type(); if (_result != SEGMENT) return false; seg = CGAL_Segment_2(_pointlist.first->point, _pointlist.first->next->point); return true; } template bool CGAL_Triangle_2_Triangle_2_pair::intersection( CGAL_Point_2 &pt) const { if (!_known) intersection_type(); if (_result != POINT) return false; pt = _pointlist.first->point; return true; } @} @$@@M==@{@- { if (_known) return _result; // The non const this pointer is used to cast away const. CGAL_Triangle_2_Triangle_2_pair *ncthis = (CGAL_Triangle_2_Triangle_2_pair *) this; ncthis->_known = true; if (!CGAL_do_overlap(_trian1->bbox(), _trian2->bbox())) { ncthis->_result = NO; return _result; } CGAL__init_list(ncthis->_pointlist, *_trian1); if (_trian2->is_degenerate()) { // CGAL__not_implemented(); CGAL_kernel_assertion(false); } else { CGAL_Line_2 l(_trian2->vertex(0), _trian2->vertex(1)); if (l.oriented_side(_trian2->vertex(2)) == CGAL_ON_POSITIVE_SIDE) { // counterclockwise triangle CGAL__cut_off(ncthis->_pointlist, l); l = CGAL_Line_2(_trian2->vertex(1), _trian2->vertex(2)); CGAL__cut_off(ncthis->_pointlist, l); l = CGAL_Line_2(_trian2->vertex(2), _trian2->vertex(0)); CGAL__cut_off(ncthis->_pointlist, l); } else { l = l.opposite(); CGAL__cut_off(ncthis->_pointlist, l); l = CGAL_Line_2(_trian2->vertex(0), _trian2->vertex(2)); CGAL__cut_off(ncthis->_pointlist, l); l = CGAL_Line_2(_trian2->vertex(2), _trian2->vertex(1)); CGAL__cut_off(ncthis->_pointlist, l); } } switch (_pointlist.size) { case 0: ncthis->_result = NO; break; case 1: ncthis->_result = POINT; break; case 2: ncthis->_result = SEGMENT; break; case 3: ncthis->_result = TRIANGLE; break; default: ncthis->_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@) #ifndef CGAL_LINE_2_TRIANGLE_2_INTERSECTION_H #include #endif // CGAL_LINE_2_TRIANGLE_2_INTERSECTION_H @} @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 #ifndef CGAL_LINE_2_H #include #endif // CGAL_LINE_2_H #ifndef CGAL_SEGMENT_2_H #include #endif // CGAL_SEGMENT_2_H #ifndef CGAL_TRIANGLE_2_H #include #endif // CGAL_TRIANGLE_2_H #ifndef CGAL_POINT_2_H #include #endif // CGAL_POINT_2_H template class CGAL_Line_2_Triangle_2_pair { public: enum Intersection_results {NO, POINT, SEGMENT}; CGAL_Line_2_Triangle_2_pair() ; CGAL_Line_2_Triangle_2_pair(CGAL_Line_2 const *line, CGAL_Triangle_2 const *trian); ~CGAL_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(CGAL_Point_2 &result) const; bool intersection(CGAL_Segment_2 &result) const; protected: CGAL_Line_2 const*_line; CGAL_Triangle_2 const * _trian; bool _known; Intersection_results _result; CGAL_Point_2 _intersection_point; CGAL_Point_2 _other_point; }; @@(Line_2@,Triangle_2@) @ #ifndef CGAL_OBJECT_H #include #endif // CGAL_OBJECT_H template CGAL_Object CGAL_intersection(const CGAL_Line_2 &line, const CGAL_Triangle_2&tr) { typedef CGAL_Line_2_Triangle_2_pair is_t; is_t ispair(&line, &tr); switch (ispair.intersection_type()) { case is_t::NO: default: return CGAL_Object(); case is_t::POINT: { CGAL_Point_2 pt; ispair.intersection(pt); return CGAL_Object(new CGAL_Wrapper< CGAL_Point_2 >(pt)); } case is_t::SEGMENT: { CGAL_Segment_2 iseg; ispair.intersection(iseg); return CGAL_Object(new CGAL_Wrapper< CGAL_Segment_2 >(iseg)); } } } template class CGAL_Triangle_2_Line_2_pair : public CGAL_Line_2_Triangle_2_pair { public: CGAL_Triangle_2_Line_2_pair( CGAL_Triangle_2 const *trian, CGAL_Line_2 const *line) : CGAL_Line_2_Triangle_2_pair(line, trian) {} }; @@(Triangle_2@,Line_2@) template inline CGAL_Object CGAL_intersection(const CGAL_Triangle_2 &tr, const CGAL_Line_2 &line) { return CGAL_intersection(line, tr); } #endif @} @$@==@{ #ifndef CGAL_STRAIGHT_2_H #include #endif // CGAL_STRAIGHT_2_H #ifndef CGAL_UTILS_H #include #endif // CGAL_UTILS_H #ifndef CGAL_NUMBER_UTILS_H #include #endif // CGAL_NUMBER_UTILS_H template CGAL_Line_2_Triangle_2_pair:: CGAL_Line_2_Triangle_2_pair() { _known = false; _line = 0; _trian = 0; } template CGAL_Line_2_Triangle_2_pair:: CGAL_Line_2_Triangle_2_pair(CGAL_Line_2 const *line, CGAL_Triangle_2 const *trian) { _known = false; _line = line; _trian = trian; } #ifndef CGAL_CFG_RETURN_TYPE_BUG_2 template CGAL_Line_2_Triangle_2_pair::Intersection_results CGAL_Line_2_Triangle_2_pair::intersection_type() const @ #endif // CGAL_CFG_RETURN_TYPE_BUG_2 template bool CGAL_Line_2_Triangle_2_pair:: intersection(CGAL_Point_2 &result) const { if (!_known) intersection_type(); if (_result != POINT) return false; result = _intersection_point; return true; } template bool CGAL_Line_2_Triangle_2_pair:: intersection(CGAL_Segment_2 &result) const { if (!_known) intersection_type(); if (_result != SEGMENT) return false; result = CGAL_Segment_2(_intersection_point, _other_point); return true; } @} @$@@M==@{@- { if (_known) return _result; // The non const this pointer is used to cast away const. CGAL_Line_2_Triangle_2_pair *ncthis = (CGAL_Line_2_Triangle_2_pair *) this; ncthis->_known = true; CGAL__Straight_2 straight(*_line); CGAL_Line_2 l(_trian->vertex(0), _trian->vertex(1)); if (l.oriented_side(_trian->vertex(2)) == CGAL_ON_POSITIVE_SIDE) { // if (_trian->is_counterclockwise()) { straight.cut_right_off( CGAL_Line_2(_trian->vertex(0), _trian->vertex(1))); straight.cut_right_off( CGAL_Line_2(_trian->vertex(1), _trian->vertex(2))); straight.cut_right_off( CGAL_Line_2(_trian->vertex(2), _trian->vertex(0))); } else { straight.cut_right_off( CGAL_Line_2(_trian->vertex(2), _trian->vertex(1))); straight.cut_right_off( CGAL_Line_2(_trian->vertex(1), _trian->vertex(0))); straight.cut_right_off( CGAL_Line_2(_trian->vertex(0), _trian->vertex(2))); } switch (straight.current_state()) { case CGAL__Straight_2::EMPTY: ncthis->_result = NO; return _result; case CGAL__Straight_2::POINT: { straight.current(ncthis->_intersection_point); ncthis->_result = POINT; return _result; } case CGAL__Straight_2::SEGMENT: { CGAL_Segment_2 seg; straight.current(seg); ncthis->_intersection_point = seg.start(); ncthis->_other_point = seg.end(); ncthis->_result = SEGMENT; return _result; } default: // should not happen. CGAL_kernel_assertion_msg(false, "Internal CGAL error."); ncthis->_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@) #ifndef CGAL_RAY_2_TRIANGLE_2_INTERSECTION_H #include #endif // CGAL_RAY_2_TRIANGLE_2_INTERSECTION_H @} @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 #ifndef CGAL_SEGMENT_2_H #include #endif // CGAL_SEGMENT_2_H #ifndef CGAL_RAY_2_H #include #endif // CGAL_RAY_2_H #ifndef CGAL_TRIANGLE_2_H #include #endif // CGAL_TRIANGLE_2_H #ifndef CGAL_POINT_2_H #include #endif // CGAL_POINT_2_H template class CGAL_Ray_2_Triangle_2_pair { public: enum Intersection_results {NO, POINT, SEGMENT}; CGAL_Ray_2_Triangle_2_pair() ; CGAL_Ray_2_Triangle_2_pair(CGAL_Ray_2 const *ray, CGAL_Triangle_2 const *trian); ~CGAL_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(CGAL_Point_2 &result) const; bool intersection(CGAL_Segment_2 &result) const; protected: CGAL_Ray_2 const* _ray; CGAL_Triangle_2 const * _trian; bool _known; Intersection_results _result; CGAL_Point_2 _intersection_point; CGAL_Point_2 _other_point; }; @@(Ray_2@,Triangle_2@) @<2D Ray Triangle intersection implementation@> #ifndef CGAL_OBJECT_H #include #endif // CGAL_OBJECT_H template CGAL_Object CGAL_intersection(const CGAL_Ray_2 &ray, const CGAL_Triangle_2&tr) { typedef CGAL_Ray_2_Triangle_2_pair is_t; is_t ispair(&ray, &tr); switch (ispair.intersection_type()) { case is_t::NO: default: return CGAL_Object(); case is_t::POINT: { CGAL_Point_2 pt; ispair.intersection(pt); return CGAL_Object(new CGAL_Wrapper< CGAL_Point_2 >(pt)); } case is_t::SEGMENT: { CGAL_Segment_2 iseg; ispair.intersection(iseg); return CGAL_Object(new CGAL_Wrapper< CGAL_Segment_2 >(iseg)); } } } template class CGAL_Triangle_2_Ray_2_pair : public CGAL_Ray_2_Triangle_2_pair { public: CGAL_Triangle_2_Ray_2_pair( CGAL_Triangle_2 const *trian, CGAL_Ray_2 const *ray) : CGAL_Ray_2_Triangle_2_pair(ray, trian) {} }; @@(Triangle_2@,Ray_2@) template inline CGAL_Object CGAL_intersection(const CGAL_Triangle_2 &tr, const CGAL_Ray_2 &ray) { return CGAL_intersection(ray, tr); } #endif @} @$@<2D Ray Triangle intersection implementation@>==@{ #ifndef CGAL_LINE_2_H #include #endif // CGAL_LINE_2_H #ifndef CGAL_UTILS_H #include #endif // CGAL_UTILS_H #ifndef CGAL_NUMBER_UTILS_H #include #endif // CGAL_NUMBER_UTILS_H #ifndef CGAL_STRAIGHT_2_H #include #endif // CGAL_STRAIGHT_2_H template CGAL_Ray_2_Triangle_2_pair:: CGAL_Ray_2_Triangle_2_pair() { _known = false; _ray = 0; _trian = 0; } template CGAL_Ray_2_Triangle_2_pair:: CGAL_Ray_2_Triangle_2_pair(CGAL_Ray_2 const *ray, CGAL_Triangle_2 const *trian) { _known = false; _ray = ray; _trian = trian; } #ifndef CGAL_CFG_RETURN_TYPE_BUG_2 template CGAL_Ray_2_Triangle_2_pair::Intersection_results CGAL_Ray_2_Triangle_2_pair::intersection_type() const @ #endif // CGAL_CFG_RETURN_TYPE_BUG_2 template bool CGAL_Ray_2_Triangle_2_pair:: intersection(CGAL_Point_2 &result) const { if (!_known) intersection_type(); if (_result != POINT) return false; result = _intersection_point; return true; } template bool CGAL_Ray_2_Triangle_2_pair:: intersection(CGAL_Segment_2 &result) const { if (!_known) intersection_type(); if (_result != SEGMENT) return false; result = CGAL_Segment_2(_intersection_point, _other_point); return true; } @} @$@@M==@{@- { if (_known) return _result; // The non const this pointer is used to cast away const. CGAL_Ray_2_Triangle_2_pair *ncthis = (CGAL_Ray_2_Triangle_2_pair *) this; ncthis->_known = true; CGAL__Straight_2 straight(*_ray); CGAL_Line_2 l(_trian->vertex(0), _trian->vertex(1)); if (l.oriented_side(_trian->vertex(2)) == CGAL_ON_POSITIVE_SIDE) { // if (_trian->is_counterclockwise()) { straight.cut_right_off( CGAL_Line_2(_trian->vertex(0), _trian->vertex(1))); straight.cut_right_off( CGAL_Line_2(_trian->vertex(1), _trian->vertex(2))); straight.cut_right_off( CGAL_Line_2(_trian->vertex(2), _trian->vertex(0))); } else { straight.cut_right_off( CGAL_Line_2(_trian->vertex(2), _trian->vertex(1))); straight.cut_right_off( CGAL_Line_2(_trian->vertex(1), _trian->vertex(0))); straight.cut_right_off( CGAL_Line_2(_trian->vertex(0), _trian->vertex(2))); } switch (straight.current_state()) { case CGAL__Straight_2::EMPTY: ncthis->_result = NO; return _result; case CGAL__Straight_2::POINT: { straight.current(ncthis->_intersection_point); ncthis->_result = POINT; return _result; } case CGAL__Straight_2::SEGMENT: { CGAL_Segment_2 seg; straight.current(seg); ncthis->_intersection_point = seg.start(); ncthis->_other_point = seg.end(); ncthis->_result = SEGMENT; return _result; } default: // should not happen. CGAL_kernel_assertion_msg(false, "Internal CGAL error."); ncthis->_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@) #ifndef CGAL_SEGMENT_2_TRIANGLE_2_INTERSECTION_H #include #endif // CGAL_SEGMENT_2_TRIANGLE_2_INTERSECTION_H @} @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 #ifndef CGAL_SEGMENT_2_H #include #endif // CGAL_SEGMENT_2_H #ifndef CGAL_TRIANGLE_2_H #include #endif // CGAL_TRIANGLE_2_H #ifndef CGAL_POINT_2_H #include #endif // CGAL_POINT_2_H template class CGAL_Segment_2_Triangle_2_pair { public: enum Intersection_results {NO, POINT, SEGMENT}; CGAL_Segment_2_Triangle_2_pair() ; CGAL_Segment_2_Triangle_2_pair(CGAL_Segment_2 const *seg, CGAL_Triangle_2 const *trian); ~CGAL_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(CGAL_Point_2 &result) const; bool intersection(CGAL_Segment_2 &result) const; protected: CGAL_Segment_2 const * _seg; CGAL_Triangle_2 const * _trian; bool _known; Intersection_results _result; CGAL_Point_2 _intersection_point; CGAL_Point_2 _other_point; }; @@(Segment_2@,Triangle_2@) @ #ifndef CGAL_OBJECT_H #include #endif // CGAL_OBJECT_H template CGAL_Object CGAL_intersection(const CGAL_Segment_2 &seg, const CGAL_Triangle_2&tr) { typedef CGAL_Segment_2_Triangle_2_pair is_t; is_t ispair(&seg, &tr); switch (ispair.intersection_type()) { case is_t::NO: default: return CGAL_Object(); case is_t::POINT: { CGAL_Point_2 pt; ispair.intersection(pt); return CGAL_Object(new CGAL_Wrapper< CGAL_Point_2 >(pt)); } case is_t::SEGMENT: { CGAL_Segment_2 iseg; ispair.intersection(iseg); return CGAL_Object(new CGAL_Wrapper< CGAL_Segment_2 >(iseg)); } } } template class CGAL_Triangle_2_Segment_2_pair : public CGAL_Segment_2_Triangle_2_pair { public: CGAL_Triangle_2_Segment_2_pair( CGAL_Triangle_2 const *trian, CGAL_Segment_2 const *seg) : CGAL_Segment_2_Triangle_2_pair(seg, trian) {} }; @@(Triangle_2@,Segment_2@) template inline CGAL_Object CGAL_intersection(const CGAL_Triangle_2 &tr, const CGAL_Segment_2 &seg) { return CGAL_intersection(seg, tr); } #endif @} @$@==@{ #ifndef CGAL_LINE_2_H #include #endif // CGAL_LINE_2_H #ifndef CGAL_UTILS_H #include #endif // CGAL_UTILS_H #ifndef CGAL_NUMBER_UTILS_H #include #endif // CGAL_NUMBER_UTILS_H #ifndef CGAL_STRAIGHT_2_H #include #endif // CGAL_STRAIGHT_2_H template CGAL_Segment_2_Triangle_2_pair:: CGAL_Segment_2_Triangle_2_pair() { _known = false; _seg = 0; _trian = 0; } template CGAL_Segment_2_Triangle_2_pair:: CGAL_Segment_2_Triangle_2_pair(CGAL_Segment_2 const *seg, CGAL_Triangle_2 const *trian) { _known = false; _seg = seg; _trian = trian; } #ifndef CGAL_CFG_RETURN_TYPE_BUG_2 template CGAL_Segment_2_Triangle_2_pair::Intersection_results CGAL_Segment_2_Triangle_2_pair::intersection_type() const @ #endif // CGAL_CFG_RETURN_TYPE_BUG_2 template bool CGAL_Segment_2_Triangle_2_pair:: intersection(CGAL_Point_2 &result) const { if (!_known) intersection_type(); if (_result != POINT) return false; result = _intersection_point; return true; } template bool CGAL_Segment_2_Triangle_2_pair:: intersection(CGAL_Segment_2 &result) const { if (!_known) intersection_type(); if (_result != SEGMENT) return false; result = CGAL_Segment_2(_intersection_point, _other_point); return true; } @} @$@@M==@{@- { if (_known) return _result; // The non const this pointer is used to cast away const. CGAL_Segment_2_Triangle_2_pair *ncthis = (CGAL_Segment_2_Triangle_2_pair *) this; ncthis->_known = true; CGAL__Straight_2 straight(*_seg); CGAL_Line_2 l(_trian->vertex(0), _trian->vertex(1)); if (l.oriented_side(_trian->vertex(2)) == CGAL_ON_POSITIVE_SIDE) { straight.cut_right_off( CGAL_Line_2(_trian->vertex(0), _trian->vertex(1))); straight.cut_right_off( CGAL_Line_2(_trian->vertex(1), _trian->vertex(2))); straight.cut_right_off( CGAL_Line_2(_trian->vertex(2), _trian->vertex(0))); } else { straight.cut_right_off( CGAL_Line_2(_trian->vertex(2), _trian->vertex(1))); straight.cut_right_off( CGAL_Line_2(_trian->vertex(1), _trian->vertex(0))); straight.cut_right_off( CGAL_Line_2(_trian->vertex(0), _trian->vertex(2))); } switch (straight.current_state()) { case CGAL__Straight_2::EMPTY: ncthis->_result = NO; return _result; case CGAL__Straight_2::POINT: { straight.current(ncthis->_intersection_point); ncthis->_result = POINT; return _result; } case CGAL__Straight_2::SEGMENT: { CGAL_Segment_2 seg; straight.current(seg); ncthis->_intersection_point = seg.start(); ncthis->_other_point = seg.end(); ncthis->_result = SEGMENT; return _result; } default: // should not happen. CGAL_kernel_assertion_msg(false, "Internal CGAL error."); ncthis->_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@) #ifndef CGAL_POINT_2_TRIANGLE_2_INTERSECTION_H #include #endif // CGAL_POINT_2_TRIANGLE_2_INTERSECTION_H @} @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 #ifndef CGAL_POINT_2_H #include #endif // CGAL_POINT_2_H #ifndef CGAL_TRIANGLE_2_H #include #endif // CGAL_TRIANGLE_2_H #ifndef CGAL_POINT_2_H #include #endif // CGAL_POINT_2_H template class CGAL_Point_2_Triangle_2_pair { public: enum Intersection_results {NO, POINT}; CGAL_Point_2_Triangle_2_pair() ; CGAL_Point_2_Triangle_2_pair(CGAL_Point_2 const *pt, CGAL_Triangle_2 const *trian); ~CGAL_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(CGAL_Point_2 &result) const; protected: CGAL_Point_2 const * _pt; CGAL_Triangle_2 const * _trian; bool _known; Intersection_results _result; CGAL_Point_2 _intersection_point; CGAL_Point_2 _other_point; }; @@(Point_2@,Triangle_2@) @ #ifndef CGAL_OBJECT_H #include #endif // CGAL_OBJECT_H template CGAL_Object CGAL_intersection(const CGAL_Point_2 &pt, const CGAL_Triangle_2&tr) { typedef CGAL_Point_2_Triangle_2_pair is_t; is_t ispair(&pt, &tr); switch (ispair.intersection_type()) { case is_t::NO: default: return CGAL_Object(); case is_t::POINT: { return CGAL_Object(new CGAL_Wrapper< CGAL_Point_2 >(pt)); } } } template class CGAL_Triangle_2_Point_2_pair : public CGAL_Point_2_Triangle_2_pair { public: CGAL_Triangle_2_Point_2_pair( CGAL_Triangle_2 const *trian, CGAL_Point_2 const *pt) : CGAL_Point_2_Triangle_2_pair(pt, trian) {} }; @@(Triangle_2@,Point_2@) template inline CGAL_Object CGAL_intersection(const CGAL_Triangle_2 &tr, const CGAL_Point_2 &pt) { return CGAL_intersection(pt, tr); } #endif @} @$@==@{ #ifndef CGAL_LINE_2_H #include #endif // CGAL_LINE_2_H #ifndef CGAL_UTILS_H #include #endif // CGAL_UTILS_H #ifndef CGAL_NUMBER_UTILS_H #include #endif // CGAL_NUMBER_UTILS_H #ifndef CGAL_STRAIGHT_2_H #include #endif // CGAL_STRAIGHT_2_H template CGAL_Point_2_Triangle_2_pair:: CGAL_Point_2_Triangle_2_pair() { _known = false; _pt = 0; _trian = 0; } template CGAL_Point_2_Triangle_2_pair:: CGAL_Point_2_Triangle_2_pair(CGAL_Point_2 const *pt, CGAL_Triangle_2 const *trian) { _known = false; _pt = pt; _trian = trian; } #ifndef CGAL_CFG_RETURN_TYPE_BUG_2 template CGAL_Point_2_Triangle_2_pair::Intersection_results CGAL_Point_2_Triangle_2_pair::intersection_type() const @ #endif // CGAL_CFG_RETURN_TYPE_BUG_2 template bool CGAL_Point_2_Triangle_2_pair:: intersection(CGAL_Point_2 &result) const { if (!_known) intersection_type(); if (_result != POINT) return false; result = *_pt; return true; } @} @$@@M==@{@- { typedef CGAL_Line_2 line_t; if (_known) return _result; // The non const this pointer is used to cast away const. CGAL_Point_2_Triangle_2_pair *ncthis = (CGAL_Point_2_Triangle_2_pair *) this; ncthis->_known = true; if (_trian->has_on_unbounded_side(*_pt)) { ncthis->_result = NO; } else { ncthis->_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)) { ncthis->_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)){ ncthis->_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@) #ifndef CGAL_LINE_2_ISO_RECTANGLE_2_INTERSECTION_H #include #endif // CGAL_LINE_2_ISO_RECTANGLE_2_INTERSECTION_H @} @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 #ifndef CGAL_LINE_2_H #include #endif // CGAL_LINE_2_H #ifndef CGAL_ISO_RECTANGLE_2_H #include #endif // CGAL_ISO_RECTANGLE_2_H template class CGAL_Line_2_Iso_rectangle_2_pair { public: enum Intersection_results {NO, POINT, SEGMENT}; CGAL_Line_2_Iso_rectangle_2_pair() ; CGAL_Line_2_Iso_rectangle_2_pair(CGAL_Line_2 const *pt, CGAL_Iso_rectangle_2 const *iso); ~CGAL_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(CGAL_Point_2 &result) const; bool intersection(CGAL_Segment_2 &result) const; protected: CGAL_Point_2 _ref_point; CGAL_Vector_2 _dir; CGAL_Point_2 _isomin; CGAL_Point_2 _isomax; bool _known; Intersection_results _result; typename R::FT _min, _max; }; @@(Line_2@,Iso_rectangle_2@) @ #ifndef CGAL_OBJECT_H #include #endif // CGAL_OBJECT_H template CGAL_Object CGAL_intersection(const CGAL_Line_2 &line, const CGAL_Iso_rectangle_2&iso) { typedef CGAL_Line_2_Iso_rectangle_2_pair is_t; is_t ispair(&line, &iso); switch (ispair.intersection_type()) { case is_t::NO: default: return CGAL_Object(); case is_t::POINT: { CGAL_Point_2 ipt; ispair.intersection(ipt); return CGAL_Object(new CGAL_Wrapper< CGAL_Point_2 >(ipt)); } case is_t::SEGMENT: { CGAL_Segment_2 iseg; ispair.intersection(iseg); return CGAL_Object(new CGAL_Wrapper< CGAL_Segment_2 >(iseg)); } } } template class CGAL_Iso_rectangle_2_Line_2_pair : public CGAL_Line_2_Iso_rectangle_2_pair { public: CGAL_Iso_rectangle_2_Line_2_pair( CGAL_Iso_rectangle_2 const *iso, CGAL_Line_2 const *line) : CGAL_Line_2_Iso_rectangle_2_pair(line, iso) {} }; @@(Iso_rectangle_2@,Line_2@) template inline CGAL_Object CGAL_intersection(const CGAL_Iso_rectangle_2&iso, const CGAL_Line_2&line) { return CGAL_intersection(line, iso); } #endif @} @$@==@{ #ifndef CGAL_LINE_2_H #include #endif // CGAL_LINE_2_H #ifndef CGAL_UTILS_H #include #endif // CGAL_UTILS_H #ifndef CGAL_NUMBER_UTILS_H #include #endif // CGAL_NUMBER_UTILS_H template CGAL_Line_2_Iso_rectangle_2_pair:: CGAL_Line_2_Iso_rectangle_2_pair() { _known = false; } template CGAL_Line_2_Iso_rectangle_2_pair:: CGAL_Line_2_Iso_rectangle_2_pair(CGAL_Line_2 const *line, CGAL_Iso_rectangle_2 const *iso) { _known = false; _ref_point = line->point(); _dir = line->direction().vector(); _isomin = iso->min(); _isomax = iso->max(); } #ifndef CGAL_CFG_RETURN_TYPE_BUG_2 template CGAL_Line_2_Iso_rectangle_2_pair::Intersection_results CGAL_Line_2_Iso_rectangle_2_pair::intersection_type() const @ #endif template bool CGAL_Line_2_Iso_rectangle_2_pair:: intersection(CGAL_Point_2 &result) const { if (!_known) intersection_type(); if (_result != POINT) return false; result = _ref_point + _dir * _min; return true; } template bool CGAL_Line_2_Iso_rectangle_2_pair:: intersection(CGAL_Segment_2 &result) const { if (!_known) intersection_type(); if (_result != SEGMENT) return false; result = CGAL_Segment_2(_ref_point + _dir*_min, _ref_point + _dir*_max); return true; } @} 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 CGAL_Line_2 line_t; if (_known) return _result; // The non const this pointer is used to cast away const. CGAL_Line_2_Iso_rectangle_2_pair *ncthis = (CGAL_Line_2_Iso_rectangle_2_pair *) this; ncthis->_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)) { ncthis->_result = NO; return NO; } if (_ref_point.cartesian(i) > _isomax.cartesian(i)) { ncthis->_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) { ncthis->_min = newmin; ncthis->_max = newmax; } else { if (newmin > _min) ncthis->_min = newmin; if (newmax < _max) ncthis->_max = newmax; if (_max < _min) { ncthis->_result = NO; return NO; } } all_values = false; } } CGAL_kernel_assertion(!all_values); if (_max == _min) { ncthis->_result = POINT; return POINT; } ncthis->_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@) #ifndef CGAL_RAY_2_ISO_RECTANGLE_2_INTERSECTION_H #include #endif // CGAL_RAY_2_ISO_RECTANGLE_2_INTERSECTION_H @} @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_BBOX_2_INTERSECTION_H #define CGAL_RAY_2_BBOX_2_INTERSECTION_H #ifndef CGAL_ISO_RECTANGLE_2_H #include #endif // CGAL_ISO_RECTANGLE_2_H #ifndef CGAL_RAY_2_H #include #endif // CGAL_RAY_2_H #ifndef CGAL_SEGMENT_2_H #include #endif // CGAL_SEGMENT_2_H #ifndef CGAL_POINT_2_H #include #endif // CGAL_POINT_2_H #ifndef CGAL_UTILS_H #include #endif // CGAL_UTILS_H #ifndef CGAL_NUMBER_UTILS_H #include #endif // CGAL_NUMBER_UTILS_H template class CGAL_Ray_2_Iso_rectangle_2_pair { public: enum Intersection_results {NO, POINT, SEGMENT}; CGAL_Ray_2_Iso_rectangle_2_pair() ; CGAL_Ray_2_Iso_rectangle_2_pair(CGAL_Ray_2 const *ray, CGAL_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( CGAL_Point_2 &result) const; bool intersection( CGAL_Segment_2 &result) const; protected: bool _known; Intersection_results _result; CGAL_Point_2 _ref_point; CGAL_Vector_2 _dir; CGAL_Point_2 _isomin; CGAL_Point_2 _isomax; typename R::FT _min, _max; }; @@(Ray_2@,Iso_rectangle_2@) #ifndef CGAL_OBJECT_H #include #endif // CGAL_OBJECT_H template CGAL_Object CGAL_intersection( const CGAL_Ray_2 &ray, const CGAL_Iso_rectangle_2 &iso) { typedef CGAL_Ray_2_Iso_rectangle_2_pair is_t; is_t ispair(&ray, &iso); switch (ispair.intersection_type()) { case is_t::NO: default: return CGAL_Object(); case is_t::POINT: { CGAL_Point_2 ipt; ispair.intersection(ipt); return CGAL_Object(new CGAL_Wrapper< CGAL_Point_2 >(ipt)); } case is_t::SEGMENT: { CGAL_Segment_2 iseg; ispair.intersection(iseg); return CGAL_Object(new CGAL_Wrapper< CGAL_Segment_2 >(iseg)); } } } @ template class CGAL_Iso_rectangle_2_Ray_2_pair: public CGAL_Ray_2_Iso_rectangle_2_pair { public: CGAL_Iso_rectangle_2_Ray_2_pair() {} CGAL_Iso_rectangle_2_Ray_2_pair(CGAL_Iso_rectangle_2 const *rect, CGAL_Ray_2 const *ray) :CGAL_Ray_2_Iso_rectangle_2_pair (ray, rect){} }; @@(Iso_rectangle_2@,Ray_2@) template inline CGAL_Object CGAL_intersection(const CGAL_Iso_rectangle_2&iso, const CGAL_Ray_2&ray) { return CGAL_intersection(ray, iso); } #endif @} @$@==@{ template CGAL_Ray_2_Iso_rectangle_2_pair::CGAL_Ray_2_Iso_rectangle_2_pair() { _known = false; } template CGAL_Ray_2_Iso_rectangle_2_pair:: CGAL_Ray_2_Iso_rectangle_2_pair( CGAL_Ray_2 const *ray, CGAL_Iso_rectangle_2 const *iso) { _known = false; _isomin = iso->min(); _isomax = iso->max(); _ref_point = ray->start(); _dir = ray->direction().vector(); _min = (typename R::FT)(0); } #ifndef CGAL_CFG_RETURN_TYPE_BUG_2 template CGAL_Ray_2_Iso_rectangle_2_pair::Intersection_results CGAL_Ray_2_Iso_rectangle_2_pair::intersection_type() const @ #endif // CGAL_CFG_RETURN_TYPE_BUG_2 template bool CGAL_Ray_2_Iso_rectangle_2_pair:: intersection(CGAL_Segment_2 &seg) const { if (!_known) intersection_type(); if (_result != SEGMENT) return false; CGAL_Point_2 p1(_ref_point + _dir*_min); CGAL_Point_2 p2(_ref_point + _dir*_max); seg = CGAL_Segment_2(p1, p2); return true; } template bool CGAL_Ray_2_Iso_rectangle_2_pair:: intersection(CGAL_Point_2 &pt) const { if (!_known) intersection_type(); if (_result != POINT) return false; pt = CGAL_Point_2(_ref_point + _dir*_min); return true; } @} @$@@M==@{@- { typedef typename R::RT RT; typedef typename R::FT FT; if (_known) return _result; CGAL_Ray_2_Iso_rectangle_2_pair *ncthis = (CGAL_Ray_2_Iso_rectangle_2_pair *) this; ncthis->_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)) { ncthis->_result = NO; return _result; } if (_ref_point.cartesian(i) > _isomax.cartesian(i)) { ncthis->_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) ncthis->_min = newmin; if (to_infinity) { ncthis->_max = newmax; } else { if (newmax < _max) ncthis->_max = newmax; } if (_max < _min) { ncthis->_result = NO; return _result; } to_infinity = false; } } CGAL_kernel_assertion(!to_infinity); if (_max == _min) { ncthis->_result = POINT; return _result; } ncthis->_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@) #ifndef CGAL_SEGMENT_2_ISO_RECTANGLE_2_INTERSECTION_H #include #endif // CGAL_SEGMENT_2_ISO_RECTANGLE_2_INTERSECTION_H @} @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_BBOX_2_INTERSECTION_H #define CGAL_SEGMENT_2_BBOX_2_INTERSECTION_H #ifndef CGAL_ISO_RECTANGLE_2_H #include #endif // CGAL_ISO_RECTANGLE_2_H #ifndef CGAL_SEGMENT_2_H #include #endif // CGAL_SEGMENT_2_H #ifndef CGAL_POINT_2_H #include #endif // CGAL_POINT_2_H #ifndef CGAL_UTILS_H #include #endif // CGAL_UTILS_H #ifndef CGAL_NUMBER_UTILS_H #include #endif // CGAL_NUMBER_UTILS_H template class CGAL_Segment_2_Iso_rectangle_2_pair { public: enum Intersection_results {NO, POINT, SEGMENT}; CGAL_Segment_2_Iso_rectangle_2_pair() ; CGAL_Segment_2_Iso_rectangle_2_pair(CGAL_Segment_2 const *seg, CGAL_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( CGAL_Point_2 &result) const; bool intersection( CGAL_Segment_2 &result) const; protected: bool _known; Intersection_results _result; CGAL_Point_2 _ref_point; CGAL_Vector_2 _dir; CGAL_Point_2 _isomin; CGAL_Point_2 _isomax; typename R::FT _min, _max; }; @@(Segment_2@,Iso_rectangle_2@) #ifndef CGAL_OBJECT_H #include #endif // CGAL_OBJECT_H template CGAL_Object CGAL_intersection( const CGAL_Segment_2 &seg, const CGAL_Iso_rectangle_2 &iso) { typedef CGAL_Segment_2_Iso_rectangle_2_pair is_t; is_t ispair(&seg, &iso); switch (ispair.intersection_type()) { case is_t::NO: default: return CGAL_Object(); case is_t::POINT: { CGAL_Point_2 ipt; ispair.intersection(ipt); return CGAL_Object(new CGAL_Wrapper< CGAL_Point_2 >(ipt)); } case is_t::SEGMENT: { CGAL_Segment_2 iseg; ispair.intersection(iseg); return CGAL_Object(new CGAL_Wrapper< CGAL_Segment_2 >(iseg)); } } } @ template class CGAL_Iso_rectangle_2_Segment_2_pair: public CGAL_Segment_2_Iso_rectangle_2_pair { public: CGAL_Iso_rectangle_2_Segment_2_pair() {} CGAL_Iso_rectangle_2_Segment_2_pair(CGAL_Iso_rectangle_2 const *rect, CGAL_Segment_2 const *seg) :CGAL_Segment_2_Iso_rectangle_2_pair (seg, rect){} }; @@(Iso_rectangle_2@,Segment_2@) template inline CGAL_Object CGAL_intersection( const CGAL_Iso_rectangle_2&iso, const CGAL_Segment_2&seg) { return CGAL_intersection(seg, iso); } #endif @} @$@==@{ template CGAL_Segment_2_Iso_rectangle_2_pair::CGAL_Segment_2_Iso_rectangle_2_pair() { _known = false; } template CGAL_Segment_2_Iso_rectangle_2_pair:: CGAL_Segment_2_Iso_rectangle_2_pair( CGAL_Segment_2 const *seg, CGAL_Iso_rectangle_2 const *iso) { _known = false; _isomin = iso->min(); _isomax = iso->max(); _ref_point = seg->source(); _dir = seg->direction().vector(); _min = (typename R::FT)(0); int main_dir = (CGAL_abs(_dir.x()) > CGAL_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 CGAL_Segment_2_Iso_rectangle_2_pair::Intersection_results CGAL_Segment_2_Iso_rectangle_2_pair::intersection_type() const @ #endif // CGAL_CFG_RETURN_TYPE_BUG_2 template bool CGAL_Segment_2_Iso_rectangle_2_pair:: intersection(CGAL_Segment_2 &seg) const { if (!_known) intersection_type(); if (_result != SEGMENT) return false; CGAL_Point_2 p1(_ref_point + _dir*_min); CGAL_Point_2 p2(_ref_point + _dir*_max); seg = CGAL_Segment_2(p1, p2); return true; } template bool CGAL_Segment_2_Iso_rectangle_2_pair:: intersection(CGAL_Point_2 &pt) const { if (!_known) intersection_type(); if (_result != POINT) return false; pt = CGAL_Point_2(_ref_point + _dir*_min); return true; } @} @$@@M==@{@- { typedef typename R::RT RT; typedef typename R::FT FT; if (_known) return _result; CGAL_Segment_2_Iso_rectangle_2_pair *ncthis = (CGAL_Segment_2_Iso_rectangle_2_pair *) this; ncthis->_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)) { ncthis->_result = NO; return _result; } if (_ref_point.cartesian(i) > _isomax.cartesian(i)) { ncthis->_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) ncthis->_min = newmin; if (newmax < _max) ncthis->_max = newmax; if (_max < _min) { ncthis->_result = NO; return _result; } } } if (_max == _min) { ncthis->_result = POINT; return _result; } ncthis->_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@) #ifndef CGAL_POINT_2_ISO_RECTANGLE_2_INTERSECTION_H #include #endif // CGAL_POINT_2_ISO_RECTANGLE_2_INTERSECTION_H @} @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 #ifndef CGAL_ISO_RECTANGLE_2_H #include #endif // CGAL_ISO_RECTANGLE_2_H #ifndef CGAL_POINT_2_H #include #endif // CGAL_POINT_2_H template inline bool CGAL_do_intersect( const CGAL_Point_2 &pt, const CGAL_Iso_rectangle_2 &iso) { return !iso.has_on_unbounded_side(pt); } #ifndef CGAL_OBJECT_H #include #endif // CGAL_OBJECT_H template CGAL_Object CGAL_intersection( const CGAL_Point_2 &pt, const CGAL_Iso_rectangle_2 &iso) { if (CGAL_do_intersect(pt,iso)) { return CGAL_Object(new CGAL_Wrapper< CGAL_Point_2 >(pt)); } return CGAL_Object(); } template inline bool CGAL_do_intersect( const CGAL_Iso_rectangle_2 &iso, const CGAL_Point_2 &pt) { return !iso.has_on_unbounded_side(pt); } template inline CGAL_Object CGAL_intersection( const CGAL_Iso_rectangle_2 &iso, const CGAL_Point_2 &pt) { if (CGAL_do_intersect(pt, iso)) { return CGAL_Object(new CGAL_Wrapper< CGAL_Point_2 >(pt)); } return CGAL_Object(); } #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 #ifndef CGAL_ISO_RECTANGLE_2_H #include #endif // CGAL_ISO_RECTANGLE_2_H #ifndef CGAL_OBJECT_H #include #endif // CGAL_OBJECT_H template CGAL_Object CGAL_intersection( const CGAL_Iso_rectangle_2 &irect1, const CGAL_Iso_rectangle_2 &irect2) { const CGAL_Point_2 &min1 = irect1.min(); const CGAL_Point_2 &min2 = irect2.min(); const CGAL_Point_2 &max1 = irect1.max(); const CGAL_Point_2 &max2 = irect2.max(); typename R::FT minx, miny, maxx, maxy; CGAL_Point_2 newmin; CGAL_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 CGAL_Object(); miny = (min1.y() >= min2.y()) ? min1.y() : min2.y(); maxy = (max1.y() <= max2.y()) ? max1.y() : max2.y(); if (maxy < miny) return CGAL_Object(); if (R::FT_denominator(minx) == R::FT_denominator(miny)) { newmin = CGAL_Point_2(R::FT_numerator(minx), R::FT_numerator(miny), R::FT_denominator(minx)); } else { newmin = CGAL_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 = CGAL_Point_2(R::FT_numerator(maxx), R::FT_numerator(maxy), R::FT_denominator(maxx)); } else { newmax = CGAL_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 CGAL_make_object(CGAL_Iso_rectangle_2(newmin, newmax)); } template inline bool CGAL_do_intersect( const CGAL_Iso_rectangle_2 &irect1, const CGAL_Iso_rectangle_2 &irect2) { CGAL_Object obj(CGAL_intersection(irect1, irect2)); CGAL_Iso_rectangle_2 irect; return (CGAL_assign(irect, obj)); } #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 #ifndef CGAL_TRIANGLE_2_TRIANGLE_2_INTERSECTION_H #include #endif // CGAL_TRIANGLE_2_TRIANGLE_2_INTERSECTION_H #ifndef CGAL_TRIANGLE_2_LINE_2_INTERSECTION_H #include #endif // CGAL_TRIANGLE_2_LINE_2_INTERSECTION_H #ifndef CGAL_TRIANGLE_2_RAY_2_INTERSECTION_H #include #endif // CGAL_TRIANGLE_2_RAY_2_INTERSECTION_H #ifndef CGAL_TRIANGLE_2_SEGMENT_2_INTERSECTION_H #include #endif // CGAL_TRIANGLE_2_SEGMENT_2_INTERSECTION_H #ifndef CGAL_LINE_2_ISO_RECTANGLE_2_INTERSECTION_H #include #endif // CGAL_LINE_2_ISO_RECTANGLE_2_INTERSECTION_H #ifndef CGAL_RAY_2_ISO_RECTANGLE_2_INTERSECTION_H #include #endif // CGAL_RAY_2_ISO_RECTANGLE_2_INTERSECTION_H #ifndef CGAL_SEGMENT_2_ISO_RECTANGLE_2_INTERSECTION_H #include #endif // CGAL_SEGMENT_2_ISO_RECTANGLE_2_INTERSECTION_H #ifndef CGAL_POINT_2_ISO_RECTANGLE_2_INTERSECTION_H #include #endif // CGAL_POINT_2_ISO_RECTANGLE_2_INTERSECTION_H #ifndef CGAL_ISO_RECTANGLE_2_ISO_RECTANGLE_2_INTERSECTION_H #include #endif // CGAL_ISO_RECTANGLE_2_ISO_RECTANGLE_2_INTERSECTION_H #endif @}