| BWAPI
   
    | 
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
 1.7.6.1
 1.7.6.1