BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Circular_kernel_2/internal_functions_on_circle_2.h
Go to the documentation of this file.
00001 // Copyright (c) 2003-2008  INRIA Sophia-Antipolis (France).
00002 // All rights reserved.
00003 //
00004 // This file is part of CGAL (www.cgal.org); you may redistribute it under
00005 // the terms of the Q Public License version 1.0.
00006 // See the file LICENSE.QPL distributed with CGAL.
00007 //
00008 // Licensees holding a valid commercial license may use this file in
00009 // accordance with the commercial license agreement provided with the software.
00010 //
00011 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00012 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00013 //
00014 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Circular_kernel_2/include/CGAL/Circular_kernel_2/internal_functions_on_circle_2.h $
00015 // $Id: internal_functions_on_circle_2.h 46419 2008-10-22 13:32:25Z pmachado $
00016 //
00017 // Author(s)     : Monique Teillaud, Sylvain Pion, Pedro Machado
00018 
00019 // Partially supported by the IST Programme of the EU as a Shared-cost
00020 // RTD (FET Open) Project under Contract No  IST-2000-26473 
00021 // (ECG - Effective Computational Geometry for Curves and Surfaces) 
00022 // and a STREP (FET Open) Project under Contract No  IST-006413 
00023 // (ACS -- Algorithms for Complex Shapes)
00024 
00025 #ifndef CGAL_CIRCULAR_KERNEL_INTERNAL_FUNCTIONS_ON_CIRCLE_2_H
00026 #define CGAL_CIRCULAR_KERNEL_INTERNAL_FUNCTIONS_ON_CIRCLE_2_H
00027 
00028 CGAL_BEGIN_NAMESPACE
00029 
00030 // temporary function : where to put it, if we want to keep it ?
00031 template< class CK>
00032 typename CK::Circular_arc_point_2
00033 circle_intersect( const typename CK::Circle_2 & c1,
00034                   const typename CK::Circle_2 & c2,
00035                   bool b )
00036 {
00037   typedef std::vector<CGAL::Object > solutions_container;
00038   solutions_container solutions;
00039   
00040   intersection( c1, c2, std::back_inserter(solutions) );
00041   
00042   typename solutions_container::iterator it = solutions.begin();
00043   
00044   CGAL_kernel_precondition( it != solutions.end() ); 
00045   // the circles intersect
00046   
00047   const std::pair<typename CK::Circular_arc_point_2, unsigned> *result;
00048   result = CGAL::object_cast< 
00049     std::pair<typename CK::Circular_arc_point_2, unsigned> > (&(*it));
00050   
00051   if ( result->second == 2 ) // double solution
00052     return result->first;
00053   
00054   if (b) 
00055     return result->first;
00056   
00057   ++it;
00058   result = CGAL::object_cast< 
00059     std::pair<typename CK::Circular_arc_point_2, unsigned> >(&(*it));
00060   
00061   return result->first;
00062 }
00063 
00064 namespace CircularFunctors {
00065   
00066   template < class CK >
00067   typename CK::Polynomial_for_circles_2_2
00068   get_equation( const typename CK::Circle_2 & c )
00069   {
00070     typedef typename CK::RT RT;
00071  
00072     typedef typename CK::Algebraic_kernel   AK;
00073     
00074     return AK().construct_polynomial_for_circles_2_2_object()
00075       ( c.center().x(), c.center().y(), c.squared_radius() );
00076   }
00077   
00078   template < class CK >
00079   typename CK::Circle_2  
00080   construct_circle_2( const typename CK::Polynomial_for_circles_2_2 &eq )
00081   {
00082     return typename 
00083       CK::Circle_2( typename CK::Point_2(eq.a(), eq.b()), eq.r_sq() ); 
00084   }
00085 
00086   template < class CK >
00087   bool
00088   has_on(const typename CK::Circle_2 &a,
00089          const typename CK::Circular_arc_point_2 &p)
00090   {
00091     typedef typename CK::Algebraic_kernel            AK;
00092     typedef typename CK::Polynomial_for_circles_2_2 Polynomial_for_circles_2_2;
00093     Polynomial_for_circles_2_2 equation = CircularFunctors::get_equation<CK>(a);
00094     
00095     return (AK().sign_at_object()(equation,p.coordinates()) == ZERO);
00096   }
00097 
00098   template < class CK >
00099   inline bool
00100   non_oriented_equal(const typename CK::Circle_2 & c1,
00101                      const typename CK::Circle_2 & c2) {
00102     if(identical(c1,c2)) return true;
00103     return (c1.squared_radius() == c2.squared_radius()) &&
00104            (c1.center() == c2.center());
00105   }
00106 
00107   template < class CK >
00108   inline
00109   typename CK::Linear_kernel::Bounded_side
00110   bounded_side(const typename CK::Circle_2 &c,
00111                const typename CK::Circular_arc_point_2 &p) {
00112    typedef typename CK::Algebraic_kernel AK;
00113     typedef typename CK::Polynomial_for_circles_2_2 Equation;
00114     Equation equation = get_equation<CK>(c);
00115     Sign sign = AK().sign_at_object()(equation,p.coordinates());
00116     if(sign == NEGATIVE) return ON_BOUNDED_SIDE;
00117     else if(sign == POSITIVE) return ON_UNBOUNDED_SIDE;
00118     else return ON_BOUNDARY;
00119   }
00120 
00121   template< class CK, class OutputIterator>
00122   OutputIterator
00123   intersect_2( const typename CK::Circle_2 & c1,
00124                const typename CK::Circle_2 & c2,
00125                OutputIterator res )
00126   {
00127     typedef typename CK::Algebraic_kernel            AK;
00128     typedef typename CK::Polynomial_for_circles_2_2  Equation; 
00129     typedef typename CK::Root_for_circles_2_2        Root_for_circles_2_2;
00130     Equation e1 = CircularFunctors::get_equation<CK>(c1);
00131     Equation e2 = CircularFunctors::get_equation<CK>(c2);
00132     
00133     if (e1 == e2) {
00134       *res++ = make_object(e1);
00135       return res;
00136     }
00137 
00138     typedef std::vector< std::pair < Root_for_circles_2_2, unsigned > > 
00139       solutions_container;
00140     solutions_container solutions;
00141     
00142     AK().solve_object()(e1, e2, std::back_inserter(solutions)); 
00143     // to be optimized
00144 
00145     typedef typename CK::Circular_arc_point_2 Circular_arc_point_2;
00146     
00147     for ( typename solutions_container::iterator it = solutions.begin(); 
00148           it != solutions.end(); ++it )
00149       {
00150         *res++ = make_object(std::make_pair(Circular_arc_point_2(it->first),
00151                                             it->second ));
00152       }
00153 
00154     return res;
00155   }
00156 
00157   // Should we have an iterator based interface, or both ?
00158   template <class CK>
00159   typename CK::Circular_arc_point_2
00160   x_extremal_point(const typename CK::Circle_2 & c, bool i)
00161   {
00162     typedef typename CK::Algebraic_kernel   AK;
00163     return AK().x_critical_points_object()(typename CK::Get_equation()(c),i);
00164   }
00165 
00166   template <class CK,class OutputIterator>
00167   OutputIterator
00168   x_extremal_points(const typename CK::Circle_2 & c, OutputIterator res)
00169   {
00170     typedef typename CK::Algebraic_kernel   AK;
00171     return AK().x_critical_points_object()(typename CK::Get_equation()(c),res);
00172   }
00173 
00174   template <class CK>
00175   typename CK::Circular_arc_point_2
00176   y_extremal_point(const typename CK::Circle_2 & c, bool i)
00177   {
00178     typedef typename CK::Algebraic_kernel   AK;
00179     return AK().y_critical_points_object()(typename CK::Get_equation()(c),i);
00180   }
00181   
00182   template <class CK,class OutputIterator>
00183   OutputIterator
00184   y_extremal_points(const typename CK::Circle_2 & c, OutputIterator res)
00185   {
00186     typedef typename CK::Algebraic_kernel   AK;
00187     return AK().y_critical_points_object()(typename CK::Get_equation()(c),res);
00188   }
00189 
00190 } // namespace CircularFunctors
00191 
00192 CGAL_END_NAMESPACE
00193 
00194 #endif // CGAL_CIRCULAR_KERNEL_INTERNAL_FUNCTIONS_ON_CIRCLE_2_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines