BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Segment_2_Segment_2_intersection.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/Segment_2_Segment_2_intersection.h $
00019 // $Id: Segment_2_Segment_2_intersection.h 45075 2008-08-21 12:50:41Z spion $
00020 // 
00021 //
00022 // Author(s)     : Geert-Jan Giezeman
00023 
00024 
00025 #ifndef CGAL_SEGMENT_2_SEGMENT_2_INTERSECTION_H
00026 #define CGAL_SEGMENT_2_SEGMENT_2_INTERSECTION_H
00027 
00028 #include <CGAL/Segment_2.h>
00029 #include <CGAL/Point_2.h>
00030 #include <CGAL/kernel_assertions.h>
00031 #include <CGAL/number_utils.h>
00032 #include <CGAL/predicates_on_points_2.h>
00033 #include <CGAL/Line_2.h>
00034 #include <CGAL/Line_2_Line_2_intersection.h>
00035 #include <CGAL/Object.h>
00036 #include <CGAL/Uncertain.h>
00037 
00038 CGAL_BEGIN_NAMESPACE
00039 
00040 namespace CGALi {
00041 
00042 template <class K>
00043 inline bool
00044 do_intersect(const typename K::Segment_2 &seg1, const typename K::Segment_2 &seg2);
00045 
00046 
00047 
00048 
00049 template <class K>
00050 bool seg_seg_do_intersect_crossing(
00051         const typename K::Point_2  &p1, const typename K::Point_2 &p2, 
00052         const typename K::Point_2 &p3, const typename K::Point_2 &p4,
00053         const K& k)
00054 {
00055     switch (make_certain(k.orientation_2_object()(p1,p2,p3))) {
00056     case LEFT_TURN:
00057       return ! (k.orientation_2_object()(p3,p4,p2) == RIGHT_TURN); //   right_turn(p3,p4,p2);
00058     case RIGHT_TURN:
00059         return ! (k.orientation_2_object()(p3,p4,p2) == LEFT_TURN); //left_turn(p3,p4,p2);
00060     case COLLINEAR:
00061         return true;
00062     }
00063     CGAL_kernel_assertion(false);
00064     return false;
00065 }
00066 
00067 
00068 template <class K>
00069 bool seg_seg_do_intersect_contained(
00070         const typename K::Point_2  &p1, const typename K::Point_2 &p2, 
00071         const typename K::Point_2 &p3, const typename K::Point_2 &p4,
00072         const K& k)
00073 {
00074     switch (make_certain(k.orientation_2_object()(p1,p2,p3))) {
00075     case LEFT_TURN:
00076       return ! (k.orientation_2_object()(p1,p2,p4) == LEFT_TURN); // left_turn(p1,p2,p4);
00077     case RIGHT_TURN:
00078         return ! (k.orientation_2_object()(p1,p2,p4) == RIGHT_TURN); // right_turn(p1,p2,p4);
00079     case COLLINEAR:
00080         return true;
00081     }
00082     CGAL_kernel_assertion(false);
00083     return false;
00084 }
00085 
00086 
00087 template <class K>
00088 bool
00089 do_intersect(const typename K::Segment_2 &seg1, 
00090              const typename K::Segment_2 &seg2,
00091              const K& k)
00092 {
00093     typename K::Point_2 const & A1 = seg1.source();
00094     typename K::Point_2 const & A2 = seg1.target();
00095     typename K::Point_2 const & B1 = seg2.source();
00096     typename K::Point_2 const & B2 = seg2.target();
00097     typename K::Less_xy_2 less_xy;
00098     typename K::Compare_xy_2 compare_xy;
00099 
00100     if (less_xy(A1,A2)) {
00101         if (less_xy(B1,B2)) {
00102             if (less_xy(A2,B1)
00103              || less_xy(B2,A1))
00104                 return false;
00105         } else {
00106             if (less_xy(A2,B2)
00107              || less_xy(B1,A1))
00108                 return false;
00109         }
00110     } else {
00111         if (less_xy(B1,B2)) {
00112             if (less_xy(A1,B1)
00113              || less_xy(B2,A2))
00114                 return false;
00115         } else {
00116             if (less_xy(A1,B2)
00117              || less_xy(B1,A2))
00118                 return false;
00119         }
00120     }
00121     if (less_xy(A1,A2)) {
00122         if (less_xy(B1,B2)) {
00123             switch(make_certain(compare_xy(A1,B1))) {
00124             case SMALLER:
00125                 switch(make_certain(compare_xy(A2,B1))) {
00126                 case SMALLER:
00127                     return false;
00128                 case EQUAL:
00129                     return true;
00130                 case LARGER:
00131                     switch(make_certain(compare_xy(A2,B2))) {
00132                     case SMALLER:
00133                         return seg_seg_do_intersect_crossing(A1,A2,B1,B2, k);
00134                     case EQUAL:
00135                         return true;
00136                     case LARGER:
00137                         return seg_seg_do_intersect_contained(A1,A2,B1,B2, k);
00138                     }
00139                 }
00140             case EQUAL:
00141                 return true;
00142             case LARGER:
00143                 switch(make_certain(compare_xy(B2,A1))) {
00144                 case SMALLER:
00145                     return false;
00146                 case EQUAL:
00147                     return true;
00148                 case LARGER:
00149                     switch(make_certain(compare_xy(B2,A2))) {
00150                     case SMALLER:
00151                         return seg_seg_do_intersect_crossing(B1,B2,A1,A2, k);
00152                     case EQUAL:
00153                         return true;
00154                     case LARGER:
00155                         return seg_seg_do_intersect_contained(B1,B2,A1,A2, k);
00156                     }
00157                 }
00158             }
00159         } else {
00160             switch(make_certain(compare_xy(A1,B2))) {
00161             case SMALLER:
00162                 switch(make_certain(compare_xy(A2,B2))) {
00163                 case SMALLER:
00164                     return false;
00165                 case EQUAL:
00166                     return true;
00167                 case LARGER:
00168                     switch(make_certain(compare_xy(A2,B1))) {
00169                     case SMALLER:
00170                         return seg_seg_do_intersect_crossing(A1,A2,B2,B1, k);
00171                     case EQUAL:
00172                         return true;
00173                     case LARGER:
00174                         return seg_seg_do_intersect_contained(A1,A2,B2,B1, k);
00175                     }
00176                 }
00177             case EQUAL:
00178                 return true;
00179             case LARGER:
00180                 switch(make_certain(compare_xy(B1,A1))) {
00181                 case SMALLER:
00182                     return false;
00183                 case EQUAL:
00184                     return true;
00185                 case LARGER:
00186                     switch(make_certain(compare_xy(B1,A2))) {
00187                     case SMALLER:
00188                         return seg_seg_do_intersect_crossing(B2,B1,A1,A2, k);
00189                     case EQUAL:
00190                         return true;
00191                     case LARGER:
00192                         return seg_seg_do_intersect_contained(B2,B1,A1,A2, k);
00193                     }
00194                 }
00195             }
00196         }
00197     } else {
00198         if (less_xy(B1,B2)) {
00199             switch(make_certain(compare_xy(A2,B1))) {
00200             case SMALLER:
00201                 switch(make_certain(compare_xy(A1,B1))) {
00202                 case SMALLER:
00203                     return false;
00204                 case EQUAL:
00205                     return true;
00206                 case LARGER:
00207                     switch(make_certain(compare_xy(A1,B2))) {
00208                     case SMALLER:
00209                         return seg_seg_do_intersect_crossing(A2,A1,B1,B2, k);
00210                     case EQUAL:
00211                         return true;
00212                     case LARGER:
00213                         return seg_seg_do_intersect_contained(A2,A1,B1,B2, k);
00214                     }
00215                 }
00216             case EQUAL:
00217                 return true;
00218             case LARGER:
00219                 switch(make_certain(compare_xy(B2,A2))) {
00220                 case SMALLER:
00221                     return false;
00222                 case EQUAL:
00223                     return true;
00224                 case LARGER:
00225                     switch(make_certain(compare_xy(B2,A1))) {
00226                     case SMALLER:
00227                         return seg_seg_do_intersect_crossing(B1,B2,A2,A1, k);
00228                     case EQUAL:
00229                         return true;
00230                     case LARGER:
00231                         return seg_seg_do_intersect_contained(B1,B2,A2,A1, k);
00232                     }
00233                 }
00234             }
00235         } else {
00236             switch(make_certain(compare_xy(A2,B2))) {
00237             case SMALLER:
00238                 switch(make_certain(compare_xy(A1,B2))) {
00239                 case SMALLER:
00240                     return false;
00241                 case EQUAL:
00242                     return true;
00243                 case LARGER:
00244                     switch(make_certain(compare_xy(A1,B1))) {
00245                     case SMALLER:
00246                         return seg_seg_do_intersect_crossing(A2,A1,B2,B1, k);
00247                     case EQUAL:
00248                         return true;
00249                     case LARGER:
00250                         return seg_seg_do_intersect_contained(A2,A1,B2,B1, k);
00251                     }
00252                 }
00253             case EQUAL:
00254                 return true;
00255             case LARGER:
00256                 switch(make_certain(compare_xy(B1,A2))) {
00257                 case SMALLER:
00258                     return false;
00259                 case EQUAL:
00260                     return true;
00261                 case LARGER:
00262                     switch(make_certain(compare_xy(B1,A1))) {
00263                     case SMALLER:
00264                         return seg_seg_do_intersect_crossing(B2,B1,A2,A1, k);
00265                     case EQUAL:
00266                         return true;
00267                     case LARGER:
00268                         return seg_seg_do_intersect_contained(B2,B1,A2,A1, k);
00269                     }
00270                 }
00271             }
00272         }
00273     }
00274     CGAL_kernel_assertion(false);
00275     return false;
00276 }
00277 
00278 
00279 template <class K>
00280 class Segment_2_Segment_2_pair {
00281 public:
00282     enum Intersection_results {NO_INTERSECTION, POINT, SEGMENT};
00283     Segment_2_Segment_2_pair(typename K::Segment_2 const *seg1,
00284                             typename K::Segment_2 const *seg2)
00285             : _seg1(seg1), _seg2(seg2), _known(false) {}
00286 
00287     Intersection_results intersection_type() const;
00288 
00289     typename K::Point_2    intersection_point() const;
00290     typename K::Segment_2  intersection_segment() const;
00291 protected:
00292     typename K::Segment_2 const*   _seg1;
00293     typename K::Segment_2 const *  _seg2;
00294     mutable bool                       _known;
00295     mutable Intersection_results       _result;
00296     mutable typename K::Point_2            _intersection_point, _other_point;
00297 };
00298 
00299 template <class K>
00300 typename Segment_2_Segment_2_pair<K>::Intersection_results
00301 Segment_2_Segment_2_pair<K>::intersection_type() const
00302 {
00303   typename K::Construct_vector_2 construct_vector;
00304     if (_known)
00305         return _result;
00306     _known = true;
00307     if (!CGALi::do_intersect(*_seg1, *_seg2, K())) {
00308         _result = NO_INTERSECTION;
00309         return _result;
00310     }
00311     typename K::Line_2 const &l1 = _seg1->supporting_line();
00312     typename K::Line_2 const &l2 = _seg2->supporting_line();
00313     Line_2_Line_2_pair<K> linepair(&l1, &l2);
00314     switch ( linepair.intersection_type()) {
00315     case Line_2_Line_2_pair<K>::NO_INTERSECTION:
00316         _result = NO_INTERSECTION;
00317         break;
00318     case Line_2_Line_2_pair<K>::POINT:
00319         _intersection_point = linepair.intersection_point();
00320         _result = POINT;
00321         break;
00322     case Line_2_Line_2_pair<K>::LINE:
00323         {
00324         typedef typename K::RT RT;
00325         typename K::Point_2 const &start1 = _seg1->source();
00326         typename K::Point_2 const &end1   = _seg1->target();
00327         typename K::Point_2 const &start2 = _seg2->source();
00328         typename K::Point_2 const &end2   = _seg2->target();
00329         typename K::Vector_2 diff1 = construct_vector(start1, end1);
00330         typename K::Point_2 const *minpt;
00331         typename K::Point_2 const *maxpt;
00332         if (CGAL_NTS abs(diff1.x()) > CGAL_NTS abs(diff1.y())) {
00333             if (start1.x() < end1.x()) {
00334                 minpt = &start1;
00335                 maxpt = &end1;
00336             } else {
00337                 minpt = &end1;
00338                 maxpt = &start1;
00339             }
00340             if (start2.x() < end2.x()) {
00341                 if (start2.x() > minpt->x()) {
00342                     minpt = &start2;
00343                 }
00344                 if (end2.x() < maxpt->x()) {
00345                     maxpt = &end2;
00346                 }
00347             } else {
00348                 if (end2.x() > minpt->x()) {
00349                     minpt = &end2;
00350                 }
00351                 if (start2.x() < maxpt->x()) {
00352                     maxpt = &start2;
00353                 }
00354             }
00355             if (maxpt->x() < minpt->x()) {
00356                 _result = NO_INTERSECTION;
00357                 return _result;
00358             }
00359             if (maxpt->x() == minpt->x()) {
00360                 _intersection_point = *minpt;
00361                 _result = POINT;
00362                 return _result;
00363             }
00364             _intersection_point = *minpt;
00365             _other_point = *maxpt;
00366             _result = SEGMENT;
00367             return _result; 
00368         } else {
00369             if (start1.y() < end1.y()) {
00370                 minpt = &start1;
00371                 maxpt = &end1;
00372             } else {
00373                 minpt = &end1;
00374                 maxpt = &start1;
00375             }
00376             if (start2.y() < end2.y()) {
00377                 if (start2.y() > minpt->y()) {
00378                     minpt = &start2;
00379                 }
00380                 if (end2.y() < maxpt->y()) {
00381                     maxpt = &end2;
00382                 }
00383             } else {
00384                 if (end2.y() > minpt->y()) {
00385                     minpt = &end2;
00386                 }
00387                 if (start2.y() < maxpt->y()) {
00388                     maxpt = &start2;
00389                 }
00390             }
00391             if (maxpt->y() < minpt->y()) {
00392                 _result = NO_INTERSECTION;
00393                 return _result;
00394             }
00395             if (maxpt->y() == minpt->y()) {
00396                 _intersection_point = *minpt;
00397                 _result = POINT;
00398                 return _result;
00399             }
00400             _intersection_point = *minpt;
00401             _other_point = *maxpt;
00402             _result = SEGMENT;
00403             return _result; 
00404         }
00405         } 
00406     }
00407     return _result;
00408 }
00409 
00410 
00411 template <class K>
00412 typename K::Point_2
00413 Segment_2_Segment_2_pair<K>::intersection_point() const
00414 {
00415     if (!_known)
00416         intersection_type();
00417     CGAL_kernel_assertion(_result == POINT);
00418     return _intersection_point;
00419 }
00420 
00421 template <class K>
00422 typename K::Segment_2
00423 Segment_2_Segment_2_pair<K>::intersection_segment() const
00424 {
00425   typedef typename K::Segment_2 Segment_2;
00426     if (!_known)
00427         intersection_type();
00428     CGAL_kernel_assertion(_result == SEGMENT);
00429     return Segment_2(_intersection_point, _other_point);
00430 }
00431 
00432 
00433 
00434 
00435 template <class K>
00436 Object
00437 intersection(const typename K::Segment_2 &seg1, 
00438              const typename K::Segment_2 &seg2,
00439              const K&)
00440 {
00441     typedef Segment_2_Segment_2_pair<K> is_t;
00442     is_t ispair(&seg1, &seg2);
00443     switch (ispair.intersection_type()) {
00444     case is_t::NO_INTERSECTION:
00445     default:
00446         return Object();
00447     case is_t::POINT:
00448         return make_object(ispair.intersection_point());
00449     case is_t::SEGMENT:
00450         return make_object(ispair.intersection_segment());
00451     }
00452 }
00453 
00454 } // namespace CGALi
00455 
00456 template <class K>
00457 inline
00458 bool
00459 do_intersect(const Segment_2<K> &seg1, 
00460              const Segment_2<K> &seg2)
00461 {
00462   typedef typename K::Do_intersect_2 Do_intersect;
00463   return Do_intersect()(seg1, seg2);
00464 }
00465 
00466 
00467 template <class K>
00468 Object
00469 intersection(const Segment_2<K> &seg1, 
00470              const Segment_2<K> &seg2)
00471 {
00472   typedef typename K::Intersect_2 Intersect;
00473   return Intersect()(seg1, seg2);
00474 }
00475 
00476 CGAL_END_NAMESPACE
00477 
00478 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines