BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Static_filters/Side_of_oriented_circle_2.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_circle_2.h $
00016 // $Id: Side_of_oriented_circle_2.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_CIRCLE_2_H
00022 #define CGAL_STATIC_FILTERS_SIDE_OF_ORIENTED_CIRCLE_2_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_Side_of_oriented_circle_2
00032   : public K_base::Side_of_oriented_circle_2
00033 {
00034   typedef typename K_base::Point_2                      Point_2;
00035   typedef typename K_base::Side_of_oriented_circle_2    Base;
00036 
00037 public:
00038 
00039   Oriented_side operator()(const Point_2 &p, const Point_2 &q,
00040                            const Point_2 &r, const Point_2 &t) const
00041   {
00042       CGAL_BRANCH_PROFILER_3("semi-static failures/attempts/calls to   : Side_of_oriented_circle_2", tmp);
00043 
00044       using std::fabs;
00045 
00046       double px, py, qx, qy, rx, ry, tx, ty;
00047 
00048       if (fit_in_double(p.x(), px) && fit_in_double(p.y(), py) &&
00049           fit_in_double(q.x(), qx) && fit_in_double(q.y(), qy) &&
00050           fit_in_double(r.x(), rx) && fit_in_double(r.y(), ry) &&
00051           fit_in_double(t.x(), tx) && fit_in_double(t.y(), ty))
00052       {
00053           CGAL_BRANCH_PROFILER_BRANCH_1(tmp);
00054 
00055           double qpx = qx-px;
00056           double qpy = qy-py;
00057           double rpx = rx-px;
00058           double rpy = ry-py;
00059           double tpx = tx-px;
00060           double tpy = ty-py;
00061 
00062           double tqx = tx-qx;
00063           double tqy = ty-qy;
00064           double rqx = rx-qx;
00065           double rqy = ry-qy;
00066 
00067           double det = determinant(qpx*tpy - qpy*tpx, tpx*tqx + tpy*tqy,
00068                                    qpx*rpy - qpy*rpx, rpx*rqx + rpy*rqy);
00069 
00070           // We compute the semi-static bound.
00071           double maxx = fabs(qpx);
00072           if (maxx < fabs(rpx)) maxx = fabs(rpx);
00073           if (maxx < fabs(tpx)) maxx = fabs(tpx);
00074           if (maxx < fabs(tqx)) maxx = fabs(tqx);
00075           if (maxx < fabs(rqx)) maxx = fabs(rqx);
00076           double maxy = fabs(qpy);
00077           if (maxy < fabs(rpy)) maxy = fabs(rpy);
00078           if (maxy < fabs(tpy)) maxy = fabs(tpy);
00079           if (maxy < fabs(tqy)) maxy = fabs(tqy);
00080           if (maxy < fabs(rqy)) maxy = fabs(rqy);
00081 
00082           if (maxx > maxy)  std::swap(maxx, maxy);
00083 
00084           // Protect against underflow in the computation of eps.
00085           if (maxx < 1e-73) {
00086             if (maxx == 0)
00087               return ON_ORIENTED_BOUNDARY;
00088           }
00089           else if (maxy < 1e76) /* sqrt(sqrt(max_double/16 [hadamard])) */ {
00090             double eps = 8.8878565762001373e-15 * maxx * maxy * (maxy*maxy);
00091             if (det > eps)  return ON_POSITIVE_SIDE;
00092             if (det < -eps) return ON_NEGATIVE_SIDE;
00093           }
00094 
00095           CGAL_BRANCH_PROFILER_BRANCH_2(tmp);
00096       }
00097 
00098       return Base::operator()(p, q, r, t);
00099   }
00100 
00101   // Computes the epsilon for Side_of_oriented_circle_2.
00102   static double compute_epsilon()
00103   {
00104     typedef CGAL::Static_filter_error F;
00105     F t1 = F(1, F::ulp()/2);         // First translation
00106     F a = t1*t1 - t1*t1;
00107     F b = t1*t1 + t1*t1;
00108     F det = determinant(a, b, a, b);
00109     double err = det.error();
00110     err += err * 3 * F::ulp(); // Correction due to "eps * maxx * maxy...".
00111 
00112     std::cerr << "*** epsilon for Side_of_oriented_circle_2 = " << err << std::endl;
00113     return err;
00114   }
00115 };
00116 
00117 CGAL_END_NAMESPACE
00118 
00119 #endif // CGAL_STATIC_FILTERS_SIDE_OF_ORIENTED_CIRCLE_2_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines