BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Intersections_3/intersection_3_1_impl.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines