BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/squared_distance_2_2.h
Go to the documentation of this file.
00001 // Copyright (c) 1998-2004  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/Distance_2/include/CGAL/squared_distance_2_2.h $
00019 // $Id: squared_distance_2_2.h 39776 2007-08-08 15:15:20Z spion $
00020 // 
00021 //
00022 // Author(s)     : Geert-Jan Giezeman
00023 
00024 
00025 #ifndef CGAL_SQUARED_DISTANCE_2_2_H
00026 #define CGAL_SQUARED_DISTANCE_2_2_H
00027 
00028 #include <CGAL/user_classes.h>
00029 
00030 #include <CGAL/kernel_assertions.h>
00031 #include <CGAL/Point_2.h>
00032 #include <CGAL/Segment_2.h>
00033 #include <CGAL/Line_2.h>
00034 #include <CGAL/Ray_2.h>
00035 #include <CGAL/Triangle_2.h>
00036 #include <CGAL/enum.h>
00037 #include <CGAL/wmult.h>
00038 #include <CGAL/squared_distance_utils.h>
00039 #include <CGAL/squared_distance_2_1.h>
00040 
00041 CGAL_BEGIN_NAMESPACE
00042 
00043 namespace CGALi {
00044 
00045   template <class K>
00046   void
00047   distance_index(int &ind1,
00048                  int &ind2,
00049                  const typename K::Point_2 &pt,
00050                  const typename K::Triangle_2 &triangle,
00051                  const K& k )
00052   {
00053     typename K::Left_turn_2 leftturn = k.left_turn_2_object();
00054     typedef typename K::Point_2 Point_2;
00055     const Point_2 &vt0 = triangle.vertex(0);
00056     const Point_2 &vt1 = triangle.vertex(1);
00057     const Point_2 &vt2 = triangle.vertex(2);
00058     if (leftturn(vt0, vt1, vt2)) {
00059       if (leftturn(pt, vt1, vt0)) {
00060         if (!is_acute_angle(vt0, vt1, pt, k)) {
00061           if (leftturn(pt, vt2, vt1)) {
00062             if (!is_acute_angle(vt1, vt2, pt, k)) {
00063               ind1 = 2; ind2 = -1;
00064               return;
00065             }
00066             if (!is_acute_angle(vt2, vt1, pt, k)) {
00067               ind1 = 1; ind2 = -1;
00068               return;
00069             }
00070             ind1 = 1; ind2 = 2;
00071             return;
00072           }
00073           ind1 = 1; ind2 = -1;
00074           return;
00075         }
00076         if (!is_acute_angle(vt1, vt0, pt, k)) {
00077           if (leftturn(pt, vt0, vt2)) {
00078             if (!is_acute_angle(vt0, vt2, pt, k)) {
00079               ind1 = 2; ind2 = -1;
00080               return;
00081             }
00082             if (!is_acute_angle(vt2, vt0, pt, k)) {
00083               ind1 = 0; ind2 = -1;
00084               return;
00085             }
00086             ind1 = 2; ind2 = 0;
00087             return;
00088           }
00089           ind1 = 0; ind2 = -1;
00090           return;
00091         }
00092         ind1 = 0; ind2 = 1;
00093         return;
00094       } else {
00095         if (leftturn(pt, vt2, vt1)) {
00096           if (!is_acute_angle(vt1, vt2, pt, k)) {
00097             if (leftturn(pt, vt0, vt2)) {
00098               if (!is_acute_angle(vt0, vt2, pt, k)) {
00099                 ind1 = 2; ind2 = -1;
00100                 return;
00101               }
00102               if (!is_acute_angle(vt2, vt0, pt, k)) {
00103                 ind1 = 0; ind2 = -1;
00104                 return;
00105               }
00106               ind1 = 2; ind2 = 0;
00107               return;
00108             }
00109             ind1 = 0; ind2 = -1;
00110             return;
00111           }
00112           if (!is_acute_angle(vt2, vt1, pt, k)) {
00113             ind1 = 1; ind2 = -1;
00114             return;
00115           }
00116           ind1 = 1; ind2 = 2;
00117           return;
00118         } else {
00119           if (leftturn(pt, vt0, vt2)) {
00120             if (!is_acute_angle(vt2, vt0, pt, k)) {
00121               ind1 = 0; ind2 = -1;
00122               return;
00123             }
00124             if (!is_acute_angle(vt0, vt2, pt, k)) {
00125               ind1 = 2; ind2 = -1;
00126               return;
00127             }
00128             ind1 = 2; ind2 = 0;
00129             return;
00130           } else {
00131             ind1 = -1; ind2 = -1; // point inside or on boundary.
00132             return;
00133           }
00134         }
00135       }
00136     } else {
00137       if (leftturn(pt, vt2, vt0)) {
00138         if (!is_acute_angle(vt0, vt2, pt, k)) {
00139           if (leftturn(pt, vt1, vt2)) {
00140             if (!is_acute_angle(vt2, vt1, pt, k)) {
00141               ind1 = 1; ind2 = -1;
00142               return;
00143             }
00144             if (!is_acute_angle(vt1, vt2, pt, k)) {
00145               ind1 = 2; ind2 = -1;
00146               return;
00147             }
00148             ind1 = 2; ind2 = 1;
00149             return;
00150           }
00151           ind1 = 2; ind2 = -1;
00152           return;
00153         }
00154         if (!is_acute_angle(vt2, vt0, pt, k)) {
00155           if (leftturn(pt, vt0, vt1)) {
00156             if (!is_acute_angle(vt0, vt1, pt, k)) {
00157               ind1 = 1; ind2 = -1;
00158               return;
00159             }
00160             if (!is_acute_angle(vt1, vt0, pt, k)) {
00161               ind1 = 0; ind2 = -1;
00162               return;
00163             }
00164             ind1 = 1; ind2 = 0;
00165             return;
00166           }
00167           ind1 = 0; ind2 = -1;
00168           return;
00169         }
00170         ind1 = 0; ind2 = 2;
00171         return;
00172       } else {
00173         if (leftturn(pt, vt1, vt2)) {
00174           if (!is_acute_angle(vt2, vt1, pt, k)) {
00175             if (leftturn(pt, vt0, vt1)) {
00176               if (!is_acute_angle(vt0, vt1, pt, k)) {
00177                 ind1 = 1; ind2 = -1;
00178                 return;
00179               }
00180               if (!is_acute_angle(vt1, vt0, pt, k)) {
00181                 ind1 = 0; ind2 = -1;
00182                 return;
00183               }
00184               ind1 = 1; ind2 = 0;
00185               return;
00186             }
00187             ind1 = 0; ind2 = -1;
00188             return;
00189           }
00190           if (!is_acute_angle(vt1, vt2, pt, k)) {
00191             ind1 = 2; ind2 = -1;
00192             return;
00193           }
00194           ind1 = 2; ind2 = 1;
00195           return;
00196         } else {
00197           if (leftturn(pt, vt0, vt1)) {
00198             if (!is_acute_angle(vt1, vt0, pt, k)) {
00199               ind1 = 0; ind2 = -1;
00200               return;
00201             }
00202             if (!is_acute_angle(vt0, vt1, pt, k)) {
00203               ind1 = 1; ind2 = -1;
00204               return;
00205             }
00206             ind1 = 1; ind2 = 0;
00207             return;
00208           } else {
00209             ind1 = -1; ind2 = -1; // point inside or on boundary.
00210             return;
00211           }
00212         }
00213       }
00214     }
00215   }
00216 
00217 
00218 
00219 
00220   template <class K>
00221   typename K::FT
00222   squared_distance_indexed(const typename K::Point_2 &pt,
00223                            const typename K::Triangle_2 &triangle, 
00224                            int ind1, int ind2,
00225                            const K& k)
00226   {
00227     typedef typename K::FT      FT;
00228     typedef typename K::Line_2  Line_2;
00229     if (ind1 == -1)
00230       return FT(0);
00231     if (ind2 == -1)
00232       return CGALi::squared_distance(pt, triangle.vertex(ind1), k);
00233     return CGALi::squared_distance(pt,
00234                  Line_2(triangle.vertex(ind1), triangle.vertex(ind2)),
00235                                    k);
00236   }
00237 
00238 
00239 
00240   template <class K>
00241   typename K::FT
00242   squared_distance(const typename K::Point_2 &pt,
00243                    const typename K::Triangle_2 &triangle,
00244                    const K& k)
00245   {
00246     int ind1,ind2;
00247     distance_index<K>(ind1, ind2, pt, triangle, k);
00248     return squared_distance_indexed(pt, triangle, ind1, ind2, k);
00249   }
00250 
00251 
00252   template <class K>
00253   inline typename K::FT
00254   squared_distance(const typename K::Triangle_2 & triangle,
00255                    const typename K::Point_2 & pt,
00256                    const K& k)
00257   {
00258     return CGALi::squared_distance(pt, triangle, k);
00259   }
00260 
00261 
00262   template <class K>
00263   typename K::FT
00264   squared_distance(const typename K::Line_2 &line,
00265                    const typename K::Triangle_2 &triangle,
00266                    const K& k)
00267   {
00268     typedef typename K::FT FT;
00269     Oriented_side side0;
00270     side0 = line.oriented_side(triangle.vertex(0));
00271     if (line.oriented_side(triangle.vertex(1)) != side0)
00272       return FT(0);
00273     if (line.oriented_side(triangle.vertex(2)) != side0)
00274       return FT(0);
00275     FT mindist, dist;
00276     int i;
00277     mindist = CGALi::squared_distance(triangle.vertex(0),line,k);
00278     for (i=1; i<3; i++) {
00279       dist = CGALi::squared_distance(triangle.vertex(i),line,k);
00280       if (dist < mindist)
00281         mindist = dist;
00282     }
00283     return mindist;
00284   }
00285 
00286 
00287   template <class K>
00288   inline typename K::FT
00289   squared_distance(const typename K::Triangle_2 & triangle,
00290                    const typename K::Line_2 & line,
00291                    const K& k)
00292   {
00293     return CGALi::squared_distance(line, triangle, k);
00294   }
00295 
00296 
00297   template <class K>
00298   typename K::FT
00299   squared_distance(const typename K::Ray_2 &ray,
00300                    const typename K::Triangle_2 &triangle,
00301                    const K& k)
00302   {
00303     typedef typename K::FT       FT;
00304     typedef typename K::Point_2  Point_2;
00305     typedef typename K::Line_2   Line_2;
00306     int i, ind_tr1, ind_tr2, ind_ray = 0, ind1;
00307     FT mindist, dist;
00308     distance_index<K>(ind_tr1, ind_tr2, ray.source(), triangle, k);
00309     mindist =
00310       squared_distance_indexed(ray.source(), triangle, ind_tr1, ind_tr2, k);
00311     for (i=0; i<3; i++) {
00312       const Point_2& pt = triangle.vertex(i);
00313       distance_index<K>(ind1, pt, ray, k);
00314       dist = squared_distance_indexed(pt, ray, ind1, k);
00315       if (dist < mindist) {
00316         ind_ray = ind1;
00317         ind_tr1 = i; ind_tr2 = -1;
00318         mindist = dist;
00319       }
00320     }
00321     // now check if all vertices are on the right side of the separating line.
00322     // In case of vertex-vertex smallest distance this is the case.
00323     if (ind_tr2 == -1 && ind_ray != -1)
00324       return mindist;
00325     if (ind_tr2 != -1) {
00326       // Check if all the segment vertices lie at the same side of
00327       // the triangle segment.
00328       const Point_2 &vt1 = triangle.vertex(ind_tr1);
00329       const Point_2 &vt2 = triangle.vertex(ind_tr2);
00330       if (clockwise(ray.direction().vector(), vt2-vt1, k)) {
00331         mindist = FT(0);
00332       }
00333     } else {
00334       // Check if all the triangle vertices lie 
00335       // at the same side of the segment.
00336       const Line_2 &sl = ray.supporting_line();
00337       Oriented_side or_s = sl.oriented_side(triangle.vertex(0));
00338       for (i=1; i<3; i++) {
00339         if (sl.oriented_side(triangle.vertex(i)) != or_s) {
00340           mindist = FT(0);
00341           break;
00342         }
00343       }
00344     }
00345     return mindist;
00346   }
00347 
00348 
00349   template <class K>
00350   inline typename K::FT
00351   squared_distance(const typename K::Triangle_2 & triangle,
00352                    const typename K::Ray_2 & ray,
00353                    const K& k)
00354   {
00355     return CGALi::squared_distance(ray, triangle, k);
00356   }
00357 
00358 
00359   template <class K>
00360   typename K::FT
00361   squared_distance(const typename K::Segment_2 &seg,
00362                    const typename K::Triangle_2 &triangle,
00363                    const K& k)
00364   {
00365     typedef typename K::FT       FT;
00366     typedef typename K::Point_2  Point_2;
00367     typename K::Orientation_2 orientation;
00368     int i, ind_tr1 = 0, ind_tr2 = -1, ind_seg = 0, ind1, ind2;
00369     FT mindist, dist;
00370     mindist = CGALi::squared_distance(seg.source(), triangle.vertex(0), k);
00371     for (i=0; i<2; i++) {
00372       const Point_2 &pt = seg.vertex(i);
00373       distance_index<K>(ind1, ind2, pt, triangle, k);
00374       dist = CGALi::squared_distance_indexed(pt, triangle, ind1, ind2, k);
00375       if (dist < mindist) {
00376         ind_seg = i;
00377         ind_tr1 = ind1; ind_tr2 = ind2;
00378         mindist = dist;
00379       }
00380     }
00381     for (i=0; i<3; i++) {
00382       const Point_2& pt = triangle.vertex(i);
00383       distance_index<K>(ind1, pt, seg, k);
00384       dist = CGALi::squared_distance_indexed(pt, seg, ind1, k);
00385       if (dist < mindist) {
00386         ind_seg = ind1;
00387         ind_tr1 = i; ind_tr2 = -1;
00388         mindist = dist;
00389       }
00390     }
00391     // now check if all vertices are on the right side of the separating line.
00392     // In case of vertex-vertex smallest distance this is the case.
00393     if (ind_tr2 == -1 && ind_seg != -1)
00394       return mindist;
00395 
00396     if (ind_tr2 != -1) {
00397       // Check if all the segment vertices lie at the same side of
00398       // the triangle segment.
00399       const Point_2 &vt1 = triangle.vertex(ind_tr1);
00400       const Point_2 &vt2 = triangle.vertex(ind_tr2);
00401       Orientation or_s = orientation(vt1, vt2, seg.source());
00402       if (orientation(vt1, vt2, seg.target()) != or_s) {
00403         mindist = FT(0);
00404       }
00405     } else {
00406       // Check if all the triangle vertices lie 
00407       // at the same side of the segment.
00408       const Point_2 &vt1 = seg.source();
00409       const Point_2 &vt2 = seg.target();
00410       Orientation or_s = orientation(vt1, vt2, triangle.vertex(0));
00411       for (i=1; i<3; i++) {
00412         if (orientation(vt1, vt2, triangle.vertex(i)) != or_s) {
00413           mindist = FT(0);
00414           break;
00415         }
00416       }
00417     }
00418     return mindist;
00419   }
00420 
00421 
00422   template <class K>
00423   inline typename K::FT
00424   squared_distance(const typename K::Triangle_2 & triangle,
00425                    const typename K::Segment_2 & seg,
00426                    const K& k)
00427   {
00428     return CGALi::squared_distance(seg, triangle, k);
00429   }
00430 
00431 
00432 
00433   template <class K>
00434   typename K::FT
00435   squared_distance(const typename K::Triangle_2 &triangle1,
00436                    const typename K::Triangle_2 &triangle2,
00437                    const K& k)
00438   {
00439     typedef typename K::FT       FT;
00440     typedef typename K::Point_2  Point_2;
00441     typename K::Orientation_2 orientation;
00442     int i, ind1_1 = 0,ind1_2 = -1, ind2_1 = 0, ind2_2 = -1, ind1, ind2;
00443     FT mindist, dist;
00444     mindist =
00445       CGALi::squared_distance(triangle1.vertex(0), triangle2.vertex(0), k);
00446     for (i=0; i<3; i++) {
00447       const Point_2& pt = triangle1.vertex(i);
00448       distance_index<K>(ind1, ind2, pt, triangle2, k);
00449       dist = squared_distance_indexed(pt, triangle2, ind1, ind2, k);
00450       if (dist < mindist) {
00451         ind1_1 = i; ind1_2 = -1;
00452         ind2_1 = ind1; ind2_2 = ind2;
00453         mindist = dist;
00454       }
00455     }
00456     for (i=0; i<3; i++) {
00457       const Point_2& pt = triangle2.vertex(i);
00458       distance_index<K>(ind1, ind2, pt, triangle1, k);
00459       dist = squared_distance_indexed(pt, triangle1, ind1, ind2, k);
00460       if (dist < mindist) {
00461         ind1_1 = ind1; ind1_2 = ind2;
00462         ind2_1 = i; ind2_2 = -1;
00463         mindist = dist;
00464       }
00465     }
00466     // now check if all vertices are on the right side of the
00467     // separating line.
00468     if (ind1_2 == -1 && ind2_2 == -1)
00469       return mindist;
00470     // In case of point-segment closest distance, there is still the
00471     // possibility of overlapping triangles.  Check if all the
00472     // vertices lie at the same side of the segment.
00473     if (ind1_2 != -1) {
00474       const Point_2 &vt1 = triangle1.vertex(ind1_1);
00475       const Point_2 &vt2 = triangle1.vertex(ind1_2);
00476       Orientation or_s = orientation(vt1, vt2, triangle2.vertex(0));
00477       for (i=1; i<3; i++) {
00478         if (orientation(vt1, vt2, triangle2.vertex(i)) != or_s) {
00479           mindist = FT(0);
00480           break;
00481         }
00482       }
00483     } else {
00484       const Point_2 &vt1 = triangle2.vertex(ind2_1);
00485       const Point_2 &vt2 = triangle2.vertex(ind2_2);
00486       Orientation or_s = orientation(vt1, vt2, triangle1.vertex(0));
00487       for (i=1; i<3; i++) {
00488         if (orientation(vt1, vt2, triangle1.vertex(i)) != or_s) {
00489           mindist = FT(0);
00490           break;
00491         }
00492       }
00493     }
00494     return mindist;
00495   }
00496 
00497 } // namespace CGALi
00498 
00499 template <class K>
00500 inline typename K::FT
00501 squared_distance(const Point_2<K> &pt,
00502                  const Triangle_2<K> &triangle)
00503 {
00504   return CGALi::squared_distance(pt, triangle, K());
00505 }
00506 
00507 template <class K>
00508 inline typename K::FT
00509 squared_distance(const Triangle_2<K> &triangle,
00510                  const Point_2<K> &pt)
00511 {
00512   return CGALi::squared_distance(pt, triangle, K());
00513 }
00514 
00515 template <class K>
00516 inline typename K::FT
00517 squared_distance(const Line_2<K> &line,
00518                  const Triangle_2<K> &triangle)
00519 {
00520   return CGALi::squared_distance(line, triangle, K());
00521 }
00522 
00523 template <class K>
00524 inline typename K::FT
00525 squared_distance(const Triangle_2<K> &triangle,
00526                  const Line_2<K> &line)
00527 {
00528   return CGALi::squared_distance(line, triangle, K());
00529 }
00530 
00531 template <class K>
00532 inline typename K::FT
00533 squared_distance(const Ray_2<K> &ray,
00534                  const Triangle_2<K> &triangle)
00535 {
00536   return CGALi::squared_distance(ray, triangle, K());
00537 }
00538 
00539 template <class K>
00540 inline typename K::FT
00541 squared_distance(const Triangle_2<K> &triangle,
00542                  const Ray_2<K> &ray)
00543 {
00544   return CGALi::squared_distance(ray, triangle, K());
00545 }
00546 
00547 template <class K>
00548 inline typename K::FT
00549 squared_distance(const Segment_2<K> &seg,
00550                  const Triangle_2<K> &triangle)
00551 {
00552   return CGALi::squared_distance(seg, triangle, K());
00553 }
00554 
00555 template <class K>
00556 inline typename K::FT
00557 squared_distance(const Triangle_2<K> &triangle,
00558                  const Segment_2<K> &seg)
00559 {
00560   return CGALi::squared_distance(seg, triangle, K());
00561 }
00562 
00563 template <class K>
00564 inline typename K::FT
00565 squared_distance(const Triangle_2<K> &triangle1,
00566                  const Triangle_2<K> &triangle2)
00567 {
00568   return CGALi::squared_distance(triangle1, triangle2, K());
00569 }
00570 
00571 CGAL_END_NAMESPACE
00572 
00573 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines