BWAPI
|
00001 // Copyright (c) 1997-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/Intersections_3/include/CGAL/Intersections_3/intersection_3_1_impl.h $ 00019 // $Id: intersection_3_1_impl.h 43518 2008-06-09 07:58:50Z pmachado $ 00020 // 00021 // 00022 // Author(s) : Geert-Jan Giezeman <geert@cs.uu.nl> 00023 00024 00025 #include <CGAL/wmult.h> 00026 00027 CGAL_BEGIN_NAMESPACE 00028 00029 namespace CGALi { 00030 00031 template <class K> 00032 Object 00033 intersection(const typename K::Plane_3 &plane, 00034 const typename K::Line_3 &line, 00035 const K&) 00036 { 00037 typedef typename K::Point_3 Point_3; 00038 typedef typename K::Direction_3 Direction_3; 00039 typedef typename K::RT RT; 00040 00041 const Point_3 &line_pt = line.point(); 00042 const Direction_3 &line_dir = line.direction(); 00043 00044 RT num = plane.a()*line_pt.hx() + plane.b()*line_pt.hy() 00045 + plane.c()*line_pt.hz() + wmult_hw((K*)0, plane.d(), line_pt); 00046 RT den = plane.a()*line_dir.dx() + plane.b()*line_dir.dy() 00047 + plane.c()*line_dir.dz(); 00048 if (den == 0) { 00049 if (num == 0) { 00050 // all line 00051 return make_object(line); 00052 } else { 00053 // no intersection 00054 return Object(); 00055 } 00056 } 00057 return make_object(Point_3( 00058 den*line_pt.hx()-num*line_dir.dx(), 00059 den*line_pt.hy()-num*line_dir.dy(), 00060 den*line_pt.hz()-num*line_dir.dz(), 00061 wmult_hw((K*)0, den, line_pt))); 00062 } 00063 00064 template <class K> 00065 inline 00066 Object 00067 intersection(const typename K::Line_3 &line, 00068 const typename K::Plane_3 &plane, 00069 const K& k) 00070 { 00071 return intersection(plane, line, k); 00072 } 00073 00074 template <class K> 00075 Object 00076 intersection(const typename K::Plane_3 &plane1, 00077 const typename K::Plane_3 &plane2, 00078 const K&) 00079 { 00080 typedef typename K::Point_3 Point_3; 00081 typedef typename K::Direction_3 Direction_3; 00082 typedef typename K::Line_3 Line_3; 00083 00084 typedef typename K::RT RT; 00085 const RT &a = plane1.a(); 00086 const RT &b = plane1.b(); 00087 const RT &c = plane1.c(); 00088 const RT &d = plane1.d(); 00089 const RT &p = plane2.a(); 00090 const RT &q = plane2.b(); 00091 const RT &r = plane2.c(); 00092 const RT &s = plane2.d(); 00093 00094 RT det = a*q-p*b; 00095 if (det != 0) { 00096 Point_3 is_pt = Point_3(b*s-d*q, p*d-a*s, 0, det); 00097 Direction_3 is_dir = Direction_3(b*r-c*q, p*c-a*r, det); 00098 return make_object(Line_3(is_pt, is_dir)); 00099 } 00100 det = a*r-p*c; 00101 if (det != 0) { 00102 Point_3 is_pt = Point_3(c*s-d*r, 0, p*d-a*s, det); 00103 Direction_3 is_dir = Direction_3(c*q-b*r, det, p*b-a*q); 00104 return make_object(Line_3(is_pt, is_dir)); 00105 } 00106 det = b*r-c*q; 00107 if (det != 0) { 00108 Point_3 is_pt = Point_3(0, c*s-d*r, d*q-b*s, det); 00109 Direction_3 is_dir = Direction_3(det, c*p-a*r, a*q-b*p); 00110 return make_object(Line_3(is_pt, is_dir)); 00111 } 00112 // degenerate case 00113 if (a!=0 || p!=0) { 00114 if (a*s == p*d) 00115 return make_object(plane1); 00116 else 00117 return Object(); 00118 } 00119 if (b!=0 || q!=0) { 00120 if (b*s == q*d) 00121 return make_object(plane1); 00122 else 00123 return Object(); 00124 } 00125 if (c!=0 || r!=0) { 00126 if (c*s == r*d) 00127 return make_object(plane1); 00128 else 00129 return Object(); 00130 } 00131 return make_object(plane1); 00132 } 00133 00134 template <class K> 00135 Object 00136 intersection(const typename K::Plane_3 &plane1, 00137 const typename K::Plane_3 &plane2, 00138 const typename K::Plane_3 &plane3, 00139 const K& k) 00140 { 00141 typedef typename K::Line_3 Line_3; 00142 typedef typename K::Plane_3 Plane_3; 00143 00144 // Intersection between plane1 and plane2 can either be 00145 // a line, a plane, or empty. 00146 Object o12 = CGALi::intersection(plane1, plane2, k); 00147 00148 if (const Line_3 *l = object_cast<Line_3>(&o12)) 00149 return CGALi::intersection(plane3, *l, k); 00150 00151 if (const Plane_3 *pl = object_cast<Plane_3>(&o12)) 00152 return CGALi::intersection(plane3, *pl, k); 00153 00154 return Object(); 00155 } 00156 00157 00158 template <class K> 00159 bool 00160 do_intersect(const typename K::Plane_3 &plane, 00161 const typename K::Line_3 &line, 00162 const K&) 00163 { 00164 typedef typename K::Point_3 Point_3; 00165 typedef typename K::Direction_3 Direction_3; 00166 typedef typename K::RT RT; 00167 const Point_3 &line_pt = line.point(); 00168 const Direction_3 &line_dir = line.direction(); 00169 00170 RT den = plane.a()*line_dir.dx() + plane.b()*line_dir.dy() 00171 + plane.c()*line_dir.dz(); 00172 if (den != 0) 00173 return true; 00174 RT num = plane.a()*line_pt.hx() + plane.b()*line_pt.hy() 00175 + plane.c()*line_pt.hz() + wmult_hw((K*)0, plane.d(), line_pt); 00176 if (num == 0) { 00177 // all line 00178 return true; 00179 } else { 00180 // no intersection 00181 return false; 00182 } 00183 } 00184 00185 template <class K> 00186 inline 00187 bool 00188 do_intersect(const typename K::Line_3 &line, 00189 const typename K::Plane_3 &plane, 00190 const K& k) 00191 { 00192 return do_intersect(plane, line, k); 00193 } 00194 00195 template <class K> 00196 Object 00197 intersection(const typename K::Line_3 &l1, 00198 const typename K::Line_3 &l2, 00199 const K&) 00200 { 00201 typedef typename K::FT FT; 00202 typedef typename K::Line_3 Line_3; 00203 typedef typename K::Point_3 Point_3; 00204 typedef typename K::Vector_3 Vector_3; 00205 00206 if(K().has_on_3_object()(l1, l2.point())) { 00207 const Vector_3& v1 = l1.to_vector(); 00208 const Vector_3& v2 = l2.to_vector(); 00209 if((v1.x() * v2.y() == v1.y() * v2.x()) && 00210 (v1.x() * v2.z() == v1.z() * v2.x()) && 00211 (v1.y() * v2.z() == v1.z() * v2.y())) 00212 return make_object(l1); 00213 } 00214 00215 if(K().are_parallel_3_object()(l1,l2)) return Object(); 00216 const Point_3 &p1 = l1.point(); 00217 const Point_3 &p3 = l2.point(); 00218 const Vector_3 &v1 = l1.to_vector(); 00219 const Vector_3 &v2 = l2.to_vector(); 00220 const Point_3 p2 = p1 + v1; 00221 const Point_3 p4 = p2 + v2; 00222 if(!K().coplanar_3_object()(p1,p2,p3,p4)) return Object(); 00223 const Vector_3 v3 = p3 - p1; 00224 const Vector_3 v3v2 = cross_product(v3,v2); 00225 const Vector_3 v1v2 = cross_product(v1,v2); 00226 const FT t = ((v3v2.x()*v1v2.x()) + (v3v2.y()*v1v2.y()) + (v3v2.z()*v1v2.z())) / 00227 (v1v2.squared_length()); 00228 return make_object(p1 + (v1 * t)); 00229 } 00230 00231 template <class K> 00232 bool 00233 do_intersect(const typename K::Line_3 &l1, 00234 const typename K::Line_3 &l2, 00235 const K&) 00236 { 00237 typedef typename K::FT FT; 00238 typedef typename K::Line_3 Line_3; 00239 typedef typename K::Point_3 Point_3; 00240 typedef typename K::Vector_3 Vector_3; 00241 00242 if(K().has_on_3_object()(l1, l2.point())) return true; 00243 if(K().are_parallel_3_object()(l1,l2)) return false; 00244 const Point_3 &p1 = l1.point(); 00245 const Point_3 &p3 = l2.point(); 00246 const Vector_3 &v1 = l1.to_vector(); 00247 const Vector_3 &v2 = l2.to_vector(); 00248 const Point_3 p2 = p1 + v1; 00249 const Point_3 p4 = p2 + v2; 00250 return K().coplanar_3_object()(p1,p2,p3,p4); 00251 } 00252 00253 template <class K> 00254 Object 00255 intersection(const typename K::Plane_3 &p, 00256 const typename K::Sphere_3 &s, 00257 const K&) 00258 { 00259 typedef typename K::Sphere_3 Sphere_3; 00260 typedef typename K::Circle_3 Circle_3; 00261 typedef typename K::Plane_3 Plane_3; 00262 typedef typename K::Point_3 Point_3; 00263 typedef typename K::FT FT; 00264 const FT d2 = CGAL::square(p.a()*s.center().x() + 00265 p.b()*s.center().y() + 00266 p.c()*s.center().z() + p.d()) / 00267 (square(p.a()) + square(p.b()) + square(p.c())); 00268 const FT cmp = d2 - s.squared_radius(); 00269 if(CGAL_NTS is_zero(cmp)) { // tangent 00270 return make_object(p.projection(s.center())); 00271 } else if(CGAL_NTS is_negative(cmp)) { // intersect 00272 Point_3 center = p.projection(s.center()); 00273 return make_object(Circle_3(center,s.squared_radius() - d2,p)); 00274 } // do not intersect 00275 return Object(); 00276 } 00277 00278 template <class K> 00279 inline 00280 bool 00281 do_intersect(const typename K::Plane_3 &p, 00282 const typename K::Sphere_3 &s, 00283 const K&) 00284 { 00285 typedef typename K::Sphere_3 Sphere_3; 00286 typedef typename K::Circle_3 Circle_3; 00287 typedef typename K::Plane_3 Plane_3; 00288 typedef typename K::Point_3 Point_3; 00289 typedef typename K::FT FT; 00290 const FT d2 = CGAL::square(p.a()*s.center().x() + 00291 p.b()*s.center().y() + 00292 p.c()*s.center().z() + p.d()) / 00293 (square(p.a()) + square(p.b()) + square(p.c())); 00294 return d2 <= s.squared_radius(); 00295 } 00296 00297 template <class K> 00298 inline 00299 bool 00300 do_intersect(const typename K::Sphere_3 &s, 00301 const typename K::Plane_3 &p, 00302 const K& k) 00303 { 00304 return do_intersect(p,s); 00305 } 00306 00307 00308 template <class K> 00309 inline 00310 Object 00311 intersection(const typename K::Sphere_3 &s, 00312 const typename K::Plane_3 &p, 00313 const K& k) 00314 { 00315 return intersection(p, s, k); 00316 } 00317 00318 template <class K> 00319 inline 00320 Object 00321 intersection(const typename K::Sphere_3 &s1, 00322 const typename K::Sphere_3 &s2, 00323 const K& k) 00324 { 00325 typedef typename K::Plane_3 Plane_3; 00326 typedef typename K::Sphere_3 Sphere_3; 00327 if(s1.center() == s2.center()) { 00328 if(s1.squared_radius() == s2.squared_radius()) { 00329 if(is_zero(s1.squared_radius())) return make_object(s1.center()); 00330 else return make_object(s1); 00331 } else return Object(); // cocentrics 00332 } 00333 Plane_3 p = K().construct_radical_plane_3_object()(s1,s2); 00334 return intersection(p, s1, k); 00335 } 00336 00337 template <class K> 00338 inline 00339 bool 00340 do_intersect(const typename K::Sphere_3 &s1, 00341 const typename K::Sphere_3 &s2, 00342 const K& k) 00343 { 00344 typedef typename K::Plane_3 Plane_3; 00345 typedef typename K::Sphere_3 Sphere_3; 00346 if(s1.center() == s2.center()) { 00347 return s1.squared_radius() == s2.squared_radius(); 00348 } 00349 Plane_3 p = K().construct_radical_plane_3_object()(s1,s2); 00350 return do_intersect(p, s1, k); 00351 } 00352 00353 template <class K> 00354 Object 00355 intersection(const typename K::Plane_3 &plane, 00356 const typename K::Ray_3 &ray, 00357 const K& k) 00358 { 00359 typedef typename K::Point_3 Point_3; 00360 const Object line_intersection = 00361 intersection(plane, ray.supporting_line(), k); 00362 if (const Point_3 *isp = object_cast<Point_3>(&line_intersection)) { 00363 if (ray.collinear_has_on(*isp)) 00364 return line_intersection; 00365 else 00366 return Object(); 00367 } 00368 if (line_intersection.is_empty()) 00369 return line_intersection; 00370 return make_object(ray); 00371 } 00372 00373 00374 template <class K> 00375 inline 00376 Object 00377 intersection(const typename K::Ray_3 &ray, 00378 const typename K::Plane_3 &plane, 00379 const K& k) 00380 { 00381 return intersection(plane, ray, k); 00382 } 00383 00384 00385 00386 template <class K> 00387 bool 00388 do_intersect(const typename K::Plane_3 &plane, 00389 const typename K::Ray_3 &ray, 00390 const K& k) 00391 { 00392 typedef typename K::Point_3 Point_3; 00393 const Object line_intersection = 00394 intersection(plane, ray.supporting_line(), k); 00395 if (line_intersection.is_empty()) 00396 return false; 00397 if (const Point_3 *isp = object_cast<Point_3>(&line_intersection)) 00398 return ray.collinear_has_on(*isp); 00399 return true; 00400 } 00401 00402 00403 template <class K> 00404 inline 00405 bool 00406 do_intersect(const typename K::Ray_3 &ray, 00407 const typename K::Plane_3 &plane, 00408 const K& k) 00409 { 00410 return do_intersect(plane, ray, k); 00411 } 00412 00413 00414 template <class K> 00415 Object 00416 intersection(const typename K::Plane_3 &plane, 00417 const typename K::Segment_3 &seg, 00418 const K& k) 00419 { 00420 typedef typename K::Point_3 Point_3; 00421 const Point_3 &source = seg.source(); 00422 const Point_3 &target = seg.target(); 00423 00424 Oriented_side source_side = plane.oriented_side(source); 00425 Oriented_side target_side = plane.oriented_side(target); 00426 00427 switch (source_side) { 00428 case ON_ORIENTED_BOUNDARY: 00429 if (target_side == ON_ORIENTED_BOUNDARY) 00430 return make_object(seg); 00431 else 00432 return make_object(source); 00433 case ON_POSITIVE_SIDE: 00434 switch (target_side) { 00435 case ON_ORIENTED_BOUNDARY: 00436 return make_object(target); 00437 case ON_POSITIVE_SIDE: 00438 return Object(); 00439 case ON_NEGATIVE_SIDE: 00440 return intersection(plane, seg.supporting_line(), k); 00441 } 00442 case ON_NEGATIVE_SIDE: 00443 switch (target_side) { 00444 case ON_ORIENTED_BOUNDARY: 00445 return make_object(target); 00446 case ON_POSITIVE_SIDE: 00447 return intersection(plane, seg.supporting_line(), k); 00448 case ON_NEGATIVE_SIDE: 00449 return Object(); 00450 } 00451 } 00452 CGAL_kernel_assertion_msg(false, "Supposedly unreachable code."); 00453 return Object(); 00454 } 00455 00456 00457 template <class K> 00458 inline 00459 Object 00460 intersection(const typename K::Segment_3 &seg, 00461 const typename K::Plane_3 &plane, 00462 const K& k) 00463 { 00464 return intersection(plane, seg, k); 00465 } 00466 00467 00468 template <class K> 00469 bool 00470 do_intersect(const typename K::Plane_3 &plane, 00471 const typename K::Segment_3 &seg, 00472 const K&) 00473 { 00474 typedef typename K::Point_3 Point_3; 00475 const Point_3 &source = seg.source(); 00476 const Point_3 &target = seg.target(); 00477 00478 Oriented_side source_side = plane.oriented_side(source); 00479 Oriented_side target_side = plane.oriented_side(target); 00480 00481 if ( source_side == target_side 00482 && target_side != ON_ORIENTED_BOUNDARY) { 00483 return false; 00484 } 00485 return true; 00486 } 00487 00488 00489 template <class K> 00490 inline 00491 bool 00492 do_intersect(const typename K::Segment_3 &seg, 00493 const typename K::Plane_3 &plane, 00494 const K& k) 00495 { 00496 return do_intersect(plane, seg, k); 00497 } 00498 00499 00500 template <class K> 00501 Object 00502 intersection(const typename K::Line_3 &line, 00503 const Bbox_3 &box, 00504 const K&) 00505 { 00506 typedef typename K::Point_3 Point_3; 00507 typedef typename K::Direction_3 Direction_3; 00508 const Point_3 &linepoint = line.point(); 00509 const Direction_3 &linedir = line.direction(); 00510 return intersection_bl(box, 00511 CGAL::to_double(linepoint.x()), 00512 CGAL::to_double(linepoint.y()), 00513 CGAL::to_double(linepoint.z()), 00514 CGAL::to_double(linedir.dx()), 00515 CGAL::to_double(linedir.dy()), 00516 CGAL::to_double(linedir.dz()), 00517 true, true 00518 ); 00519 } 00520 00521 00522 template <class K> 00523 inline 00524 Object 00525 intersection(const Bbox_3 &box, 00526 const typename K::Line_3 &line, 00527 const K& k) 00528 { 00529 return intersection(line, box, k); 00530 } 00531 00532 00533 template <class K> 00534 Object 00535 intersection(const typename K::Ray_3 &ray, 00536 const Bbox_3 &box, 00537 const K&) 00538 { 00539 typedef typename K::Point_3 Point_3; 00540 typedef typename K::Direction_3 Direction_3; 00541 const Point_3 &linepoint = ray.source(); 00542 const Direction_3 &linedir = ray.direction(); 00543 return intersection_bl(box, 00544 CGAL::to_double(linepoint.x()), 00545 CGAL::to_double(linepoint.y()), 00546 CGAL::to_double(linepoint.z()), 00547 CGAL::to_double(linedir.dx()), 00548 CGAL::to_double(linedir.dy()), 00549 CGAL::to_double(linedir.dz()), 00550 false, true 00551 ); 00552 } 00553 00554 00555 template <class K> 00556 inline 00557 Object 00558 intersection(const Bbox_3 &box, 00559 const typename K::Ray_3 &ray, 00560 const K& k) 00561 { 00562 return intersection(ray, box, k); 00563 } 00564 00565 00566 00567 template <class K> 00568 Object 00569 intersection(const typename K::Segment_3 &seg, 00570 const Bbox_3 &box, 00571 const K&) 00572 { 00573 typedef typename K::Point_3 Point_3; 00574 typedef typename K::Vector_3 Vector_3; 00575 const Point_3 &linepoint = seg.source(); 00576 const Vector_3 &diffvec = seg.target()-linepoint; 00577 return intersection_bl(box, 00578 CGAL::to_double(linepoint.x()), 00579 CGAL::to_double(linepoint.y()), 00580 CGAL::to_double(linepoint.z()), 00581 CGAL::to_double(diffvec.x()), 00582 CGAL::to_double(diffvec.y()), 00583 CGAL::to_double(diffvec.z()), 00584 false, false 00585 ); 00586 } 00587 00588 00589 template <class K> 00590 inline 00591 Object 00592 intersection(const Bbox_3 &box, 00593 const typename K::Segment_3 &seg, 00594 const K& k) 00595 { 00596 return intersection(seg, box, k); 00597 } 00598 00599 00600 template <class K> 00601 Object 00602 intersection(const typename K::Line_3 &line, 00603 const typename K::Iso_cuboid_3 &box, 00604 const K&) 00605 { 00606 typedef typename K::Point_3 Point_3; 00607 typedef typename K::Vector_3 Vector_3; 00608 typedef typename K::Segment_3 Segment_3; 00609 typedef typename K::RT RT; 00610 typedef typename K::FT FT; 00611 bool all_values = true; 00612 FT _min = 0, _max = 0; // initialization to stop compiler warning 00613 Point_3 const & _ref_point=line.point(); 00614 Vector_3 const & _dir=line.direction().vector(); 00615 Point_3 const & _iso_min=(box.min)(); 00616 Point_3 const & _iso_max=(box.max)(); 00617 for (int i=0; i< _ref_point.dimension(); i++) { 00618 if (_dir.homogeneous(i) == 0) { 00619 if (_ref_point.cartesian(i) < _iso_min.cartesian(i)) { 00620 return Object(); 00621 } 00622 if (_ref_point.cartesian(i) > _iso_max.cartesian(i)) { 00623 return Object(); 00624 } 00625 } else { 00626 FT newmin, newmax; 00627 if (_dir.homogeneous(i) > 0) { 00628 newmin = (_iso_min.cartesian(i) - _ref_point.cartesian(i)) / 00629 _dir.cartesian(i); 00630 newmax = (_iso_max.cartesian(i) - _ref_point.cartesian(i)) / 00631 _dir.cartesian(i); 00632 } else { 00633 newmin = (_iso_max.cartesian(i) - _ref_point.cartesian(i)) / 00634 _dir.cartesian(i); 00635 newmax = (_iso_min.cartesian(i) - _ref_point.cartesian(i)) / 00636 _dir.cartesian(i); 00637 } 00638 if (all_values) { 00639 _min = newmin; 00640 _max = newmax; 00641 } else { 00642 if (newmin > _min) 00643 _min = newmin; 00644 if (newmax < _max) 00645 _max = newmax; 00646 if (_max < _min) { 00647 return Object(); 00648 } 00649 } 00650 all_values = false; 00651 } 00652 } 00653 CGAL_kernel_assertion(!all_values); 00654 if (_max == _min) { 00655 return make_object(Point_3(_ref_point + _dir * _min )); 00656 } 00657 return make_object( 00658 Segment_3(_ref_point + _dir*_min, _ref_point + _dir*_max)); 00659 } 00660 00661 00662 template <class K> 00663 inline 00664 Object 00665 intersection(const typename K::Iso_cuboid_3 &box, 00666 const typename K::Line_3 &line, 00667 const K& k) 00668 { 00669 return intersection(line, box, k); 00670 } 00671 00672 00673 00674 template <class K> 00675 Object 00676 intersection(const typename K::Ray_3 &ray, 00677 const typename K::Iso_cuboid_3 &box, 00678 const K&) 00679 { 00680 typedef typename K::Point_3 Point_3; 00681 typedef typename K::Vector_3 Vector_3; 00682 typedef typename K::Segment_3 Segment_3; 00683 typedef typename K::RT RT; 00684 typedef typename K::FT FT; 00685 bool all_values = true; 00686 FT _min = 0, _max = 0; // initialization to prevent compiler warning 00687 Point_3 const & _ref_point=ray.source(); 00688 Vector_3 const & _dir=ray.direction().vector(); 00689 Point_3 const & _iso_min=(box.min)(); 00690 Point_3 const & _iso_max=(box.max)(); 00691 00692 for (int i=0; i< _ref_point.dimension(); i++) { 00693 if (_dir.homogeneous(i) == 0) { 00694 if (_ref_point.cartesian(i) < _iso_min.cartesian(i)) { 00695 return Object(); 00696 } 00697 if (_ref_point.cartesian(i) > _iso_max.cartesian(i)) { 00698 return Object(); 00699 } 00700 } else { 00701 FT newmin, newmax; 00702 if (_dir.homogeneous(i) > 0) { 00703 newmin = (_iso_min.cartesian(i) - _ref_point.cartesian(i)) / 00704 _dir.cartesian(i); 00705 newmax = (_iso_max.cartesian(i) - _ref_point.cartesian(i)) / 00706 _dir.cartesian(i); 00707 } else { 00708 newmin = (_iso_max.cartesian(i) - _ref_point.cartesian(i)) / 00709 _dir.cartesian(i); 00710 newmax = (_iso_min.cartesian(i) - _ref_point.cartesian(i)) / 00711 _dir.cartesian(i); 00712 } 00713 if (all_values) { 00714 _max = newmax; 00715 } else { 00716 if (newmax < _max) 00717 _max = newmax; 00718 } 00719 if (newmin > _min) 00720 _min = newmin; 00721 if (_max < _min) 00722 return Object(); 00723 all_values = false; 00724 } 00725 } 00726 CGAL_kernel_assertion(!all_values); 00727 if (_max == _min) { 00728 return make_object(Point_3(_ref_point + _dir * _min )); 00729 } 00730 return make_object( 00731 Segment_3(_ref_point + _dir*_min, _ref_point + _dir*_max)); 00732 } 00733 00734 00735 template <class K> 00736 inline 00737 Object 00738 intersection(const typename K::Iso_cuboid_3 &box, 00739 const typename K::Ray_3 &ray, 00740 const K& k) 00741 { 00742 return intersection(ray, box, k); 00743 } 00744 00745 00746 template <class K> 00747 Object 00748 intersection(const typename K::Segment_3 &seg, 00749 const typename K::Iso_cuboid_3 &box, 00750 const K&) 00751 { 00752 typedef typename K::Point_3 Point_3; 00753 typedef typename K::Vector_3 Vector_3; 00754 typedef typename K::Segment_3 Segment_3; 00755 typedef typename K::RT RT; 00756 typedef typename K::FT FT; 00757 FT _min = 0, _max; 00758 00759 Point_3 const & _ref_point=seg.source(); 00760 Vector_3 const & _dir=seg.direction().vector(); 00761 Point_3 const & _iso_min=(box.min)(); 00762 Point_3 const & _iso_max=(box.max)(); 00763 int main_dir = 00764 (CGAL_NTS abs(_dir.x()) > CGAL_NTS abs(_dir.y()) ) 00765 ? (CGAL_NTS abs(_dir.x()) > CGAL_NTS abs(_dir.z()) ? 0 : 2) 00766 : (CGAL_NTS abs(_dir.y()) > CGAL_NTS abs(_dir.z()) ? 1 : 2); 00767 _max = (seg.target().cartesian(main_dir)-_ref_point.cartesian(main_dir)) / 00768 _dir.cartesian(main_dir); 00769 00770 for (int i=0; i< _ref_point.dimension(); i++) { 00771 if (_dir.homogeneous(i) == 0) { 00772 if (_ref_point.cartesian(i) < _iso_min.cartesian(i)) { 00773 return Object(); 00774 } 00775 if (_ref_point.cartesian(i) > _iso_max.cartesian(i)) { 00776 return Object(); 00777 } 00778 } else { 00779 FT newmin, newmax; 00780 if (_dir.homogeneous(i) > 0) { 00781 newmin = (_iso_min.cartesian(i) - _ref_point.cartesian(i)) / 00782 _dir.cartesian(i); 00783 newmax = (_iso_max.cartesian(i) - _ref_point.cartesian(i)) / 00784 _dir.cartesian(i); 00785 } else { 00786 newmin = (_iso_max.cartesian(i) - _ref_point.cartesian(i)) / 00787 _dir.cartesian(i); 00788 newmax = (_iso_min.cartesian(i) - _ref_point.cartesian(i)) / 00789 _dir.cartesian(i); 00790 } 00791 if (newmax < _max) 00792 _max = newmax; 00793 if (newmin > _min) 00794 _min = newmin; 00795 if (_max < _min) 00796 return Object(); 00797 } 00798 } 00799 if (_max == _min) { 00800 return make_object(Point_3(_ref_point + _dir * _min )); 00801 } 00802 return make_object( 00803 Segment_3(_ref_point + _dir*_min, _ref_point + _dir*_max)); 00804 } 00805 00806 00807 template <class K> 00808 inline 00809 Object 00810 intersection(const typename K::Iso_cuboid_3 &box, 00811 const typename K::Segment_3 &seg, 00812 const K& k) 00813 { 00814 return intersection(seg, box, k); 00815 } 00816 00817 00818 template <class K> 00819 Object 00820 intersection( 00821 const typename K::Iso_cuboid_3 &icub1, 00822 const typename K::Iso_cuboid_3 &icub2, 00823 const K&) 00824 { 00825 typedef typename K::Point_3 Point_3; 00826 typedef typename K::Iso_cuboid_3 Iso_cuboid_3; 00827 00828 Point_3 min_points[2]; 00829 Point_3 max_points[2]; 00830 min_points[0] = (icub1.min)(); 00831 min_points[1] = (icub2.min)(); 00832 max_points[0] = (icub1.max)(); 00833 max_points[1] = (icub2.max)(); 00834 typedef typename K::FT FT; 00835 const int DIM = 3; 00836 int min_idx[DIM]; 00837 int max_idx[DIM]; 00838 Point_3 newmin; 00839 Point_3 newmax; 00840 for (int dim = 0; dim < DIM; ++dim) { 00841 min_idx[dim] = 00842 min_points[0].cartesian(dim) >= min_points[1].cartesian(dim) ? 0 : 1; 00843 max_idx[dim] = 00844 max_points[0].cartesian(dim) <= max_points[1].cartesian(dim) ? 0 : 1; 00845 if (min_idx[dim] != max_idx[dim] 00846 && max_points[max_idx[dim]].cartesian(dim) 00847 < min_points[min_idx[dim]].cartesian(dim)) 00848 return Object(); 00849 } 00850 if (min_idx[0] == min_idx[1] && min_idx[0] == min_idx[2]) { 00851 newmin = min_points[min_idx[0]]; 00852 } else { 00853 newmin = Point_3( 00854 min_idx[0] == 0 00855 ? wmult_hw((K*)0, min_points[0].hx(), min_points[1]) 00856 : wmult_hw((K*)0, min_points[1].hx(), min_points[0]) 00857 , 00858 min_idx[1] == 0 00859 ? wmult_hw((K*)0, min_points[0].hy(), min_points[1]) 00860 : wmult_hw((K*)0, min_points[1].hy(), min_points[0]) 00861 , 00862 min_idx[2] == 0 00863 ? wmult_hw((K*)0, min_points[0].hz(), min_points[1]) 00864 : wmult_hw((K*)0, min_points[1].hz(), min_points[0]) 00865 , 00866 wmult_hw((K*)0, min_points[0].hw(), min_points[1]) ); 00867 } 00868 if (max_idx[0] == max_idx[1] && max_idx[0] == max_idx[2]) { 00869 newmax = max_points[max_idx[0]]; 00870 } else { 00871 newmax = Point_3( 00872 max_idx[0] == 0 00873 ? wmult_hw((K*)0, max_points[0].hx(), max_points[1]) 00874 : wmult_hw((K*)0, max_points[1].hx(), max_points[0]) 00875 , 00876 max_idx[1] == 0 00877 ? wmult_hw((K*)0, max_points[0].hy(), max_points[1]) 00878 : wmult_hw((K*)0, max_points[1].hy(), max_points[0]) 00879 , 00880 max_idx[2] == 0 00881 ? wmult_hw((K*)0, max_points[0].hz(), max_points[1]) 00882 : wmult_hw((K*)0, max_points[1].hz(), max_points[0]) 00883 , 00884 wmult_hw((K*)0, max_points[0].hw(), max_points[1]) ); 00885 } 00886 Object result = make_object(Iso_cuboid_3(newmin, newmax)); 00887 return result; 00888 } 00889 00890 00891 } // namespace CGALi 00892 00893 00894 00895 00896 00897 00898 template <class K> 00899 inline 00900 Object 00901 intersection(const Plane_3<K> &plane1, const Plane_3<K> &plane2) 00902 { 00903 return typename K::Intersect_3()(plane1, plane2); 00904 } 00905 00906 template <class K> 00907 inline 00908 Object 00909 intersection(const Plane_3<K> &plane1, const Plane_3<K> &plane2, 00910 const Plane_3<K> &plane3) 00911 { 00912 return typename K::Intersect_3()(plane1, plane2, plane3); 00913 } 00914 00915 00916 template <class K> 00917 inline 00918 Object 00919 intersection(const Plane_3<K> &plane, const Line_3<K> &line) 00920 { 00921 return typename K::Intersect_3()(plane, line); 00922 } 00923 00924 template <class K> 00925 inline 00926 bool 00927 do_intersect(const Plane_3<K> &plane, const Line_3<K> &line) 00928 { 00929 return typename K::Do_intersect_3()(plane, line); 00930 } 00931 00932 template <class K> 00933 inline 00934 Object 00935 intersection(const Plane_3<K> &plane, const Ray_3<K> &ray) 00936 { 00937 return typename K::Intersect_3()(plane, ray); 00938 } 00939 00940 template <class K> 00941 inline 00942 bool 00943 do_intersect(const Plane_3<K> &plane, const Ray_3<K> &ray) 00944 { 00945 return typename K::Do_intersect_3()(plane, ray); 00946 } 00947 00948 template <class K> 00949 inline 00950 Object 00951 intersection(const Plane_3<K> &plane, const Segment_3<K> &seg) 00952 { 00953 return typename K::Intersect_3()(plane, seg); 00954 } 00955 00956 00957 template <class K> 00958 inline 00959 bool 00960 do_intersect(const Plane_3<K> &plane, const Segment_3<K> &seg) 00961 { 00962 return typename K::Do_intersect_3()(plane, seg); 00963 } 00964 00965 template <class K> 00966 inline 00967 Object 00968 intersection(const Line_3<K> &line, 00969 const Bbox_3 &box) 00970 { 00971 return typename K::Intersect_3()(line, box); 00972 } 00973 00974 template <class K> 00975 inline 00976 Object 00977 intersection(const Ray_3<K> &ray, 00978 const Bbox_3 &box) 00979 { 00980 return typename K::Intersect_3()(ray, box); 00981 } 00982 00983 template <class K> 00984 inline 00985 Object 00986 intersection(const Segment_3<K> &seg, 00987 const Bbox_3 &box) 00988 { 00989 return typename K::Intersect_3()(seg, box); 00990 } 00991 00992 template <class K> 00993 inline 00994 Object 00995 intersection(const Line_3<K> &line, 00996 const Iso_cuboid_3<K> &box) 00997 { 00998 return typename K::Intersect_3()(line, box); 00999 } 01000 01001 template <class K> 01002 inline 01003 Object 01004 intersection(const Ray_3<K> &ray, 01005 const Iso_cuboid_3<K> &box) 01006 { 01007 return typename K::Intersect_3()(ray, box); 01008 } 01009 01010 template <class K> 01011 inline 01012 Object 01013 intersection(const Segment_3<K> &seg, 01014 const Iso_cuboid_3<K> &box) 01015 { 01016 return typename K::Intersect_3()(seg, box); 01017 } 01018 01019 01020 template <class K> 01021 inline 01022 Object 01023 intersection(const Iso_cuboid_3<K> &icub1, 01024 const Iso_cuboid_3<K> &icub2) 01025 { 01026 return typename K::Intersect_3()(icub1, icub2); 01027 } 01028 01029 template <class K> 01030 inline 01031 Object 01032 intersection(const Line_3<K> &l1, 01033 const Line_3<K> &l2) { 01034 return typename K::Intersect_3()(l1, l2); 01035 } 01036 01037 template <class K> 01038 inline 01039 bool 01040 do_intersect(const Line_3<K> &l1, 01041 const Line_3<K> &l2) 01042 { 01043 return typename K::Do_intersect_3()(l1, l2); 01044 } 01045 01046 template <class K> 01047 inline 01048 Object 01049 intersection(const Sphere_3<K> &s1, 01050 const Sphere_3<K> &s2) { 01051 return typename K::Intersect_3()(s1, s2); 01052 } 01053 01054 template <class K> 01055 inline 01056 bool 01057 do_intersect(const Sphere_3<K> &s1, 01058 const Sphere_3<K> &s2) 01059 { 01060 return typename K::Do_intersect_3()(s1, s2); 01061 } 01062 01063 template <class K> 01064 inline 01065 Object 01066 intersection(const Plane_3<K> &p, 01067 const Sphere_3<K> &s) { 01068 return typename K::Intersect_3()(p, s); 01069 } 01070 01071 template <class K> 01072 inline 01073 bool 01074 do_intersect(const Plane_3<K> &p, 01075 const Sphere_3<K> &s) 01076 { 01077 return typename K::Do_intersect_3()(p, s); 01078 } 01079 01080 CGAL_END_NAMESPACE