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