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