BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Static_filters/Side_of_oriented_sphere_3.h
Go to the documentation of this file.
00001 // Copyright (c) 2001,2004  INRIA Sophia-Antipolis (France).
00002 // All rights reserved.
00003 //
00004 // This file is part of CGAL (www.cgal.org); you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public License as
00006 // published by the Free Software Foundation; version 2.1 of the License.
00007 // See the file LICENSE.LGPL distributed with CGAL.
00008 //
00009 // Licensees holding a valid commercial license may use this file in
00010 // accordance with the commercial license agreement provided with the software.
00011 //
00012 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00013 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00014 //
00015 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Filtered_kernel/include/CGAL/Static_filters/Side_of_oriented_sphere_3.h $
00016 // $Id: Side_of_oriented_sphere_3.h 47568 2008-12-21 15:56:20Z spion $
00017 // 
00018 //
00019 // Author(s)     : Sylvain Pion
00020 
00021 #ifndef CGAL_STATIC_FILTERS_SIDE_OF_ORIENTED_SPHERE_3_H
00022 #define CGAL_STATIC_FILTERS_SIDE_OF_ORIENTED_SPHERE_3_H
00023 
00024 #include <CGAL/Profile_counter.h>
00025 #include <CGAL/Static_filter_error.h>
00026 
00027 CGAL_BEGIN_NAMESPACE
00028 
00029 template < typename K_base >
00030 class SF_Side_of_oriented_sphere_3
00031   : public K_base::Side_of_oriented_sphere_3
00032 {
00033   typedef typename K_base::Point_3                      Point_3;
00034   typedef typename K_base::Side_of_oriented_sphere_3    Base;
00035 
00036 public:
00037 
00038   Oriented_side
00039   operator()(const Point_3 &p, const Point_3 &q, const Point_3 &r,
00040              const Point_3 &s, const Point_3 &t) const
00041   {
00042       CGAL_BRANCH_PROFILER_3("semi-static failures/attempts/calls to   : Side_of_oriented_sphere_3", tmp);
00043 
00044       using std::fabs;
00045 
00046       double px, py, pz, qx, qy, qz, rx, ry, rz, sx, sy, sz, tx, ty, tz;
00047 
00048       if (fit_in_double(p.x(), px) && fit_in_double(p.y(), py) &&
00049           fit_in_double(p.z(), pz) &&
00050           fit_in_double(q.x(), qx) && fit_in_double(q.y(), qy) &&
00051           fit_in_double(q.z(), qz) &&
00052           fit_in_double(r.x(), rx) && fit_in_double(r.y(), ry) &&
00053           fit_in_double(r.z(), rz) &&
00054           fit_in_double(s.x(), sx) && fit_in_double(s.y(), sy) &&
00055           fit_in_double(s.z(), sz) &&
00056           fit_in_double(t.x(), tx) && fit_in_double(t.y(), ty) &&
00057           fit_in_double(t.z(), tz))
00058       {
00059           CGAL_BRANCH_PROFILER_BRANCH_1(tmp);
00060 
00061           double ptx = px - tx;
00062           double pty = py - ty;
00063           double ptz = pz - tz;
00064           double pt2 = CGAL_NTS square(ptx) + CGAL_NTS square(pty)
00065                      + CGAL_NTS square(ptz);
00066           double qtx = qx - tx;
00067           double qty = qy - ty;
00068           double qtz = qz - tz;
00069           double qt2 = CGAL_NTS square(qtx) + CGAL_NTS square(qty)
00070                      + CGAL_NTS square(qtz);
00071           double rtx = rx - tx;
00072           double rty = ry - ty;
00073           double rtz = rz - tz;
00074           double rt2 = CGAL_NTS square(rtx) + CGAL_NTS square(rty)
00075                      + CGAL_NTS square(rtz);
00076           double stx = sx - tx;
00077           double sty = sy - ty;
00078           double stz = sz - tz;
00079           double st2 = CGAL_NTS square(stx) + CGAL_NTS square(sty)
00080                      + CGAL_NTS square(stz);
00081 
00082           // Compute the semi-static bound.
00083           double maxx = fabs(ptx);
00084           if (maxx < fabs(qtx)) maxx = fabs(qtx);
00085           if (maxx < fabs(rtx)) maxx = fabs(rtx);
00086           if (maxx < fabs(stx)) maxx = fabs(stx);
00087           double maxy = fabs(pty);
00088           if (maxy < fabs(qty)) maxy = fabs(qty);
00089           if (maxy < fabs(rty)) maxy = fabs(rty);
00090           if (maxy < fabs(sty)) maxy = fabs(sty);
00091           double maxz = fabs(ptz);
00092           if (maxz < fabs(qtz)) maxz = fabs(qtz);
00093           if (maxz < fabs(rtz)) maxz = fabs(rtz);
00094           if (maxz < fabs(stz)) maxz = fabs(stz);
00095 
00096           // Sort maxx < maxy < maxz.
00097           if (maxx > maxz)
00098               std::swap(maxx, maxz);
00099           if (maxy > maxz)
00100               std::swap(maxy, maxz);
00101           else if (maxy < maxx)
00102               std::swap(maxx, maxy);
00103 
00104           double det = determinant(ptx,pty,ptz,pt2,
00105                                    rtx,rty,rtz,rt2,
00106                                    qtx,qty,qtz,qt2,
00107                                    stx,sty,stz,st2);
00108 
00109           // Protect against underflow in the computation of eps.
00110           if (maxx < 1e-58) /* sqrt^5(min_double/eps) */ {
00111             if (maxx == 0)
00112               return ON_ORIENTED_BOUNDARY;
00113           }
00114           // Protect against overflow in the computation of det.
00115           else if (maxz < 1e61) /* sqrt^5(max_double/4 [hadamard]) */ {
00116             double eps = 1.2466136531027298e-13 * maxx * maxy * maxz
00117                        * (maxz * maxz);
00118             if (det > eps)  return ON_POSITIVE_SIDE;
00119             if (det < -eps) return ON_NEGATIVE_SIDE;
00120           }
00121 
00122           CGAL_BRANCH_PROFILER_BRANCH_2(tmp);
00123       }
00124       return Base::operator()(p, q, r, s, t);
00125   }
00126 
00127   // Computes the epsilon for Side_of_oriented_sphere_3.
00128   static double compute_epsilon()
00129   {
00130     typedef CGAL::Static_filter_error F;
00131     F t1 = F(1,F::ulp()/2);         // First translation
00132     F sq = t1*t1+t1*t1+t1*t1; // squares
00133     F det = determinant(t1, t1, t1, sq,
00134                               t1, t1, t1, sq,
00135                               t1, t1, t1, sq,
00136                               t1, t1, t1, sq); // Full det
00137     double err = det.error();
00138     err += err * 3 * F::ulp(); // Correction due to "eps * maxx * ...".
00139 
00140     std::cerr << "*** epsilon for Side_of_oriented_sphere_3 = " << err << std::endl;
00141     return err;
00142   }
00143 };
00144 
00145 CGAL_END_NAMESPACE
00146 
00147 #endif // CGAL_STATIC_FILTERS_SIDE_OF_ORIENTED_SPHERE_3_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines