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