BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/squared_distance_2_1.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_1.h $
00019 // $Id: squared_distance_2_1.h 45215 2008-08-29 15:48:00Z spion $
00020 // 
00021 //
00022 // Author(s)     : Geert-Jan Giezeman
00023 //                 Michel Hoffmann <hoffmann@inf.ethz.ch>
00024 //                 Andreas Fabri <Andreas.Fabri@geometryfactory.com>
00025 
00026 
00027 #ifndef CGAL_SQUARED_DISTANCE_2_1_H
00028 #define CGAL_SQUARED_DISTANCE_2_1_H
00029 
00030 #include <CGAL/user_classes.h>
00031 
00032 
00033 #include <CGAL/kernel_assertions.h>
00034 #include <CGAL/Point_2.h>
00035 #include <CGAL/Segment_2.h>
00036 #include <CGAL/Line_2.h>
00037 #include <CGAL/Ray_2.h>
00038 #include <CGAL/enum.h>
00039 #include <CGAL/wmult.h>
00040 #include <CGAL/squared_distance_utils.h>
00041 
00042 CGAL_BEGIN_NAMESPACE
00043 
00044 namespace CGALi {
00045   
00046   template <class K>
00047   inline typename K::FT
00048   squared_distance(const typename K::Point_2 & pt1,
00049                    const typename K::Point_2 & pt2,
00050                    const K& k)
00051   {
00052     typename K::Vector_2 vec = k.construct_vector_2_object()(pt2, pt1);
00053     return (typename K::FT)k.compute_squared_length_2_object()(vec);
00054   }
00055 
00056   template <class K>
00057   typename K::FT
00058   squared_distance(const typename K::Point_2 &pt,
00059                    const typename K::Line_2 &line,
00060                    const K&,
00061                    const Homogeneous_tag&)
00062   {
00063     typedef typename K::RT RT;
00064     typedef typename K::FT FT;
00065     const RT & a = line.a();
00066     const RT & b = line.b();
00067     const RT & w = pt.hw();
00068     RT n = a*pt.hx() + b*pt.hy() + w * line.c();
00069     RT d = (CGAL_NTS square(a) + CGAL_NTS square(b)) * CGAL_NTS square(w);
00070     return Rational_traits<FT>().make_rational(CGAL_NTS square(n), d);
00071   }
00072 
00073   template <class K>
00074   typename K::FT
00075   squared_distance(const typename K::Point_2 &pt,
00076                    const typename K::Line_2 &line,
00077                    const K&,
00078                    const Cartesian_tag&)
00079   {
00080     typedef typename K::FT FT;
00081     const FT & a = line.a();
00082     const FT & b = line.b();
00083     FT n = a*pt.x() + b*pt.y() + line.c();
00084     FT d = CGAL_NTS square(a) + CGAL_NTS square(b);
00085     return CGAL_NTS square(n)/d;
00086   }
00087 
00088 
00089   template <class K>
00090   typename K::FT
00091   squared_distance(const typename K::Point_2 &pt,
00092                    const typename K::Line_2 &line,
00093                    const K& k)
00094   {  
00095     typedef typename K::Kernel_tag Tag;
00096     Tag tag;
00097     return squared_distance(pt, line, k, tag);
00098   }
00099 
00100   template <class K>
00101   inline typename K::FT
00102   squared_distance(const typename K::Line_2 &line, 
00103                    const typename K::Point_2 &pt,
00104                    const K& k)
00105   {
00106     return CGALi::squared_distance(pt, line, k);
00107   }
00108   
00109   template <class K>
00110   typename K::FT
00111   squared_distance(const typename K::Point_2 &pt,
00112                    const typename K::Ray_2 &ray,
00113                    const K& k)
00114   {
00115     typedef typename K::Vector_2 Vector_2;
00116     typename K::Construct_vector_2 construct_vector;
00117     Vector_2 diff = construct_vector(ray.source(), pt);
00118     const Vector_2 &dir = ray.direction().vector();
00119     if (!is_acute_angle(dir,diff, k) )
00120       return (typename K::FT)k.compute_squared_length_2_object()(diff);
00121     return CGALi::squared_distance(pt, ray.supporting_line(), k);
00122   }
00123 
00124   template <class K>
00125   inline typename K::FT
00126   squared_distance(const typename K::Ray_2 &ray,
00127                    const typename K::Point_2 &pt,
00128                    const K& k)
00129   {
00130     return CGALi::squared_distance(pt, ray, k);
00131   }
00132 
00133   template <class K>
00134   typename K::FT
00135   squared_distance(const typename K::Point_2 &pt,
00136                    const typename K::Segment_2 &seg,
00137                    const K& k)
00138   {
00139     typename K::Construct_vector_2 construct_vector;
00140     typedef typename K::Vector_2 Vector_2;
00141     typedef typename K::RT RT;
00142     // assert that the segment is valid (non zero length).
00143     Vector_2 diff = construct_vector(seg.source(), pt);
00144     Vector_2 segvec = construct_vector(seg.source(), seg.target());
00145     RT d = wdot(diff,segvec, k);
00146     if (d <= (RT)0)
00147       return (typename K::FT)k.compute_squared_length_2_object()(diff);
00148     RT e = wdot(segvec,segvec, k);
00149     if (wmult((K*)0 ,d, segvec.hw()) > wmult((K*)0, e, diff.hw()))
00150       return CGALi::squared_distance(pt, seg.target(), k);
00151     return CGALi::squared_distance(pt, seg.supporting_line(), k);
00152   }
00153 
00154   template <class K>
00155   inline typename K::FT
00156   squared_distance(const typename K::Segment_2 &seg,
00157                    const typename K::Point_2 &pt,
00158                    const K& k)
00159   {
00160     return CGALi::squared_distance(pt, seg, k);
00161   }
00162 
00163   template <class K>
00164   typename K::FT
00165   squared_distance_parallel(const typename K::Segment_2 &seg1,
00166                             const typename K::Segment_2 &seg2,
00167                             const K& k)
00168   {
00169     typedef typename K::Vector_2 Vector_2;
00170     const Vector_2 &dir1 = seg1.direction().vector();
00171     const Vector_2 &dir2 = seg2.direction().vector();
00172     if (same_direction(dir1, dir2, k)) {
00173       if (!is_acute_angle(seg1.source(), seg1.target(), seg2.source(), k))
00174         return CGALi::squared_distance(seg1.target(), seg2.source(), k);
00175       if (!is_acute_angle(seg1.target(), seg1.source(), seg2.target(), k))
00176         return CGALi::squared_distance(seg1.source(), seg2.target(), k);
00177     } else {
00178       if (!is_acute_angle(seg1.source(), seg1.target(), seg2.target(), k))
00179         return CGALi::squared_distance(seg1.target(), seg2.target(), k);
00180       if (!is_acute_angle(seg1.target(), seg1.source(), seg2.source(), k))
00181         return CGALi::squared_distance(seg1.source(), seg2.source(), k);
00182     }
00183     return CGALi::squared_distance(seg2.source(), seg1.supporting_line(), k);
00184   }
00185 
00186   template <class K>
00187   inline typename K::RT 
00188   _distance_measure_sub(const typename K::RT &startwcross, 
00189                         const typename K::RT &endwcross,
00190                         const typename K::Point_2 &start, 
00191                         const typename K::Point_2 &end)
00192   {
00193     return  CGAL_NTS abs(wmult((K*)0, startwcross, end.hw())) -
00194       CGAL_NTS abs(wmult((K*)0, endwcross, start.hw()));
00195   }
00196 
00197   template <class K>
00198   typename K::FT
00199   squared_distance(const typename K::Segment_2 &seg1,
00200                    const typename K::Segment_2 &seg2,
00201                    const K& k)
00202   {
00203     typedef typename K::RT RT;
00204     typedef typename K::FT FT;
00205     bool crossing1, crossing2;
00206     RT c1s, c1e, c2s, c2e;
00207     if (seg1.source() == seg1.target())
00208       return CGALi::squared_distance(seg1.source(), seg2, k);
00209     if (seg2.source() == seg2.target())
00210       return CGALi::squared_distance(seg2.source(), seg1, k);
00211     c1s = wcross(seg2.source(), seg2.target(), seg1.source(), k);
00212     c1e = wcross(seg2.source(), seg2.target(), seg1.target(), k);
00213     c2s = wcross(seg1.source(), seg1.target(), seg2.source(), k);
00214     c2e = wcross(seg1.source(), seg1.target(), seg2.target(), k);
00215     if (c1s < RT(0)) {
00216       crossing1 = (c1e >= RT(0));
00217     } else {
00218       if (c1e <= RT(0)) {
00219         if (c1s == RT(0) && c1e == RT(0))
00220           return CGALi::squared_distance_parallel(seg1, seg2, k);
00221         crossing1 = true;
00222       } else {
00223         crossing1 = (c1s == RT(0));
00224       }
00225     }
00226     if (c2s < RT(0)) {
00227       crossing2 = (c2e >= RT(0));
00228     } else {
00229       if (c2e <= RT(0)) {
00230         if (c2s == RT(0) && c2e == RT(0))
00231           return CGALi::squared_distance_parallel(seg1, seg2, k);
00232         crossing2 = true;
00233       } else {
00234         crossing2 = (c2s == RT(0));
00235       }
00236     }
00237 
00238     if (crossing1) {
00239       if (crossing2)
00240         return (FT)0;
00241       RT dm;
00242       dm = _distance_measure_sub<K>(c2s,c2e, seg2.source(), seg2.target());
00243       if (dm < RT(0)) {
00244         return CGALi::squared_distance(seg2.source(), seg1, k);
00245       } else {
00246         if (dm > RT(0)) {
00247           return CGALi::squared_distance(seg2.target(), seg1, k);
00248         } else {
00249           // parallel, should not happen (no crossing)
00250           return CGALi::squared_distance_parallel(seg1, seg2, k);
00251         }
00252       }
00253     } else {
00254       if (crossing2) {
00255         RT dm;
00256         dm =
00257           _distance_measure_sub<K>(c1s, c1e,seg1.source(),seg1.target());
00258         if (dm < RT(0)) {
00259           return CGALi::squared_distance(seg1.source(), seg2, k);
00260         } else {
00261           if (dm > RT(0)) {
00262             return CGALi::squared_distance(seg1.target(), seg2, k);
00263           } else {
00264             // parallel, should not happen (no crossing)
00265             return CGALi::squared_distance_parallel(seg1, seg2, k);
00266           }
00267         }
00268       } else {
00269 
00270         FT min1, min2;
00271         RT dm = _distance_measure_sub<K>(
00272                                       c1s, c1e, seg1.source(), seg1.target());
00273         if (dm == RT(0))
00274           return CGALi::squared_distance_parallel(seg1, seg2, k);
00275         min1 = (dm < RT(0)) ?
00276           CGALi::squared_distance(seg1.source(), seg2, k):
00277           CGALi::squared_distance(seg1.target(), seg2, k);
00278         dm = _distance_measure_sub<K>(
00279                                    c2s, c2e, seg2.source(), seg2.target());
00280         if (dm == RT(0))  // should not happen.
00281           return CGALi::squared_distance_parallel(seg1, seg2, k);
00282         min2 = (dm < RT(0)) ?
00283           CGALi::squared_distance(seg2.source(), seg1, k):
00284           CGALi::squared_distance(seg2.target(), seg1, k);
00285         return (min1 < min2) ? min1 : min2;
00286       }
00287     }
00288   }
00289 
00290   template <class K>
00291   inline typename K::RT 
00292   _distance_measure_sub(const typename K::RT &startwcross, 
00293                         const typename K::RT &endwcross,
00294                         const typename K::Vector_2 &start, 
00295                         const typename K::Vector_2 &end)
00296   {
00297     return  CGAL_NTS abs(wmult((K*)0, startwcross, end.hw())) -
00298       CGAL_NTS abs(wmult((K*)0, endwcross, start.hw()));
00299   }
00300 
00301   template <class K>
00302   typename K::FT
00303   squared_distance_parallel(const typename K::Segment_2 &seg,
00304                             const typename K::Ray_2 &ray,
00305                             const K& k)
00306   {
00307     typedef typename K::Vector_2 Vector_2;
00308     const Vector_2 &dir1 = seg.direction().vector();
00309     const Vector_2 &dir2 = ray.direction().vector();
00310 
00311     if (same_direction(dir1, dir2, k)) {
00312       if (!is_acute_angle(seg.source(), seg.target(), ray.source(), k))
00313         return CGALi::squared_distance(seg.target(), ray.source(), k);
00314     } else {
00315       if (!is_acute_angle(seg.target(), seg.source(), ray.source(), k))
00316         return CGALi::squared_distance(seg.source(), ray.source(), k);
00317     }
00318     return CGALi::squared_distance(ray.source(), seg.supporting_line(), k);
00319   }
00320 
00321   template <class K>
00322   typename K::FT
00323   squared_distance(const typename K::Segment_2 &seg,
00324                    const typename K::Ray_2 &ray,
00325                    const K& k)
00326   {
00327     typename K::Construct_vector_2 construct_vector;
00328     typedef typename K::RT RT;
00329     typedef typename K::FT FT;
00330     typedef typename K::Vector_2 Vector_2;
00331     const Vector_2 &raydir = ray.direction().vector();
00332     Vector_2 startvec(construct_vector(ray.source(), seg.source()));
00333     Vector_2 endvec(construct_vector(ray.source(), seg.target()));
00334     typename K::Orientation_2 orientation;
00335 
00336     bool crossing1, crossing2;
00337     RT c1s, c1e;
00338     if (seg.source() == seg.target())
00339       return CGALi::squared_distance(seg.source(), ray, k);
00340     c1s = wcross(raydir, startvec, k);
00341     c1e = wcross(raydir, endvec, k);
00342     if (c1s < RT(0)) {
00343       crossing1 = (c1e >= RT(0));
00344     } else {
00345       if (c1e <= RT(0)) {
00346         if (c1s == RT(0) && c1e == RT(0))
00347           return CGALi::squared_distance_parallel(seg, ray, k);
00348         crossing1 = true;
00349       } else {
00350         crossing1 = (c1s == RT(0));
00351       }
00352     }
00353     switch (orientation(seg.source(), seg.target(), ray.source())) {
00354     case LEFT_TURN:
00355       crossing2 = right_turn(construct_vector(seg.source(), seg.target()), raydir, k);
00356       break;
00357     case RIGHT_TURN:
00358       crossing2 = left_turn(construct_vector(seg.source(), seg.target()), raydir, k);
00359       break;
00360     default:
00361       crossing2 = true;
00362       break;
00363     }
00364 
00365     if (crossing1) {
00366       if (crossing2)
00367         return FT(0);
00368       return CGALi::squared_distance(ray.source(), seg, k);
00369     } else {
00370       if (crossing2) {
00371         RT dm;
00372         dm = _distance_measure_sub<K>(c1s, c1e, startvec, endvec);
00373         if (dm < RT(0)) {
00374           return CGALi::squared_distance(seg.source(), ray, k);
00375         } else {
00376           if (dm > RT(0)) {
00377             return CGALi::squared_distance(seg.target(), ray, k);
00378           } else {
00379             // parallel, should not happen (no crossing)
00380             return CGALi::squared_distance_parallel(seg, ray, k);
00381           }
00382         }
00383       } else {
00384         FT min1, min2;
00385         RT dm = _distance_measure_sub<K>(c1s, c1e, startvec, endvec);
00386         if (dm == RT(0))
00387           return CGALi::squared_distance_parallel(seg, ray, k);
00388         min1 = (dm < RT(0))
00389           ? CGALi::squared_distance(seg.source(), ray, k)
00390           : CGALi::squared_distance(seg.target(), ray, k);
00391         min2 = CGALi::squared_distance(ray.source(), seg, k);
00392         return (min1 < min2) ? min1 : min2;
00393       }
00394     }
00395   }
00396 
00397   template <class K>
00398   inline typename K::FT
00399   squared_distance(const typename K::Ray_2 &ray,
00400                    const typename K::Segment_2 &seg,
00401                    const K& k)
00402   {
00403     return CGALi::squared_distance(seg, ray, k);
00404   }
00405 
00406   template <class K>
00407   typename K::FT
00408   _sqd_to_line(const typename K::Vector_2 &diff,
00409                const typename K::RT & wcross, 
00410                const typename K::Vector_2 &dir )
00411   {
00412     typedef typename K::RT RT;
00413     typedef typename K::FT FT;
00414     RT numerator = CGAL_NTS square(wcross);
00415     RT denominator = wmult((K*)0, RT(wdot(dir,dir, K())),
00416                            diff.hw(), diff.hw());
00417     return Rational_traits<FT>().make_rational(numerator, denominator);
00418   }
00419 
00420   template <class K>
00421   typename K::FT
00422   squared_distance(const typename K::Segment_2 &seg,
00423                    const typename K::Line_2 &line,
00424                    const K& k)
00425   {
00426     typename K::Construct_vector_2 construct_vector;
00427     typedef typename K::RT RT;
00428     typedef typename K::FT FT;
00429     typedef typename K::Vector_2 Vector_2;
00430     typedef typename K::Point_2  Point_2;
00431     const Vector_2 &linedir = line.direction().vector();
00432     const Point_2 &linepoint = line.point();
00433     Vector_2 startvec(construct_vector(linepoint, seg.source()));
00434     Vector_2 endvec(construct_vector(linepoint, seg.target()));
00435 
00436     bool crossing1;
00437     RT c1s, c1e;
00438     if (seg.source() == seg.target())
00439       return CGALi::squared_distance(seg.source(), line, k);
00440     c1s = wcross(linedir, startvec, k);
00441     c1e = wcross(linedir, endvec, k);
00442     if (c1s < RT(0)) {
00443       crossing1 = (c1e >= RT(0));
00444     } else {
00445       if (c1e <= RT(0)) {
00446         crossing1 = true;
00447       } else {
00448         crossing1 = (c1s == RT(0));
00449       }
00450     }
00451 
00452     if (crossing1) {
00453       return (FT)0;
00454     } else {
00455       RT dm;
00456       dm = _distance_measure_sub<K>(c1s, c1e, startvec, endvec);
00457       if (dm <= RT(0)) {
00458         return _sqd_to_line<K>(startvec, c1s, linedir);
00459       } else {
00460         return _sqd_to_line<K>(endvec, c1e, linedir);
00461       }
00462     }
00463   }
00464 
00465   template <class K>
00466   inline typename K::FT
00467   squared_distance(const typename K::Line_2 &line,
00468                    const typename K::Segment_2 &seg,
00469                    const K& k)
00470   {
00471     return CGALi::squared_distance(seg, line, k);
00472   }
00473 
00474   template <class K>
00475   typename K::FT
00476   ray_ray_squared_distance_parallel(
00477     const typename K::Vector_2 &ray1dir,
00478     const typename K::Vector_2 &ray2dir,
00479     const typename K::Vector_2 &from1to2,
00480     const K& k)
00481   {
00482     typedef typename K::RT RT;
00483     typedef typename K::FT FT;
00484     if (!is_acute_angle(ray1dir, from1to2, k)) {
00485       if (!same_direction(ray1dir, ray2dir, k))
00486         return (typename K::FT)k.compute_squared_length_2_object()(from1to2);
00487     }
00488     RT wcr, w;
00489     wcr = wcross(ray1dir, from1to2, k);
00490     w = from1to2.hw();
00491     return (typename K::FT)(FT(wcr*wcr)
00492                             / FT(wmult((K*)0, RT(wdot(ray1dir, ray1dir, k)), w, w)));
00493   }
00494 
00495   template <class K>
00496   typename K::FT
00497   squared_distance(const typename K::Ray_2 &ray1,
00498                    const typename K::Ray_2 &ray2,
00499                    const K& k)
00500   {
00501     typename K::Construct_vector_2 construct_vector;
00502     typedef typename K::Vector_2 Vector_2;
00503     typedef typename K::FT FT;
00504     const Vector_2 &ray1dir = ray1.direction().vector();
00505     const Vector_2 &ray2dir = ray2.direction().vector();
00506     Vector_2 diffvec(construct_vector(ray1.source(),ray2.source()));
00507 
00508     bool crossing1, crossing2;
00509     switch (orientation(ray1dir, ray2dir, k)) {
00510     case COUNTERCLOCKWISE:
00511       crossing1 = !clockwise(diffvec, ray2dir, k);
00512       crossing2 = !counterclockwise(ray1dir, diffvec, k);
00513       break;
00514     case CLOCKWISE:
00515       crossing1 = !counterclockwise(diffvec, ray2dir, k);
00516       crossing2 = !clockwise(ray1dir, diffvec, k);
00517       break;
00518     default:
00519       return ray_ray_squared_distance_parallel(ray1dir,ray2dir,diffvec,k);
00520     }
00521 
00522     if (crossing1) {
00523       if (crossing2)
00524         return (FT)0;
00525       return CGALi::squared_distance(ray2.source(), ray1, k);
00526     } else {
00527       if (crossing2) {
00528         return CGALi::squared_distance(ray1.source(), ray2, k);
00529       } else {
00530 
00531         FT min1, min2;
00532         min1 = CGALi::squared_distance(ray1.source(), ray2, k);
00533         min2 = CGALi::squared_distance(ray2.source(), ray1, k);
00534         return (min1 < min2) ? min1 : min2;
00535       }
00536     }
00537   }
00538   
00539   template <class K>
00540   typename K::FT
00541   squared_distance(const typename K::Line_2 &line,
00542                    const typename K::Ray_2 &ray,
00543                    const K& k)
00544   {
00545     typename K::Construct_vector_2 construct_vector;
00546     typedef typename K::FT FT;
00547     typedef typename K::Vector_2 Vector_2;
00548     Vector_2 normalvec(line.a(), line.b());
00549     Vector_2 diff = construct_vector(line.point(), ray.source());
00550     FT sign_dist = k.compute_scalar_product_2_object()(diff,normalvec);
00551     if (sign_dist < FT(0)) {
00552       if (is_acute_angle(normalvec, ray.direction().vector(), k) )
00553         return (FT)0;
00554     } else {
00555       if (is_obtuse_angle(normalvec, ray.direction().vector(), k) )
00556         return (FT)0;
00557     }
00558     return (typename K::FT)((sign_dist*sign_dist)/k.compute_squared_length_2_object()(normalvec));
00559   }
00560 
00561   template <class K>
00562   inline typename K::FT
00563   squared_distance(const typename K::Ray_2 &ray,
00564                    const typename K::Line_2 &line,
00565                    const K& k)
00566   {
00567     return CGALi::squared_distance(line, ray, k);
00568   }
00569 
00570   template <class K>
00571   inline typename K::FT
00572   squared_distance(const typename K::Line_2 &line1,
00573                    const typename K::Line_2 &line2,
00574                    const K& k)
00575   {
00576     typedef typename K::FT FT;
00577     if (CGALi::parallel(line1, line2, k))
00578       return CGALi::squared_distance(line1.point(), line2, k);
00579     else
00580       return (FT)0;
00581   }
00582 
00583   template <class K>
00584   void
00585   distance_index(int &ind,
00586                  const typename K::Point_2 &pt,
00587                  const typename K::Ray_2 &ray,
00588                  const K& k)
00589   {
00590     typename K::Construct_vector_2 construct_vector;
00591     if (!is_acute_angle(ray.direction().vector(), construct_vector(ray.source(), pt), k)) {
00592       ind = 0;
00593       return;
00594     }
00595     ind = -1;
00596   }
00597 
00598   template <class K>
00599   void
00600   distance_index(int &ind,
00601                  const typename K::Point_2 &pt,
00602                  const typename K::Segment_2 &seg,
00603                  const K& k)
00604   {
00605     if (!is_acute_angle(seg.target(),seg.source(),pt, k)) {
00606       ind = 0;
00607       return;
00608     }
00609     if (!is_acute_angle(seg.source(),seg.target(),pt, k)) {
00610       ind = 1;
00611       return;
00612     }
00613     ind = -1;
00614   }
00615 
00616   template <class K>
00617   inline typename K::FT
00618   squared_distance_indexed(const typename K::Point_2 &pt,
00619                            const typename K::Ray_2 &ray, 
00620                            int ind,
00621                            const K& k)
00622   {
00623     if (ind == 0)
00624       return CGALi::squared_distance(pt, ray.source(), k);
00625     return CGALi::squared_distance(pt, ray.supporting_line(), k);
00626   }
00627 
00628   template <class K>
00629   inline typename K::FT
00630   squared_distance_indexed(const typename K::Point_2 &pt,
00631                            const typename K::Segment_2 &seg, 
00632                            int ind,
00633                            const K& k)
00634   {
00635     if (ind == 0)
00636       return CGALi::squared_distance(pt, seg.source(), k);
00637     if (ind == 1)
00638       return CGALi::squared_distance(pt, seg.target(), k);
00639     return CGALi::squared_distance(pt, seg.supporting_line(), k);
00640   }
00641   
00642 } // namespace CGALi
00643 
00644 template <class K>
00645 inline typename K::FT
00646 squared_distance(const Point_2<K> & pt1, const Point_2<K> & pt2)
00647 {
00648   return CGALi::squared_distance(pt1, pt2, K());
00649 }
00650 
00651 
00652 template <class K>
00653 inline typename K::FT
00654 squared_distance(const Point_2<K> &pt, const Line_2<K> &line)
00655 {
00656   return CGALi::squared_distance(pt, line, K());
00657 }
00658 
00659 
00660 template <class K>
00661 inline typename K::FT
00662 squared_distance(const Line_2<K> & line, const Point_2<K> & pt)
00663 {
00664     return squared_distance(pt, line);
00665 }
00666 
00667 
00668 template <class K>
00669 inline typename K::FT
00670 squared_distance(const Point_2<K> &pt, const Ray_2<K> &ray)
00671 {
00672   return CGALi::squared_distance(pt, ray, K());
00673 }
00674 
00675 template <class K>
00676 inline typename K::FT
00677 squared_distance(const Ray_2<K> & ray, const Point_2<K> & pt)
00678 {
00679     return squared_distance(pt, ray);
00680 }
00681 
00682 
00683 template <class K>
00684 inline typename K::FT
00685 squared_distance(const Point_2<K> &pt, const Segment_2<K> &seg)
00686 {
00687   return CGALi::squared_distance(pt, seg, K());
00688 }
00689 
00690 
00691 template <class K>
00692 inline typename K::FT
00693 squared_distance(const Segment_2<K> & seg, const Point_2<K> & pt)
00694 {
00695   return CGALi::squared_distance(pt, seg, K());
00696 }
00697 
00698 
00699 template <class K>
00700 inline typename K::FT
00701 squared_distance(const Segment_2<K> &seg1, const Segment_2<K> &seg2)
00702 {
00703   return CGALi::squared_distance(seg1, seg2, K());
00704 }
00705 
00706 template <class K>
00707 inline typename K::FT
00708 squared_distance(const Segment_2<K> &seg, const Ray_2<K> &ray)
00709 {
00710   return CGALi::squared_distance(seg, ray, K());
00711 }
00712 
00713 template <class K>
00714 inline typename K::FT
00715 squared_distance(const Ray_2<K> & ray, const Segment_2<K> & seg)
00716 {
00717   return CGALi::squared_distance(seg, ray, K());
00718 }
00719 
00720 template <class K>
00721 inline typename K::FT
00722 squared_distance(const Segment_2<K> &seg, const Line_2<K> &line)
00723 {
00724   return CGALi::squared_distance(seg, line, K());
00725 }
00726 
00727 template <class K>
00728 inline typename K::FT
00729 squared_distance(const Line_2<K> & line, const Segment_2<K> & seg)
00730 {
00731   return CGALi::squared_distance(seg, line, K());
00732 }
00733 
00734 template <class K>
00735 inline typename K::FT
00736 squared_distance(const Ray_2<K> &ray1, const Ray_2<K> &ray2)
00737 {
00738   return CGALi::squared_distance(ray1, ray2, K());
00739 }
00740 
00741 template <class K>
00742 inline typename K::FT
00743 squared_distance(const Line_2<K> &line, const Ray_2<K> &ray)
00744 {
00745   return CGALi::squared_distance(line, ray, K());
00746 }
00747 
00748 template <class K>
00749 inline typename K::FT
00750 squared_distance(const Ray_2<K> & ray, const Line_2<K> & line)
00751 {
00752   return CGALi::squared_distance(line, ray, K());
00753 }
00754 
00755 template <class K>
00756 inline typename K::FT
00757 squared_distance(const Line_2<K> &line1, const Line_2<K> &line2)
00758 {
00759   return CGALi::squared_distance(line1, line2, K());
00760 }
00761 
00762 CGAL_END_NAMESPACE
00763 
00764 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines