BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Intersections_2/Triangle_2_Triangle_2_intersection_impl.h
Go to the documentation of this file.
00001 // Copyright (c) 2000  Utrecht University (The Netherlands),
00002 // ETH Zurich (Switzerland), Freie Universitaet Berlin (Germany),
00003 // INRIA Sophia-Antipolis (France), Martin-Luther-University Halle-Wittenberg
00004 // (Germany), Max-Planck-Institute Saarbruecken (Germany), RISC Linz (Austria),
00005 // and Tel-Aviv University (Israel).  All rights reserved.
00006 //
00007 // This file is part of CGAL (www.cgal.org); you can redistribute it and/or
00008 // modify it under the terms of the GNU Lesser General Public License as
00009 // published by the Free Software Foundation; version 2.1 of the License.
00010 // See the file LICENSE.LGPL distributed with CGAL.
00011 //
00012 // Licensees holding a valid commercial license may use this file in
00013 // accordance with the commercial license agreement provided with the software.
00014 //
00015 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00016 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00017 //
00018 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Intersections_2/include/CGAL/Intersections_2/Triangle_2_Triangle_2_intersection_impl.h $
00019 // $Id: Triangle_2_Triangle_2_intersection_impl.h 45075 2008-08-21 12:50:41Z spion $
00020 // 
00021 //
00022 // Author(s)     : Geert-Jan Giezeman
00023 
00024 #include <CGAL/Segment_2.h>
00025 #include <CGAL/Triangle_2.h>
00026 #include <CGAL/Line_2.h>
00027 #include <CGAL/kernel_assertions.h>
00028 #include <CGAL/number_utils.h>
00029 #include <vector>
00030 
00031 #include <CGAL/Line_2_Line_2_intersection.h>
00032 
00033 CGAL_BEGIN_NAMESPACE
00034 
00035 namespace CGALi {
00036 
00037 template <class K>
00038 struct Pointlist_2_rec_ {
00039     Pointlist_2_rec_ *next;
00040     typename K::Point_2 point;
00041     Oriented_side side;
00042 };
00043 
00044 template <class K>
00045 struct Pointlist_2_ {
00046     int size;
00047     Pointlist_2_rec_<K> *first;
00048     Pointlist_2_() ;
00049     ~Pointlist_2_() ;
00050 };
00051 
00052 
00053 
00054 template <class K>
00055 Pointlist_2_<K>::Pointlist_2_()
00056 {
00057     size = 0;
00058     first = 0;
00059 }
00060 
00061 template <class K>
00062 Pointlist_2_<K>::~Pointlist_2_()
00063 {
00064     Pointlist_2_rec_<K> *cur;
00065     for (int i=0; i<size; i++) {
00066         cur = first;
00067         first = cur->next;
00068         delete cur;
00069     }
00070 }
00071 
00072 
00073 
00074 
00075 template <class K>
00076 void _init_list(Pointlist_2_<K> &list,
00077                 const typename K::Triangle_2 &trian)
00078 {
00079     // check on degeneracies of trian.
00080     if (!trian.is_degenerate()) {
00081         list.size = 3;
00082         list.first = 0;
00083         for (int i=0; i<3; i++) {
00084             Pointlist_2_rec_<K> *newrec =
00085                         new Pointlist_2_rec_<K>;
00086             newrec->next = list.first;
00087             list.first = newrec;
00088             newrec->point = trian[i];
00089         }
00090     } else {
00091         // _not_implemented();
00092         CGAL_kernel_assertion(false);
00093     }
00094 }
00095 
00096 
00097 
00098 template <class K>
00099 void _cut_off(Pointlist_2_<K> &list,
00100                 const typename K::Line_2 &cutter)
00101 {
00102     int i;
00103     int add = 0;
00104     Pointlist_2_rec_<K> *cur, *last=0, *newrec;
00105     for (i=0, cur = list.first; i<list.size; i++, cur = cur->next) {
00106         cur->side = cutter.oriented_side(cur->point);
00107         last = cur;
00108     }
00109     for (cur = list.first, i=0; i<list.size; i++, cur = cur->next) {
00110         if ((cur->side == ON_POSITIVE_SIDE
00111              && last->side == ON_NEGATIVE_SIDE)
00112            || (cur->side == ON_NEGATIVE_SIDE
00113                && last->side == ON_POSITIVE_SIDE)) {
00114             // add a vertex after cur
00115             add++;
00116             typename K::Line_2 l(cur->point, last->point);
00117             newrec = new Pointlist_2_rec_<K>;
00118             newrec->next = last->next;
00119             last->next = newrec;
00120             newrec->side = ON_ORIENTED_BOUNDARY;
00121             Line_2_Line_2_pair<K> linepair(&cutter,  &l);
00122             typename Line_2_Line_2_pair<K>::Intersection_results isr;
00123             isr = linepair.intersection_type();
00124             CGAL_kernel_assertion(isr == Line_2_Line_2_pair<K>::POINT);
00125             newrec->point = linepair.intersection_point();
00126         }
00127         last = cur;
00128     }
00129     CGAL_kernel_assertion(add <= 2);
00130     Pointlist_2_rec_<K> **curpt;
00131     curpt = &list.first;
00132     while (*curpt != 0) {
00133         cur = *curpt;
00134         if (cur->side == ON_NEGATIVE_SIDE) {
00135             add--;
00136             *curpt = cur->next;
00137             delete cur;
00138         } else {
00139             curpt = &cur->next;
00140         }
00141     }
00142     if (list.size == 2 && add == 1) {
00143         add = 0;
00144         cur = list.first;
00145         if (cur->side == ON_ORIENTED_BOUNDARY) {
00146             list.first = cur->next;
00147             delete cur;
00148         } else {
00149             last = cur;
00150             cur = cur->next;
00151             last->next = cur->next;
00152             delete cur;
00153         }
00154     }
00155     list.size += add;
00156 }
00157 
00158 
00159 template <class K>
00160 class Triangle_2_Triangle_2_pair {
00161 public:
00162     enum Intersection_results {NO_INTERSECTION, POINT, SEGMENT, TRIANGLE, POLYGON};
00163     Triangle_2_Triangle_2_pair(typename K::Triangle_2 const *trian1,
00164                                typename K::Triangle_2 const *trian2)
00165         : _trian1(trian1), _trian2(trian2), _known(false) {}
00166 
00167     Intersection_results intersection_type() const;
00168 
00169     typename K::Point_2     intersection_point() const;
00170     typename K::Segment_2   intersection_segment() const;
00171     typename K::Triangle_2  intersection_triangle() const;
00172     bool                    intersection(/*Polygon_2<R> &result*/) const;
00173     int                     vertex_count() const;
00174     typename K::Point_2     vertex(int i) const;
00175 protected:
00176     typename K::Triangle_2 const*   _trian1;
00177     typename K::Triangle_2 const *  _trian2;
00178     mutable bool                    _known;
00179     mutable Intersection_results    _result;
00180     mutable Pointlist_2_<K>    _pointlist;
00181 };
00182 
00183 template <class K>
00184 typename Triangle_2_Triangle_2_pair<K>::Intersection_results
00185 Triangle_2_Triangle_2_pair<K>::intersection_type() const
00186 {
00187   typedef typename K::Line_2 Line_2;
00188     if (_known)
00189         return _result;
00190 // The non const this pointer is used to cast away const.
00191     _known = true;
00192     if (!do_overlap(_trian1->bbox(), _trian2->bbox())) {
00193         _result = NO_INTERSECTION;
00194         return _result;
00195     }
00196     _init_list(_pointlist, *_trian1);
00197     if (_trian2->is_degenerate()) {
00198         // _not_implemented();
00199         CGAL_kernel_assertion(false);
00200     } else {
00201         Line_2 l(_trian2->vertex(0), _trian2->vertex(1));
00202         if (l.oriented_side(_trian2->vertex(2)) == ON_POSITIVE_SIDE) {
00203             // counterclockwise triangle
00204             _cut_off(_pointlist, l);
00205             l = Line_2(_trian2->vertex(1), _trian2->vertex(2));
00206             _cut_off(_pointlist, l);
00207             l = Line_2(_trian2->vertex(2), _trian2->vertex(0));
00208             _cut_off(_pointlist, l);
00209         } else {
00210             l = l.opposite();
00211             _cut_off(_pointlist, l);
00212             l = Line_2(_trian2->vertex(0), _trian2->vertex(2));
00213             _cut_off(_pointlist, l);
00214             l = Line_2(_trian2->vertex(2), _trian2->vertex(1));
00215             _cut_off(_pointlist, l);
00216         }
00217     }
00218     switch (_pointlist.size) {
00219     case 0:
00220         _result = NO_INTERSECTION;
00221         break;
00222     case 1:
00223         _result = POINT;
00224         break;
00225     case 2:
00226         _result = SEGMENT;
00227         break;
00228     case 3:
00229         _result = TRIANGLE;
00230         break;
00231     default:
00232         _result = POLYGON;
00233     }
00234     return _result;
00235 }
00236 
00237 
00238 template <class K>
00239 bool
00240 Triangle_2_Triangle_2_pair<K>::intersection(
00241         /* Polygon_2<R> &result */) const
00242 {
00243     if (!_known)
00244         intersection_type();
00245     if (_result != TRIANGLE  &&  _result != POLYGON)
00246         return false;
00247     Pointlist_2_rec_<K> *cur;
00248     int i;
00249     for (i=0, cur = _pointlist.first;
00250          i<_pointlist.size;
00251          i++, cur = cur->next) {
00252       std::cout << to_double(cur->point.x()) << ' ';
00253       std::cout << to_double(cur->point.y()) << ' ';
00254     }
00255     std::cout << std::endl;
00256     return true;
00257 }
00258 
00259 template <class K>
00260 int
00261 Triangle_2_Triangle_2_pair<K>::vertex_count() const
00262 {
00263     CGAL_kernel_assertion(_known);
00264     return _pointlist.size;
00265 }
00266 
00267 template <class K>
00268 typename K::Point_2
00269 Triangle_2_Triangle_2_pair<K>::vertex(int n) const
00270 {
00271     CGAL_kernel_assertion(_known);
00272     CGAL_kernel_assertion(n >= 0 && n < _pointlist.size);
00273     Pointlist_2_rec_<K> *cur;
00274     int k;
00275     for (k=0, cur = _pointlist.first;
00276          k < n;
00277          k++, cur = cur->next) {
00278     }
00279     return cur->point;
00280 }
00281 
00282 template <class K>
00283 typename K::Triangle_2
00284 Triangle_2_Triangle_2_pair<K>::intersection_triangle() const
00285 {
00286   typedef typename K::Triangle_2 Triangle_2;
00287     if (!_known)
00288         intersection_type();
00289     CGAL_kernel_assertion(_result == TRIANGLE);
00290     return Triangle_2(_pointlist.first->point,
00291                       _pointlist.first->next->point,
00292                       _pointlist.first->next->next->point);
00293 }
00294 
00295 template <class K>
00296 typename K::Segment_2
00297 Triangle_2_Triangle_2_pair<K>::intersection_segment() const
00298 {
00299   typedef typename K::Segment_2 Segment_2;
00300     if (!_known)
00301         intersection_type();
00302     CGAL_kernel_assertion(_result == SEGMENT);
00303     return Segment_2(_pointlist.first->point,
00304                      _pointlist.first->next->point);
00305 }
00306 
00307 template <class K>
00308 typename K::Point_2
00309 Triangle_2_Triangle_2_pair<K>::intersection_point() const
00310 {
00311     if (!_known)
00312         intersection_type();
00313     CGAL_kernel_assertion(_result == POINT);
00314     return _pointlist.first->point;
00315 }
00316 
00317 
00318 
00319 template <class K>
00320 Object
00321 intersection(const typename K::Triangle_2 &tr1, 
00322              const typename K::Triangle_2 &tr2,
00323              const K&)
00324 {
00325     typedef Triangle_2_Triangle_2_pair<K> is_t;
00326     is_t ispair(&tr1, &tr2);
00327     switch (ispair.intersection_type()) {
00328     case is_t::NO_INTERSECTION:
00329     default:
00330         return Object();
00331     case is_t::POINT:
00332         return make_object(ispair.intersection_point());
00333     case is_t::SEGMENT:
00334         return make_object(ispair.intersection_segment());
00335     case is_t::TRIANGLE:
00336         return make_object(ispair.intersection_triangle());
00337     case is_t::POLYGON: {
00338         typedef std::vector<typename K::Point_2> Container;
00339         Container points(ispair.vertex_count());
00340         for (int i =0; i < ispair.vertex_count(); i++) {
00341             points[i] = ispair.vertex(i);
00342         }
00343         return make_object(points);
00344     }
00345     }
00346 }
00347 
00348 } // namespace CGALi
00349 
00350 CGAL_END_NAMESPACE
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines