BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Circular_kernel_3/internal_function_compare_to_right_spherical_kernel.h
Go to the documentation of this file.
00001 // Copyright (c) 2005-2009  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 // Partially supported by the IST Programme of the EU as a Shared-cost
00015 // RTD (FET Open) Project under Contract No  IST-2000-26473 
00016 // (ECG - Effective Computational Geometry for Curves and Surfaces) 
00017 // and a STREP (FET Open) Project under Contract No  IST-006413 
00018 // (ACS -- Algorithms for Complex Shapes)
00019 //
00020 // $URL:  $
00021 // $Id: internal_function_compare_to_right_spherical_kernel.h 40627 2007-10-16 15:00:59Z sloriot $
00022 //
00023 // Author(s) : Sebastien Loriot
00024 
00025 
00026 #ifndef CGAL_SPHERICAL_KERNEL_PREDICATES_COMPARE_TO_RIGHT_H
00027 #define CGAL_SPHERICAL_KERNEL_PREDICATES_COMPARE_TO_RIGHT_H
00028 
00029 namespace CGAL {
00030   namespace SphericalFunctors {
00031 
00032 //Traits providing primitives to compare two theta-monotone circular arc to the right of a common point Pt
00033 template <class SK>
00034 struct Trait_for_cmp_tgt{
00035   typename SK::Algebraic_kernel::Root_for_spheres_2_3 Pt_;
00036   typedef typename SK::Algebraic_kernel::Root_of_2 Tk_type;
00037   
00038   Trait_for_cmp_tgt(const typename SK::Algebraic_kernel::Root_for_spheres_2_3& Pt,
00039                     const typename SK::Sphere_3& sphere)
00040                   :Pt_(Pt.x()-sphere.center().x(),Pt.y()-sphere.center().y(),Pt.z()-sphere.center().z()){}
00041 
00042   typename SK::Algebraic_kernel::Root_of_2 
00043   unsigned_tkz_coeff_normal(const typename SK::Point_3& C,
00044                             const typename SK::FT& rk,
00045                             const typename SK::FT& R,
00046                             const typename SK::FT& gamma_k
00047                           ) const
00048   {
00049     return CGAL_NTS sign(gamma_k)*(C.x()*Pt_.y()-C.y()*Pt_.x());
00050   }
00051 
00052   Tk_type 
00053   unsigned_tkz_coeff_threaded(const typename SK::Point_3& C) const {
00054     return C.x()*Pt_.y()-C.y()*Pt_.x();
00055   }
00056   
00057 };
00058 
00059 // Same as Trait_for_cmp_tgt but in the case where common point is at theta=0
00060 template <class SK>
00061 struct Trait_for_cmp_tgt_theta_0{
00062   typename SK::Algebraic_kernel::Root_for_spheres_2_3 Pt_;
00063   typedef typename SK::FT Tk_type;
00064   
00065   Trait_for_cmp_tgt_theta_0(const typename SK::Algebraic_kernel::Root_for_spheres_2_3& Pt,
00066                             const typename SK::Sphere_3& sphere)
00067                           :Pt_(Pt.x()-sphere.center().x(),Pt.y()-sphere.center().y(),Pt.z()-sphere.center().z()){}
00068   
00069   typename SK::FT 
00070   unsigned_tkz_coeff_normal( const typename SK::Point_3& C,
00071                              const typename SK::FT& rk,
00072                              const typename SK::FT& R,
00073                              const typename SK::FT& gamma_k
00074                            ) const
00075   {
00076     return - CGAL_NTS sign(gamma_k)*C.y();
00077   }
00078 
00079   Tk_type
00080   unsigned_tkz_coeff_threaded(const typename SK::Point_3& C) const{
00081     return -C.y();
00082   }
00083 };
00084 
00085 // Class to compare two theta-monotone circular arc to the right of a common point.
00086 // This class need a traits class which can be either Trait_for_cmp_tgt or Trait_for_cmp_tgt_theta_0
00087 //depending on the properties of the point.
00088 template<class SK,class Traits>
00089 struct Compare_to_right_of_arcs{
00090   Traits traits_;
00091   const typename SK::Sphere_3& sphere_;
00092   
00093   Compare_to_right_of_arcs(const Traits& traits,const typename SK::Sphere_3& sphere):
00094     traits_(traits),sphere_(sphere){}
00095   
00096   typename SK::FT 
00097   gamma_k ( const typename  SK::Point_3& c,
00098             const typename SK::FT& rk,
00099             const typename SK::FT& R,
00100             typename SK::FT& ak2) const
00101   {
00102     ak2=c.x()*c.x()+c.y()*c.y()+c.z()*c.z();
00103     return (ak2+R-rk)/(2.*ak2);
00104   }
00105 
00106   typename SK::FT
00107   gamma_k (const typename SK::Point_3& c,
00108             const typename SK::FT& rk,
00109             const typename SK::FT& R) const
00110   {
00111     typename SK::FT ak2=c.x()*c.x()+c.y()*c.y()+c.z()*c.z();
00112     return (ak2+R-rk)/(2.*ak2);
00113   }
00114   
00115   bool is_arc_an_upper_one(const typename SK::Circular_arc_3& arc,const typename SK::Sphere_3& sphere) const {
00116     CGAL::Circle_type type=classify_circle_3<SK>(arc.supporting_circle(),sphere);
00117     if ( type==CGAL::NORMAL)
00118       return  extremal_points_z_coordinate<SK>(arc.supporting_circle(),sphere)-sphere.center().z() < traits_.Pt_.z();
00119     CGAL_kernel_precondition(type==POLAR);
00120     return arc.supporting_circle().center().z() < sphere.center().z() ;
00121   }
00122     
00123   
00124   typename SK::FT square_norm_tk_normal (const typename SK::Point_3& c,const typename SK::FT& rk,const typename SK::FT& R) const;
00125   typename SK::FT square_norm_tk_threaded (const typename SK::Point_3& c,const typename SK::FT& rk,const typename SK::FT& R) const;
00126   void fill_tzk_n(const typename SK::Circular_arc_3& arc,typename Traits::Tk_type& tz,typename SK::FT& n,bool is_supporting_circle_threaded) const;
00127   int sign_of_delta(const typename SK::Circular_arc_3& arc1,bool circle1_threaded,const typename SK::Circular_arc_3& arc2,bool circle2_threaded) const;
00128   typename SK::FT give_rk(const typename SK::Circular_arc_3& arc) const;
00129   int compare_for_delta_eq_0_threaded(const typename SK::Circular_arc_3& arc_threaded,const typename SK::Circular_arc_3& arc,bool circle_threaded) const;
00130   int compare_for_delta_eq_0(const typename SK::Circular_arc_3& arc1,bool circle1_threaded,const typename SK::Circular_arc_3& arc2,bool circle2_threaded) const;
00131   CGAL::Comparison_result operator()(const typename SK::Circular_arc_3& arc1,const typename SK::Circular_arc_3& arc2,bool do_it_to_left=false) const; 
00132 };
00133 
00134 
00135 template<class SK,class Traits>
00136 typename SK::FT
00137 Compare_to_right_of_arcs<SK,Traits>::square_norm_tk_normal(
00138   const typename SK::Point_3& c,
00139   const typename SK::FT& rk,
00140   const typename SK::FT& R) const
00141 {
00142   typename SK::FT ak2;
00143   typename SK::FT gk=gamma_k(c,rk,R,ak2);
00144   return ak2 * (R - gk * gk * ak2);
00145 };
00146 
00147 template<class SK,class Traits>
00148 typename SK::FT 
00149 Compare_to_right_of_arcs<SK,Traits>::square_norm_tk_threaded(
00150   const typename SK::Point_3& c,
00151   const typename SK::FT& rk,
00152   const typename SK::FT& R) const
00153 {
00154   typename SK::FT ak2;
00155   typename SK::FT gk=gamma_k(c,rk,R,ak2);
00156   return ak2 * (R - gk * gk * ak2);
00157 };
00158 
00159 template<class SK,class Traits>
00160 void
00161 Compare_to_right_of_arcs<SK,Traits>::fill_tzk_n(
00162   const typename SK::Circular_arc_3& arc,
00163   typename Traits::Tk_type& tz,
00164   typename SK::FT& n,
00165   bool is_supporting_circle_threaded) const
00166 {
00167   if (is_supporting_circle_threaded){
00168     //use a pseudo-sphere whose center is translated by ortho from the center
00169     // of the circle
00170     //~ tz=traits_.unsigned_tkz_coeff_threaded(arc.supporting_circle().supporting_sphere_center());
00171     typename SK::Vector_3 ortho=arc.supporting_circle().supporting_plane().orthogonal_vector();
00172     tz=traits_.unsigned_tkz_coeff_threaded(CGAL::ORIGIN+ortho);
00173     //~ tz*=(CGAL::pole_covered_by_supporting_sphere<SK>(arc.supporting_circle())==CGAL::NPOLE)?(1):(-1);
00174     if (ortho.z() <= 0)
00175       tz=-tz;
00176     //~ tz*= ( (ortho.z() > 0)?(1):(-1) );
00177     //~ n=square_norm_tk_threaded(arc.supporting_circle().supporting_sphere_center(),
00178                               //~ arc.supporting_circle().supporting_sphere_squared_radius(),
00179                               //~ sphere_.squared_radius());
00180     n=square_norm_tk_threaded(CGAL::ORIGIN+ortho,
00181                               arc.supporting_circle().squared_radius() + ortho.squared_length(),
00182                               sphere_.squared_radius());
00183     //warning : down to here
00184   }
00185   else{
00186     typename SK::Point_3 tmp_pt=typename SK::Point_3(0.,0.,0.) + (arc.supporting_circle().center()-sphere_.center());
00187     typename SK::FT gk=
00188       gamma_k(tmp_pt,
00189               arc.supporting_circle().squared_radius(),
00190               sphere_.squared_radius());
00191     
00192     tz=traits_.unsigned_tkz_coeff_normal(tmp_pt,
00193                                          arc.supporting_circle().squared_radius(),
00194                                          sphere_.squared_radius(),
00195                                          gk);
00196     if ( is_arc_an_upper_one(arc,sphere_) )
00197       tz=-tz;
00198     //~ tz*=is_arc_an_upper_one(arc,sphere_)?(-1):(1);
00199     n=square_norm_tk_normal(tmp_pt,
00200                             arc.supporting_circle().squared_radius(),
00201                             sphere_.squared_radius());
00202   }
00203 };
00204 
00205 
00206 template<class SK,class Traits>
00207 int 
00208 Compare_to_right_of_arcs<SK,Traits>::sign_of_delta(
00209   const typename SK::Circular_arc_3& arc1, bool is_circle_1_threaded,
00210   const typename SK::Circular_arc_3& arc2, bool is_circle_2_threaded) const
00211 {
00212   typename Traits::Tk_type tz1,tz2;
00213   typename SK::FT n1,n2;
00214   fill_tzk_n(arc1,tz1,n1,is_circle_1_threaded);
00215   fill_tzk_n(arc2,tz2,n2,is_circle_2_threaded);
00216   if (tz1==0 && tz2==0)
00217     return 0;
00218   if (tz1==0)
00219     return CGAL_NTS sign(tz2);
00220   if (tz2==0)
00221     return -CGAL_NTS sign(tz1);
00222   
00223   if (CGAL_NTS sign(tz1)!=CGAL_NTS sign(tz2))
00224     return CGAL_NTS sign(tz2);
00225   return CGAL_NTS sign(tz2)*CGAL_NTS sign(n1*CGAL::square(tz2)-n2*CGAL::square(tz1));
00226 };
00227 
00228 
00229 template<class SK,class Traits>
00230 typename SK::FT 
00231 Compare_to_right_of_arcs<SK,Traits>::give_rk(
00232   const typename SK::Circular_arc_3& arc) const
00233 {
00234   return (is_arc_an_upper_one(arc,sphere_)?(1):(-1))*arc.supporting_circle().squared_radius();  
00235 };
00236 
00237 template<class SK,class Traits>
00238 int
00239 Compare_to_right_of_arcs<SK,Traits>::compare_for_delta_eq_0_threaded(
00240   const typename SK::Circular_arc_3& arc_threaded,
00241   const typename SK::Circular_arc_3& arc,
00242   bool is_supporting_circle_threaded) const
00243 {
00244   if (!is_supporting_circle_threaded)
00245     return ( is_upper_arc<SK>(arc,sphere_) )?(-1):(1); //IN THAT CASE WE CAN OPTIMIZE AND USE THE Z-COORDINATES OF THE POINT AND CIRCLE THETA-EXTREMAL PT
00246   return (-CGAL_NTS sign(arc_threaded.supporting_circle().center().z()-arc.supporting_circle().center().z()));
00247 };
00248   
00249 template<class SK,class Traits>
00250 int 
00251 Compare_to_right_of_arcs<SK,Traits>::compare_for_delta_eq_0(
00252   const typename SK::Circular_arc_3& arc1,
00253   bool is_circle_1_threaded,
00254   const typename SK::Circular_arc_3& arc2,
00255   bool is_circle_2_threaded) const
00256 {
00257   if (is_circle_1_threaded) 
00258     return  compare_for_delta_eq_0_threaded(arc1,arc2,is_circle_2_threaded);
00259   if (is_circle_2_threaded) 
00260     return -compare_for_delta_eq_0_threaded(arc2,arc1,is_circle_1_threaded);
00261   typename SK::FT rc1=give_rk(arc1);
00262   typename SK::FT rc2=give_rk(arc2);
00263   CGAL_precondition(rc1!=0 && rc2!=0);
00264   if(CGAL_NTS sign(rc1)*CGAL_NTS sign(rc2)<0)
00265     return (CGAL_NTS sign(rc1)>0)?(1):(-1);
00266   return (rc1<rc2)?(1):(-1);
00267 };
00268 
00269 
00270 template<class SK,class Traits>
00271 CGAL::Comparison_result Compare_to_right_of_arcs<SK,Traits>::operator()(
00272                           const typename SK::Circular_arc_3& arc1,
00273                           const typename SK::Circular_arc_3& arc2,
00274                           bool do_it_to_left
00275                         ) const
00276 {
00277   bool is_circle_1_threaded = (classify_circle_3<SK>(arc1.supporting_circle(),sphere_)==CGAL::THREADED);
00278   bool is_circle_2_threaded = (classify_circle_3<SK>(arc2.supporting_circle(),sphere_)==CGAL::THREADED);
00279   
00280   int res=(do_it_to_left?-1:1)*sign_of_delta(arc1,is_circle_1_threaded,arc2,is_circle_2_threaded);
00281   if (res==0)
00282     res=compare_for_delta_eq_0(arc1,is_circle_1_threaded,arc2,is_circle_2_threaded);
00283   CGAL_precondition(res!=0);
00284   if (res<0) return CGAL::LARGER;
00285   return CGAL::SMALLER;
00286 };
00287 
00288 }
00289 }
00290 
00291 #endif //CGAL_SPHERICAL_KERNEL_PREDICATES_COMPARE_TO_RIGHT_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines