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