BWAPI
|
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