| 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/Orientation_3.h $ 00016 // $Id: Orientation_3.h 47568 2008-12-21 15:56:20Z spion $ 00017 // 00018 // 00019 // Author(s) : Sylvain Pion 00020 00021 #ifndef CGAL_STATIC_FILTERS_ORIENTATION_3_H 00022 #define CGAL_STATIC_FILTERS_ORIENTATION_3_H 00023 00024 #include <CGAL/Profile_counter.h> 00025 #include <CGAL/Static_filter_error.h> 00026 #include <cmath> 00027 00028 CGAL_BEGIN_NAMESPACE 00029 00030 template < typename K_base > 00031 class SF_Orientation_3 00032 : public K_base::Orientation_3 00033 { 00034 typedef typename K_base::Point_3 Point_3; 00035 typedef typename K_base::Vector_3 Vector_3; 00036 typedef typename K_base::Sphere_3 Sphere_3; 00037 typedef typename K_base::Orientation_3 Base; 00038 00039 public: 00040 typedef typename Base::result_type result_type; 00041 00042 #ifndef CGAL_CFG_MATCHING_BUG_6 00043 using Base::operator(); 00044 #else 00045 result_type 00046 operator()(const Vector_3& u, const Vector_3& v, const Vector_3& w) const 00047 { 00048 return Base::operator()(u,v,w); 00049 } 00050 00051 result_type 00052 operator()(const Sphere_3& s) const 00053 { 00054 return Base::operator()(s); 00055 } 00056 #endif 00057 00058 result_type 00059 operator()(const Point_3 &p, const Point_3 &q, 00060 const Point_3 &r, const Point_3 &s) const 00061 { 00062 CGAL_BRANCH_PROFILER_3("semi-static failures/attempts/calls to : Orientation_3", tmp); 00063 00064 using std::fabs; 00065 00066 double px, py, pz, qx, qy, qz, rx, ry, rz, sx, sy, sz; 00067 00068 if (fit_in_double(p.x(), px) && fit_in_double(p.y(), py) && 00069 fit_in_double(p.z(), pz) && 00070 fit_in_double(q.x(), qx) && fit_in_double(q.y(), qy) && 00071 fit_in_double(q.z(), qz) && 00072 fit_in_double(r.x(), rx) && fit_in_double(r.y(), ry) && 00073 fit_in_double(r.z(), rz) && 00074 fit_in_double(s.x(), sx) && fit_in_double(s.y(), sy) && 00075 fit_in_double(s.z(), sz)) 00076 { 00077 CGAL_BRANCH_PROFILER_BRANCH_1(tmp); 00078 00079 double pqx = qx - px; 00080 double pqy = qy - py; 00081 double pqz = qz - pz; 00082 double prx = rx - px; 00083 double pry = ry - py; 00084 double prz = rz - pz; 00085 double psx = sx - px; 00086 double psy = sy - py; 00087 double psz = sz - pz; 00088 00089 // Then semi-static filter. 00090 double maxx = fabs(pqx); 00091 if (maxx < fabs(prx)) maxx = fabs(prx); 00092 if (maxx < fabs(psx)) maxx = fabs(psx); 00093 double maxy = fabs(pqy); 00094 if (maxy < fabs(pry)) maxy = fabs(pry); 00095 if (maxy < fabs(psy)) maxy = fabs(psy); 00096 double maxz = fabs(pqz); 00097 if (maxz < fabs(prz)) maxz = fabs(prz); 00098 if (maxz < fabs(psz)) maxz = fabs(psz); 00099 double det = determinant(pqx, pqy, pqz, 00100 prx, pry, prz, 00101 psx, psy, psz); 00102 00103 // Sort maxx < maxy < maxz. 00104 if (maxx > maxz) 00105 std::swap(maxx, maxz); 00106 if (maxy > maxz) 00107 std::swap(maxy, maxz); 00108 else if (maxy < maxx) 00109 std::swap(maxx, maxy); 00110 00111 // Protect against underflow in the computation of eps. 00112 if (maxx < 1e-97) /* cbrt(min_double/eps) */ { 00113 if (maxx == 0) 00114 return ZERO; 00115 } 00116 // Protect against overflow in the computation of det. 00117 else if (maxz < 1e102) /* cbrt(max_double [hadamard]/4) */ { 00118 double eps = 5.1107127829973299e-15 * maxx * maxy * maxz; 00119 if (det > eps) return POSITIVE; 00120 if (det < -eps) return NEGATIVE; 00121 } 00122 00123 CGAL_BRANCH_PROFILER_BRANCH_2(tmp); 00124 } 00125 00126 return Base::operator()(p, q, r, s); 00127 } 00128 00129 // Computes the epsilon for Orientation_3. 00130 static double compute_epsilon() 00131 { 00132 typedef Static_filter_error F; 00133 F t1 = F(1, F::ulp()/2); // First translation 00134 F det = determinant(t1, t1, t1, 00135 t1, t1, t1, 00136 t1, t1, t1); // Full det 00137 double err = det.error(); 00138 err += err * 2 * F::ulp(); // Correction due to "eps * maxx * maxy...". 00139 std::cerr << "*** epsilon for Orientation_3 = " << err << std::endl; 00140 return err; 00141 } 00142 00143 }; 00144 00145 CGAL_END_NAMESPACE 00146 00147 #endif // CGAL_STATIC_FILTERS_ORIENTATION_3_H
 1.7.6.1
 1.7.6.1