BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/squared_distance_3_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_3/include/CGAL/squared_distance_3_1.h $
00019 // $Id: squared_distance_3_1.h 45223 2008-08-29 17:51:33Z spion $
00020 // 
00021 //
00022 // Author(s)     : Geert-Jan Giezeman, Andreas Fabri
00023 
00024 
00025 #ifndef CGAL_DISTANCE_3_1_H
00026 #define CGAL_DISTANCE_3_1_H
00027 
00028 
00029 #include <CGAL/squared_distance_3_0.h>
00030 
00031 #include <CGAL/Segment_3.h>
00032 #include <CGAL/Line_3.h>
00033 #include <CGAL/Ray_3.h>
00034 
00035 
00036 CGAL_BEGIN_NAMESPACE
00037 
00038 namespace CGALi {
00039 
00040 template <class K>
00041 typename K::FT
00042 squared_distance(
00043     const typename K::Point_3 &pt,
00044     const typename K::Line_3 &line,
00045     const K& k)
00046 {
00047   typedef typename K::Vector_3 Vector_3;
00048   typename K::Construct_vector_3 construct_vector;
00049   Vector_3 dir(line.direction().vector());
00050   Vector_3 diff = construct_vector(line.point(), pt);
00051   return CGALi::squared_distance_to_line(dir, diff, k);
00052 }
00053 
00054 template <class K>
00055 inline
00056 typename K::FT
00057 squared_distance(
00058     const typename K::Line_3 & line,
00059     const typename K::Point_3 & pt,
00060     const K& k)
00061 {
00062     return squared_distance(pt, line, k);
00063 }
00064 
00065 
00066 template <class K>
00067 typename K::FT
00068 squared_distance(
00069     const typename K::Point_3 &pt,
00070     const typename K::Ray_3 &ray,
00071     const K& k)
00072 {
00073   typename K::Construct_vector_3 construct_vector;
00074   typedef typename K::Vector_3 Vector_3;
00075 
00076     Vector_3 diff = construct_vector(ray.source(), pt);
00077     const Vector_3 &dir = ray.direction().vector();
00078     if (!is_acute_angle(dir,diff, k) )
00079         return (typename K::FT)(diff*diff);
00080     return squared_distance_to_line(dir, diff, k);
00081 }
00082 
00083 
00084 template <class K>
00085 inline
00086 typename K::FT
00087 squared_distance(
00088     const typename K::Ray_3 & ray,
00089     const typename K::Point_3 & pt,
00090     const K& k)
00091 {
00092     return squared_distance(pt, ray, k);
00093 }
00094 
00095 
00096 
00097 
00098 template <class K>
00099 typename K::FT
00100 squared_distance(
00101     const typename K::Point_3 &pt,
00102     const typename K::Segment_3 &seg,
00103     const K& k,
00104     const Homogeneous_tag)
00105 {
00106     typename K::Construct_vector_3 construct_vector;
00107     typedef typename K::Vector_3 Vector_3;
00108     typedef typename K::RT RT;
00109     typedef typename K::FT FT;
00110     // assert that the segment is valid (non zero length).
00111     Vector_3 diff = construct_vector(seg.source(), pt);
00112     Vector_3 segvec = construct_vector(seg.source(), seg.target());
00113     RT d = wdot(diff,segvec, k);
00114     if (d <= (RT)0)
00115         return (FT(diff*diff));
00116     RT e = wdot(segvec,segvec, k);
00117     if ( (d * segvec.hw()) > (e * diff.hw()))
00118         return squared_distance(pt, seg.target(), k);
00119 
00120     Vector_3 wcr = wcross(segvec, diff, k);
00121     return FT(wcr*wcr)/FT(e * diff.hw() * diff.hw());
00122 }
00123 
00124 template <class K>
00125 typename K::FT
00126 squared_distance(
00127     const typename K::Point_3 &pt,
00128     const typename K::Segment_3 &seg,
00129     const K& k,
00130     const Cartesian_tag&)
00131 {
00132     typename K::Construct_vector_3 construct_vector;
00133     typedef typename K::Vector_3 Vector_3;
00134     typedef typename K::RT RT;
00135     typedef typename K::FT FT;
00136     // assert that the segment is valid (non zero length).
00137     Vector_3 diff = construct_vector(seg.source(), pt);
00138     Vector_3 segvec = construct_vector(seg.source(), seg.target());
00139     RT d = wdot(diff,segvec, k);
00140     if (d <= (RT)0)
00141         return (FT(diff*diff));
00142     RT e = wdot(segvec,segvec, k);
00143     if (d > e)
00144         return squared_distance(pt, seg.target(), k);
00145 
00146     Vector_3 wcr = wcross(segvec, diff, k);
00147     return FT(wcr*wcr)/e;
00148 }
00149 
00150 
00151 template <class K>
00152 inline
00153 typename K::FT
00154 squared_distance(
00155     const typename K::Point_3 &pt,
00156     const typename K::Segment_3 &seg,
00157     const K& k)
00158 { 
00159   typedef typename K::Kernel_tag Tag;
00160   Tag tag;
00161   return squared_distance(pt, seg, k, tag);
00162 }
00163 
00164 
00165 template <class K>
00166 inline 
00167 typename K::FT
00168 squared_distance(
00169     const typename K::Segment_3 & seg,
00170     const typename K::Point_3 & pt,
00171     const K& k)
00172 {
00173     return squared_distance(pt, seg, k);
00174 }
00175 
00176 
00177 
00178 
00179 template <class K>
00180 typename K::FT
00181 squared_distance_parallel(
00182     const typename K::Segment_3 &seg1,
00183     const typename K::Segment_3 &seg2,
00184     const K& k)
00185 {
00186   typedef typename K::Vector_3 Vector_3;
00187     const Vector_3 &dir1 = seg1.direction().vector();
00188     const Vector_3 &dir2 = seg2.direction().vector();
00189  
00190     if (same_direction(dir1, dir2, k)) {
00191         if (!is_acute_angle(seg1.source(), seg1.target(), seg2.source(), k))
00192             return squared_distance(seg1.target(), seg2.source(), k);
00193         if (!is_acute_angle(seg1.target(), seg1.source(), seg2.target(), k))
00194             return squared_distance(seg1.source(), seg2.target(), k);
00195     } else {
00196         if (!is_acute_angle(seg1.source(), seg1.target(), seg2.target(), k))
00197             return squared_distance(seg1.target(), seg2.target(), k);
00198         if (!is_acute_angle(seg1.target(), seg1.source(), seg2.source(), k))
00199             return squared_distance(seg1.source(), seg2.source(), k);
00200     }
00201     return squared_distance(seg2.source(), seg1.supporting_line(), k);
00202 }
00203 
00204 
00205 
00206 template <class K>
00207 inline
00208 typename K::RT 
00209 _distance_measure_sub(typename K::RT startwdist, typename K::RT endwdist,
00210                          const typename K::Vector_3 &start, 
00211                          const typename K::Vector_3 &end,
00212                          const K&)
00213 {
00214     return  CGAL_NTS abs(wmult((K*)0, startwdist, end.hw())) -
00215             CGAL_NTS abs(wmult((K*)0, endwdist, start.hw()));
00216 }
00217 
00218 
00219 template <class K>
00220 typename K::FT
00221 squared_distance(
00222     const typename K::Segment_3 &seg1,
00223     const typename K::Segment_3 &seg2,
00224     const K& k)
00225 {
00226     typename K::Construct_vector_3 construct_vector;
00227     typedef typename K::Vector_3 Vector_3;
00228     typedef typename K::Point_3 Point_3;
00229     typedef typename K::RT RT;
00230     typedef typename K::FT FT;
00231     const Point_3 &start1 = seg1.source();
00232     const Point_3 &start2 = seg2.source();
00233     const Point_3 &end1 = seg1.target();
00234     const Point_3 &end2 = seg2.target();
00235 
00236     if (start1 == end1)
00237         return squared_distance(start1, seg2, k);
00238     if (start2 == end2)
00239         return squared_distance(start2, seg1, k);
00240     
00241     Vector_3 dir1, dir2, normal;
00242     dir1 = seg1.direction().vector();
00243     dir2 = seg2.direction().vector();
00244     normal = wcross(dir1, dir2, k);
00245     if (is_null(normal, k))
00246         return squared_distance_parallel(seg1, seg2, k);
00247     
00248     bool crossing1, crossing2;
00249     RT sdm_s1to2, sdm_e1to2, sdm_s2to1, sdm_e2to1;
00250     Vector_3 perpend1, perpend2, s2mins1, e2mins1, e1mins2;
00251     perpend1 = wcross(dir1, normal, k);
00252     perpend2 = wcross(dir2, normal, k);
00253     s2mins1 = construct_vector(start1, start2);
00254     e2mins1 = construct_vector(start1, end2);
00255     e1mins2 = construct_vector(start2, end1);
00256     sdm_s1to2 = -RT(wdot(perpend2, s2mins1, k));
00257     sdm_e1to2 = wdot(perpend2, e1mins2, k);
00258     sdm_s2to1 = wdot(perpend1, s2mins1, k);
00259     sdm_e2to1 = wdot(perpend1, e2mins1, k);
00260     
00261     if (sdm_s1to2 < RT(0)) {
00262         crossing1 = (sdm_e1to2 >= RT(0));
00263     } else {
00264         if (sdm_e1to2 <= RT(0)) {
00265             crossing1 = true;
00266         } else {
00267             crossing1 = (sdm_s1to2 == RT(0));
00268         }
00269     }
00270     if (sdm_s2to1 < RT(0)) {
00271         crossing2 = (sdm_e2to1 >= RT(0));
00272     } else {
00273         if (sdm_e2to1 <= RT(0)) {
00274             crossing2 = true;
00275         } else {
00276             crossing2 = (sdm_s2to1 == RT(0));
00277         }
00278     }
00279     
00280     if (crossing1) {
00281         if (crossing2) {
00282             return squared_distance_to_plane(normal, s2mins1, k);
00283         }
00284     
00285         RT dm;
00286         dm = _distance_measure_sub(
00287                   sdm_s2to1, sdm_e2to1, s2mins1, e2mins1, k);
00288         if (dm < RT(0)) {
00289             return squared_distance(start2, seg1, k);
00290         } else {
00291             if (dm > RT(0)) {
00292                 return squared_distance(end2, seg1, k);
00293             } else {
00294                 // should not happen with exact arithmetic.
00295                 return squared_distance_parallel(seg1, seg2, k);
00296             }
00297         }
00298     } else {
00299         if (crossing2) {
00300             RT dm;
00301             dm =_distance_measure_sub(
00302                  sdm_s1to2, sdm_e1to2, s2mins1, e1mins2, k);
00303             if (dm < RT(0)) {
00304                 return squared_distance(start1, seg2, k);
00305             } else {
00306                 if (dm > RT(0)) {
00307                     return squared_distance(end1, seg2, k);
00308                 } else {
00309                     // should not happen with exact arithmetic.
00310                     return squared_distance_parallel(seg1, seg2, k);
00311                 }
00312             }
00313         } else {
00314             FT min1, min2;
00315             RT dm;
00316             dm = _distance_measure_sub(
00317                      sdm_s1to2, sdm_e1to2, s2mins1, e1mins2, k);
00318             if (dm == RT(0)) // should not happen with exact arithmetic.
00319                return squared_distance_parallel(seg1, seg2, k);
00320             min1 = (dm < RT(0)) ?
00321                 squared_distance(seg1.source(), seg2, k):
00322                 squared_distance(end1, seg2, k);
00323             dm = _distance_measure_sub(
00324                      sdm_s2to1, sdm_e2to1, s2mins1, e2mins1, k);
00325             if (dm == RT(0)) // should not happen with exact arithmetic.
00326                 return squared_distance_parallel(seg1, seg2, k);
00327             min2 = (dm < RT(0)) ?
00328                 squared_distance(start2, seg1, k):
00329                 squared_distance(end2, seg1, k);
00330             return (min1 < min2) ? min1 : min2;
00331         }
00332     }
00333     
00334 }
00335 
00336 
00337 
00338 
00339 
00340 
00341 template <class K>
00342 typename K::FT
00343 squared_distance_parallel(
00344     const typename K::Segment_3 &seg,
00345     const typename K::Ray_3 &ray,
00346     const K& k)
00347 {
00348 
00349   typedef typename K::Vector_3 Vector_3;
00350   bool same_direction;
00351   const Vector_3 &dir1 = seg.direction().vector();
00352   const Vector_3 &dir2 = ray.direction().vector();
00353   if (CGAL_NTS abs(dir1.hx()) > CGAL_NTS abs(dir1.hy())) {
00354     same_direction = (CGAL_NTS sign(dir1.hx()) == CGAL_NTS sign(dir2.hx()));
00355   } else {
00356     same_direction = (CGAL_NTS sign(dir1.hy()) == CGAL_NTS sign(dir2.hy()));
00357   }
00358   if (same_direction) {
00359     if (!is_acute_angle(seg.source(), seg.target(), ray.source(), k))
00360       return squared_distance(seg.target(), ray.source(), k);
00361   } else {
00362     if (!is_acute_angle(seg.target(), seg.source(), ray.source(), k))
00363       return squared_distance(seg.source(), ray.source(), k);
00364   }
00365   return squared_distance(ray.source(), seg.supporting_line(), k);
00366 }
00367 
00368 
00369 template <class K>
00370 typename K::FT
00371 squared_distance(
00372     const typename K::Segment_3 &seg,
00373     const typename K::Ray_3 &ray,
00374     const K& k)
00375 {
00376     typename K::Construct_vector_3 construct_vector;
00377     typedef typename K::Point_3 Point_3;
00378     typedef typename K::Vector_3 Vector_3;
00379     typedef typename K::RT RT;
00380     typedef typename K::FT FT;
00381     const Point_3 & ss = seg.source();
00382     const Point_3 & se = seg.target();
00383     if (ss == se)
00384         return squared_distance(ss, ray, k);
00385     Vector_3 raydir, segdir, normal;
00386     raydir = ray.direction().vector();
00387     segdir = seg.direction().vector();
00388     normal = wcross(segdir, raydir, k);
00389     if (is_null(normal, k))
00390         return squared_distance_parallel(seg, ray, k);
00391 
00392     bool crossing1, crossing2;
00393     RT sdm_ss2r, sdm_se2r, sdm_rs2s, sdm_re2s;
00394     Vector_3 perpend2seg, perpend2ray, ss_min_rs, se_min_rs;
00395     perpend2seg = wcross(segdir, normal, k);
00396     perpend2ray = wcross(raydir, normal, k);
00397     ss_min_rs = construct_vector(ray.source(), ss);
00398     se_min_rs = construct_vector(ray.source(), se);
00399     sdm_ss2r = wdot(perpend2ray, ss_min_rs, k);
00400     sdm_se2r = wdot(perpend2ray, se_min_rs, k);
00401     if (sdm_ss2r < RT(0)) {
00402         crossing1 = (sdm_se2r >= RT(0));
00403     } else {
00404         if (sdm_se2r <= RT(0)) {
00405             crossing1 = true;
00406         } else {
00407             crossing1 = (sdm_ss2r == RT(0));
00408         }
00409     }
00410 
00411     sdm_rs2s = -RT(wdot(perpend2seg, ss_min_rs, k));
00412     sdm_re2s = wdot(perpend2seg, raydir, k);
00413     if (sdm_rs2s < RT(0)) {
00414         crossing2 = (sdm_re2s >= RT(0));
00415     } else {
00416         if (sdm_re2s <= RT(0)) {
00417             crossing2 = true;
00418         } else {
00419             crossing2 = (sdm_rs2s == RT(0));
00420         }
00421     }
00422 
00423     if (crossing1) {
00424         if (crossing2) {
00425             return squared_distance_to_plane(normal, ss_min_rs, k);
00426         }
00427         return squared_distance(ray.source(), seg, k);
00428     } else {
00429         if (crossing2) {
00430             RT dm;
00431             dm = _distance_measure_sub(
00432                     sdm_ss2r, sdm_se2r, ss_min_rs, se_min_rs, k);
00433             if (dm < RT(0)) {
00434                 return squared_distance(ss, ray, k);
00435             } else {
00436                 if (dm > RT(0)) {
00437                     return squared_distance(se, ray, k);
00438                 } else {
00439                     // parallel, should not happen (no crossing)
00440                     return squared_distance_parallel(seg, ray, k);
00441                 }
00442             }
00443         } else {
00444             FT min1, min2;
00445             RT dm;
00446             dm = _distance_measure_sub(
00447                     sdm_ss2r, sdm_se2r, ss_min_rs, se_min_rs, k);
00448             if (dm == RT(0))
00449                 return squared_distance_parallel(seg, ray, k);
00450             min1 = (dm < RT(0))
00451                  ? squared_distance(ss, ray, k)
00452                  : squared_distance(se, ray, k);
00453             min2 = squared_distance(ray.source(), seg, k);
00454             return (min1 < min2) ? min1 : min2;
00455         }
00456     }
00457 }
00458 
00459 
00460 
00461 template <class K>
00462 inline
00463 typename K::FT
00464 squared_distance(
00465     const typename K::Ray_3 & ray,
00466     const typename K::Segment_3 & seg,
00467     const K& k)
00468 {
00469     return squared_distance(seg, ray, k);
00470 }
00471 
00472 
00473 template <class K>
00474 typename K::FT
00475 squared_distance(
00476     const typename K::Segment_3 &seg,
00477     const typename K::Line_3 &line,
00478     const K& k)
00479 {
00480     typename K::Construct_vector_3 construct_vector;
00481     typedef typename K::Vector_3 Vector_3;
00482     typedef typename K::Point_3 Point_3;
00483     typedef typename K::RT RT;
00484     const Point_3 &linepoint = line.point();
00485     const Point_3 &start = seg.source();
00486     const Point_3 &end = seg.target();
00487 
00488     if (start == end)
00489         return squared_distance(start, line, k);
00490     Vector_3 linedir = line.direction().vector();
00491     Vector_3 segdir = seg.direction().vector();
00492     Vector_3 normal = wcross(segdir, linedir, k);
00493     if (is_null(normal, k))
00494         return squared_distance_to_line(linedir, 
00495                                         construct_vector(linepoint,start), k);
00496 
00497     bool crossing;
00498     RT sdm_ss2l, sdm_se2l;
00499     Vector_3 perpend2line, start_min_lp, end_min_lp;
00500     perpend2line = wcross(linedir, normal, k);
00501     start_min_lp = construct_vector(linepoint, start);
00502     end_min_lp = construct_vector(linepoint, end);
00503     sdm_ss2l = wdot(perpend2line, start_min_lp, k);
00504     sdm_se2l = wdot(perpend2line, end_min_lp, k);
00505     if (sdm_ss2l < RT(0)) {
00506         crossing = (sdm_se2l >= RT(0));
00507     } else {
00508         if (sdm_se2l <= RT(0)) {
00509             crossing = true;
00510         } else {
00511             crossing = (sdm_ss2l == RT(0));
00512         }
00513     }
00514 
00515     if (crossing) {
00516         return squared_distance_to_plane(normal, start_min_lp, k);
00517     } else {
00518         RT dm;
00519         dm = _distance_measure_sub(
00520                 sdm_ss2l, sdm_se2l, start_min_lp, end_min_lp, k);
00521         if (dm <= RT(0)) {
00522             return squared_distance_to_line(linedir, start_min_lp, k);
00523         } else {
00524             return squared_distance_to_line(linedir, end_min_lp, k);
00525         }
00526     }
00527 }
00528 
00529 
00530 template <class K>
00531 inline 
00532 typename K::FT
00533 squared_distance(
00534     const typename K::Line_3 & line,
00535     const typename K::Segment_3 & seg,
00536     const K& k)
00537 {
00538     return squared_distance(seg, line, k);
00539 }
00540 
00541 
00542 
00543 
00544 template <class K>
00545 typename K::FT
00546 ray_ray_squared_distance_parallel(
00547     const typename K::Vector_3 &ray1dir,
00548     const typename K::Vector_3 &ray2dir,
00549     const typename K::Vector_3 &s1_min_s2,
00550     const K& k)
00551 {
00552   if (!is_acute_angle(ray2dir, s1_min_s2, k)) {
00553     if (!same_direction(ray1dir, ray2dir, k))
00554       return (typename K::FT)(s1_min_s2*s1_min_s2);
00555   }
00556   return squared_distance_to_line(ray1dir, s1_min_s2, k);
00557 }
00558 
00559 
00560 template <class K>
00561 typename K::FT
00562 squared_distance(
00563     const typename K::Ray_3 &ray1,
00564     const typename K::Ray_3 &ray2,
00565     const K& k)
00566 {
00567   typename K::Construct_vector_3 construct_vector;
00568     typedef typename K::Vector_3 Vector_3;
00569     typedef typename K::Point_3 Point_3;
00570     typedef typename K::RT RT;
00571     typedef typename K::FT FT;
00572     const Point_3 & s1 = ray1.source();
00573     const Point_3 & s2 = ray2.source();
00574     Vector_3 dir1, dir2, normal;
00575     dir1 = ray1.direction().vector();
00576     dir2 = ray2.direction().vector();
00577     normal = wcross(dir1, dir2, k);
00578     Vector_3 s1_min_s2 = construct_vector(s2, s1);
00579     if (is_null(normal, k))
00580         return ray_ray_squared_distance_parallel(dir1, dir2, s1_min_s2, k);
00581 
00582     bool crossing1, crossing2;
00583     RT sdm_s1_2, sdm_s2_1;
00584     Vector_3 perpend1, perpend2;
00585     perpend1 = wcross(dir1, normal, k);
00586     perpend2 = wcross(dir2, normal, k);
00587 
00588     sdm_s1_2 = wdot(perpend2, s1_min_s2, k);
00589     if (sdm_s1_2 < RT(0)) {
00590         crossing1 = (RT(wdot(perpend2, dir1, k)) >= RT(0));
00591     } else {
00592         if (RT(wdot(perpend2, dir1, k)) <= RT(0)) {
00593             crossing1 = true;
00594         } else {
00595             crossing1 = (sdm_s1_2 == RT(0));
00596         }
00597     }
00598     sdm_s2_1 = -RT(wdot(perpend1, s1_min_s2, k));
00599     if (sdm_s2_1 < RT(0)) {
00600         crossing2 = (RT(wdot(perpend1, dir2, k)) >= RT(0));
00601     } else {
00602         if (RT(wdot(perpend1, dir2, k)) <= RT(0)) {
00603             crossing2 = true;
00604         } else {
00605             crossing2 = (sdm_s2_1 == RT(0));
00606         }
00607     }
00608     if (crossing1) {
00609         if (crossing2)
00610             return squared_distance_to_plane(normal, s1_min_s2, k);
00611         return squared_distance(ray2.source(), ray1, k);
00612     } else {
00613         if (crossing2) {
00614             return squared_distance(ray1.source(), ray2, k);
00615         } else {
00616           FT min1, min2;
00617             min1 = squared_distance(ray1.source(), ray2, k);
00618             min2 = squared_distance(ray2.source(), ray1, k);
00619             return (min1 < min2) ? min1 : min2;
00620         }
00621     }
00622 }
00623 
00624 
00625 
00626 
00627 
00628 template <class K>
00629 typename K::FT
00630 squared_distance(
00631     const typename K::Line_3 &line,
00632     const typename K::Ray_3 &ray,
00633     const K& k)
00634 {
00635   typename K::Construct_vector_3 construct_vector;
00636   typedef typename K::Vector_3 Vector_3;
00637   typedef typename K::Point_3 Point_3;
00638     typedef typename K::RT RT;
00639     const Point_3 & rs =ray.source();
00640     Vector_3 raydir, linedir, normal;
00641     linedir = line.direction().vector();
00642     raydir = ray.direction().vector();
00643     normal = wcross(raydir, linedir, k);
00644     Vector_3 rs_min_lp = construct_vector(line.point(), rs);
00645     if (is_null(normal, k))
00646         return squared_distance_to_line(linedir, rs_min_lp, k);
00647 
00648     bool crossing;
00649     RT sdm_sr_l;
00650     Vector_3 perpend2l;
00651     perpend2l = wcross(linedir, normal, k);
00652 
00653     sdm_sr_l = wdot(perpend2l, rs_min_lp, k);
00654     if (sdm_sr_l < RT(0)) {
00655         crossing = (RT(wdot(perpend2l, raydir, k)) >= RT(0));
00656     } else {
00657         if (RT(wdot(perpend2l, raydir, k)) <= RT(0)) {
00658             crossing = true;
00659         } else {
00660             crossing = (sdm_sr_l == RT(0));
00661         }
00662     }
00663 
00664     if (crossing)
00665         return squared_distance_to_plane(normal, rs_min_lp, k);
00666     else
00667         return squared_distance_to_line(linedir, rs_min_lp, k);
00668 }
00669 
00670 
00671 template <class K>
00672 inline typename K::FT
00673 squared_distance(
00674     const typename K::Ray_3 & ray,
00675     const typename K::Line_3 & line,
00676     const K& k)
00677 {
00678     return squared_distance(line, ray, k);
00679 }
00680 
00681 
00682 
00683 
00684 template <class K>
00685 typename K::FT
00686 squared_distance(
00687     const typename K::Line_3 &line1,
00688     const typename K::Line_3 &line2,
00689     const K& k)
00690 {   
00691   typename K::Construct_vector_3 construct_vector;
00692     typedef typename K::Vector_3 Vector_3;
00693 
00694     Vector_3 dir1, dir2, normal, diff;
00695     dir1 = line1.direction().vector();
00696     dir2 = line2.direction().vector();
00697     normal = wcross(dir1, dir2, k);
00698     diff = construct_vector(line1.point(), line2.point());
00699     if (is_null(normal, k))
00700         return squared_distance_to_line(dir2, diff, k);
00701     return squared_distance_to_plane(normal, diff, k);
00702 }
00703 
00704 
00705 
00706 } // namespace CGALi
00707 
00708 
00709 
00710 template <class K>
00711 inline
00712 typename K::FT
00713 squared_distance(const Point_3<K> &pt,
00714                  const Line_3<K> &line)
00715 {
00716   return CGALi::squared_distance(pt, line, K());
00717 }
00718 
00719 
00720 template <class K>
00721 inline
00722 typename K::FT
00723 squared_distance(
00724     const Line_3<K> & line,
00725     const Point_3<K> & pt)
00726 {
00727   return CGALi::squared_distance(pt, line, K());
00728 }
00729 
00730 
00731 template <class K>
00732 inline
00733 typename K::FT
00734 squared_distance(
00735     const Point_3<K> &pt,
00736     const Ray_3<K> &ray)
00737 {
00738     return CGALi::squared_distance(pt, ray, K());
00739 }
00740 
00741 
00742 template <class K>
00743 inline 
00744 typename K::FT
00745 squared_distance(
00746     const Ray_3<K> & ray,
00747     const Point_3<K> & pt)
00748 {
00749     return CGALi::squared_distance(pt, ray, K());
00750 }
00751 
00752 
00753 template <class K>
00754 inline
00755 typename K::FT
00756 squared_distance(
00757     const Point_3<K> &pt,
00758     const Segment_3<K> &seg)
00759 {
00760   return CGALi::squared_distance(pt, seg, K());
00761 }
00762 
00763 
00764 template <class K>
00765 inline 
00766 typename K::FT
00767 squared_distance(
00768     const Segment_3<K> & seg,
00769     const Point_3<K> & pt)
00770 {
00771     return CGALi::squared_distance(pt, seg, K());
00772 }
00773 
00774 
00775 
00776 
00777 template <class K>
00778 inline
00779 typename K::FT
00780 squared_distance_parallel(
00781     const Segment_3<K> &seg1,
00782     const Segment_3<K> &seg2)
00783 {
00784   return CGALi::squared_distance_parallel(seg1, seg2, K());
00785 }
00786 
00787 
00788 
00789 
00790 template <class K>
00791 inline
00792 typename K::FT
00793 squared_distance(const Segment_3<K> &seg1,
00794                  const Segment_3<K> &seg2)
00795 {
00796   return CGALi::squared_distance(seg1, seg2, K());
00797 }
00798 
00799 
00800 
00801 
00802 
00803 
00804 template <class K>
00805 inline
00806 typename K::FT
00807 squared_distance_parallel(
00808     const Segment_3<K> &seg,
00809     const Ray_3<K> &ray)
00810 {
00811   return CGALi::squared_distance_parallel(ray,seg, K());
00812 }
00813 
00814 
00815 template <class K>
00816 inline
00817 typename K::FT
00818 squared_distance(
00819     const Segment_3<K> &seg,
00820     const Ray_3<K> &ray)
00821 {
00822   return CGALi::squared_distance(ray, seg, K());
00823 }
00824 
00825 
00826 
00827 template <class K>
00828 inline
00829 typename K::FT
00830 squared_distance(
00831     const Ray_3<K> & ray,
00832     const Segment_3<K> & seg)
00833 {
00834     return CGALi::squared_distance(seg, ray, K());
00835 }
00836 
00837 
00838 template <class K>
00839 inline
00840 typename K::FT
00841 squared_distance(
00842     const Segment_3<K> &seg,
00843     const Line_3<K> &line)
00844 {
00845   return CGALi::squared_distance(seg, line, K());
00846 }
00847 
00848 
00849 template <class K>
00850 inline 
00851 typename K::FT
00852 squared_distance(
00853     const Line_3<K> & line,
00854     const Segment_3<K> & seg)
00855 {
00856     return CGALi::squared_distance(seg, line, K());
00857 }
00858 
00859 
00860 
00861 
00862 template <class K>
00863 inline
00864 typename K::FT
00865 ray_ray_squared_distance_parallel(
00866     const Vector_3<K> &ray1dir,
00867     const Vector_3<K> &ray2dir,
00868     const Vector_3<K> &s1_min_s2)
00869 {
00870   return CGALi::ray_ray_squared_distance_parallel(ray1dir, ray2dir, 
00871                                                   s1_min_s2, K());
00872 }
00873 
00874 template <class K>
00875 inline
00876 typename K::FT
00877 squared_distance(
00878     const Ray_3<K> &ray1,
00879     const Ray_3<K> &ray2)
00880 {
00881   return CGALi::squared_distance(ray1, ray2, K());
00882 }
00883 
00884 
00885 
00886 
00887 
00888 template <class K>
00889 inline
00890 typename K::FT
00891 squared_distance(
00892     const Line_3<K> &line,
00893     const Ray_3<K> &ray)
00894 {
00895   return CGALi::squared_distance(line, ray, K());
00896 }
00897 
00898 
00899 template <class K>
00900 inline
00901 typename K::FT
00902 squared_distance(
00903     const Ray_3<K> & ray,
00904     const Line_3<K> & line)
00905 {
00906     return CGALi::squared_distance(line, ray, K());
00907 }
00908 
00909 
00910 
00911 
00912 template <class K>
00913 inline
00914 typename K::FT
00915 squared_distance(
00916     const Line_3<K> &line1,
00917     const Line_3<K> &line2)
00918 {  
00919     return CGALi::squared_distance(line1, line2, K());
00920 }
00921 
00922 
00923 
00924 CGAL_END_NAMESPACE
00925 
00926 
00927 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines