BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Kernel/function_objects.h
Go to the documentation of this file.
00001 // Copyright (c) 1999,2002,2005  Utrecht University (The Netherlands),
00002 // ETH Zurich (Switzerland), Freie Universitaet Berlin (Germany),
00003 // INRIA Sophia-Antipolis (France), Martin-Luther-University Halle-Wittenberg
00004 // (Germany), Max-Planck-Institute Saarbruecken (Germany), RISC Linz (Austria),
00005 // and Tel-Aviv University (Israel).  All rights reserved.
00006 //
00007 // This file is part of CGAL (www.cgal.org); you can redistribute it and/or
00008 // modify it under the terms of the GNU Lesser General Public License as
00009 // published by the Free Software Foundation; version 2.1 of the License.
00010 // See the file LICENSE.LGPL distributed with CGAL.
00011 //
00012 // Licensees holding a valid commercial license may use this file in
00013 // accordance with the commercial license agreement provided with the software.
00014 //
00015 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00016 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00017 //
00018 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Kernel_23/include/CGAL/Kernel/function_objects.h $
00019 // $Id: function_objects.h 47275 2008-12-08 14:47:16Z afabri $
00020 //
00021 //
00022 // Author(s)     : Stefan Schirra, Sylvain Pion
00023 
00024 #ifndef CGAL_KERNEL_FUNCTION_OBJECTS_H
00025 #define CGAL_KERNEL_FUNCTION_OBJECTS_H
00026 
00027 #include <CGAL/Origin.h>
00028 #include <CGAL/Bbox_2.h>
00029 #include <CGAL/Bbox_3.h>
00030 #include <CGAL/squared_distance_2.h>
00031 #include <CGAL/squared_distance_3.h>
00032 #include <CGAL/intersection_2.h>
00033 #include <CGAL/intersection_3.h>
00034 #include <CGAL/Kernel/Return_base_tag.h>
00035 
00036 CGAL_BEGIN_NAMESPACE
00037 
00038 namespace CommonKernelFunctors {
00039 
00040   template <typename K>
00041   class Are_ordered_along_line_2
00042   {
00043     typedef typename K::Point_2     Point_2;
00044     typedef typename K::Collinear_2 Collinear_2;
00045     typedef typename K::Collinear_are_ordered_along_line_2
00046     Collinear_are_ordered_along_line_2;
00047 
00048     Collinear_2 c;
00049     Collinear_are_ordered_along_line_2 cao;
00050   public:
00051     typedef typename K::Boolean     result_type;
00052 
00053     Are_ordered_along_line_2() {}
00054     Are_ordered_along_line_2(const Collinear_2& c_,
00055                              const Collinear_are_ordered_along_line_2& cao_)
00056       : c(c_), cao(cao_)
00057     {}
00058 
00059     result_type
00060     operator()(const Point_2& p, const Point_2& q, const Point_2& r) const
00061     { return c(p, q, r) && cao(p, q, r); }
00062   };
00063 
00064   template <typename K>
00065   class Are_ordered_along_line_3
00066   {
00067     typedef typename K::Point_3     Point_3;
00068     typedef typename K::Collinear_3 Collinear_3;
00069     typedef typename K::Collinear_are_ordered_along_line_3
00070     Collinear_are_ordered_along_line_3;
00071 
00072     Collinear_3 c;
00073     Collinear_are_ordered_along_line_3 cao;
00074   public:
00075     typedef typename K::Boolean     result_type;
00076 
00077     Are_ordered_along_line_3() {}
00078     Are_ordered_along_line_3(const Collinear_3& c_,
00079                              const Collinear_are_ordered_along_line_3& cao_)
00080       : c(c_), cao(cao_)
00081     {}
00082 
00083     result_type
00084     operator()(const Point_3& p, const Point_3& q, const Point_3& r) const
00085     { return c(p, q, r) && cao(p, q, r); }
00086   };
00087 
00088   template <typename K>
00089   class Are_strictly_ordered_along_line_2
00090   {
00091     typedef typename K::Point_2     Point_2;
00092     typedef typename K::Collinear_2 Collinear_2;
00093     typedef typename K::Collinear_are_strictly_ordered_along_line_2
00094     Collinear_are_strictly_ordered_along_line_2;
00095 
00096     Collinear_2 c;
00097     Collinear_are_strictly_ordered_along_line_2 cao;
00098   public:
00099     typedef typename K::Boolean     result_type;
00100 
00101     Are_strictly_ordered_along_line_2() {}
00102     Are_strictly_ordered_along_line_2(
00103                                       const Collinear_2& c_,
00104                                       const Collinear_are_strictly_ordered_along_line_2& cao_)
00105       : c(c_), cao(cao_)
00106     {}
00107 
00108     result_type
00109     operator()(const Point_2& p, const Point_2& q, const Point_2& r) const
00110     { return c(p, q, r) && cao(p, q, r); }
00111   };
00112 
00113   template <typename K>
00114   class Are_strictly_ordered_along_line_3
00115   {
00116     typedef typename K::Point_3     Point_3;
00117     typedef typename K::Collinear_3 Collinear_3;
00118     typedef typename K::Collinear_are_strictly_ordered_along_line_3
00119     Collinear_are_strictly_ordered_along_line_3;
00120 
00121     Collinear_3 c;
00122     Collinear_are_strictly_ordered_along_line_3 cao;
00123   public:
00124     typedef typename K::Boolean     result_type;
00125 
00126     Are_strictly_ordered_along_line_3() {}
00127     Are_strictly_ordered_along_line_3(
00128                                       const Collinear_3& c_,
00129                                       const Collinear_are_strictly_ordered_along_line_3& cao_)
00130       : c(c_), cao(cao_)
00131     {}
00132 
00133     result_type
00134     operator()(const Point_3& p, const Point_3& q, const Point_3& r) const
00135     { return c(p, q, r) && cao(p, q, r); }
00136   };
00137 
00138   template <typename K>
00139   class Assign_2
00140   {
00141     typedef typename K::Object_2  Object_2;
00142   public:
00143     //typedef typename K::Boolean   result_type;
00144     typedef bool                  result_type;
00145 
00146     template <class T>
00147     result_type
00148     operator()(T& t, const Object_2& o) const
00149     { return assign(t, o); }
00150   };
00151 
00152   template <typename K>
00153   class Assign_3
00154   {
00155     typedef typename K::Object_3        Object_3;
00156   public:
00157     //typedef typename K::Boolean         result_type;
00158     typedef bool                        result_type;
00159 
00160     template <class T>
00161     result_type
00162     operator()(T& t, const Object_3& o) const
00163     { return assign(t, o); }
00164   };
00165 
00166   template <typename K>
00167   class Compute_area_3
00168   {
00169     typedef typename K::FT                FT;
00170     typedef typename K::Point_3           Point_3;
00171     typedef typename K::Triangle_3        Triangle_3;
00172   public:
00173     typedef FT               result_type;
00174 
00175     FT
00176     operator()( const Triangle_3& t ) const
00177     {
00178         return CGAL_NTS sqrt(K().compute_squared_area_3_object()(t));
00179     }
00180 
00181     FT
00182     operator()( const Point_3& p, const Point_3& q, const Point_3& r ) const
00183     {
00184         return CGAL_NTS sqrt(K().compute_squared_area_3_object()(p, q, r));
00185     }
00186   };
00187 
00188   template <typename K>
00189   class Compute_squared_distance_2
00190   {
00191     typedef typename K::FT   FT;
00192   public:
00193     typedef FT               result_type;
00194 
00195     // There are 25 combinaisons, we use a template.
00196     template <class T1, class T2>
00197     FT
00198     operator()( const T1& t1, const T2& t2) const
00199     { return CGALi::squared_distance(t1, t2, K()); }
00200   };
00201 
00202   template <typename K>
00203   class Compute_squared_distance_3
00204   {
00205     typedef typename K::FT        FT;
00206     typedef typename K::Point_3   Point_3;
00207   public:
00208     typedef FT               result_type;
00209 
00210     // There are 25 combinaisons, we use a template.
00211     template <class T1, class T2>
00212     FT
00213     operator()( const T1& t1, const T2& t2) const
00214     { return CGALi::squared_distance(t1, t2, K()); }
00215 
00216     FT
00217     operator()( const Point_3& pt1, const Point_3& pt2) const
00218     {
00219       typedef typename K::Vector_3 Vector_3;
00220       Vector_3 vec = pt2 - pt1;
00221       return vec*vec;
00222     }
00223   };
00224 
00225   template <typename K>
00226   class Compute_squared_length_2
00227   {
00228     typedef typename K::FT          FT;
00229     typedef typename K::Segment_2   Segment_2;
00230     typedef typename K::Vector_2    Vector_2;
00231   public:
00232     typedef FT               result_type;
00233 
00234     FT
00235     operator()( const Vector_2& v) const
00236     { return CGAL_NTS square(K().compute_x_2_object()(v)) +
00237              CGAL_NTS square(K().compute_y_2_object()(v));}
00238 
00239     FT
00240     operator()( const Segment_2& s) const
00241     { return K().compute_squared_distance_2_object()(s.source(), s.target()); }
00242   };
00243 
00244   template <typename K>
00245   class Compute_squared_length_3
00246   {
00247     typedef typename K::FT          FT;
00248     typedef typename K::Segment_3   Segment_3;
00249     typedef typename K::Vector_3    Vector_3;
00250   public:
00251     typedef FT               result_type;
00252 
00253     FT
00254     operator()( const Vector_3& v) const
00255     { return v.rep().squared_length(); }
00256 
00257     FT
00258     operator()( const Segment_3& s) const
00259     { return s.squared_length(); }
00260   };
00261 
00262   template <typename K>
00263   class Compute_a_2
00264   {
00265     typedef typename K::RT             RT;
00266     typedef typename K::Line_2         Line_2;
00267 
00268   public:
00269     typedef RT               result_type;
00270 
00271     RT
00272     operator()(const Line_2& l) const
00273     {
00274       return l.rep().a();
00275     }
00276   };
00277 
00278   template <typename K>
00279   class Compute_a_3
00280   {
00281     typedef typename K::RT             RT;
00282     typedef typename K::Plane_3        Plane_3;
00283 
00284   public:
00285     typedef RT               result_type;
00286 
00287     RT
00288     operator()(const Plane_3& l) const
00289     {
00290       return l.rep().a();
00291     }
00292   };
00293 
00294 
00295   template <typename K>
00296   class Compute_b_2
00297   {
00298     typedef typename K::RT             RT;
00299     typedef typename K::Line_2         Line_2;
00300 
00301   public:
00302     typedef RT               result_type;
00303 
00304     RT
00305     operator()(const Line_2& l) const
00306     {
00307       return l.rep().b();
00308     }
00309   };
00310 
00311   template <typename K>
00312   class Compute_b_3
00313   {
00314     typedef typename K::RT             RT;
00315     typedef typename K::Plane_3        Plane_3;
00316 
00317   public:
00318     typedef RT               result_type;
00319 
00320     RT
00321     operator()(const Plane_3& l) const
00322     {
00323       return l.rep().b();
00324     }
00325   };
00326 
00327 
00328   template <typename K>
00329   class Compute_c_2
00330   {
00331     typedef typename K::RT             RT;
00332     typedef typename K::Line_2         Line_2;
00333 
00334   public:
00335     typedef RT               result_type;
00336 
00337     RT
00338     operator()(const Line_2& l) const
00339     {
00340       return l.rep().c();
00341     }
00342   };
00343 
00344   template <typename K>
00345   class Compute_c_3
00346   {
00347     typedef typename K::RT             RT;
00348     typedef typename K::Plane_3        Plane_3;
00349 
00350   public:
00351     typedef RT               result_type;
00352 
00353     RT
00354     operator()(const Plane_3& l) const
00355     {
00356       return l.rep().c();
00357     }
00358   };
00359 
00360   template <typename K>
00361   class Compute_d_3
00362   {
00363     typedef typename K::RT             RT;
00364     typedef typename K::Plane_3        Plane_3;
00365 
00366   public:
00367     typedef RT               result_type;
00368 
00369     RT
00370     operator()(const Plane_3& l) const
00371     {
00372       return l.rep().d();
00373     }
00374   };
00375 
00376   template <typename K>
00377   class Compute_x_at_y_2
00378   {
00379     typedef typename K::FT             FT;
00380     typedef typename K::Point_2        Point_2;
00381     typedef typename K::Line_2         Line_2;
00382 
00383   public:
00384     typedef FT               result_type;
00385 
00386     FT
00387     operator()(const Line_2& l, const FT& y) const
00388     {
00389       CGAL_kernel_precondition( ! l.is_degenerate() );
00390       return (FT(-l.b())*y - FT(l.c()) )/FT(l.a());
00391     }
00392   };
00393 
00394   template <typename K>
00395   class Compute_y_at_x_2
00396   {
00397     typedef typename K::FT             FT;
00398     typedef typename K::Point_2        Point_2;
00399     typedef typename K::Line_2         Line_2;
00400 
00401   public:
00402     typedef FT               result_type;
00403 
00404     FT
00405     operator()(const Line_2& l, const FT& x) const
00406     {
00407       CGAL_kernel_precondition_msg( ! l.is_vertical(),
00408                     "Compute_y_at_x(FT x) is undefined for vertical line");
00409       return (FT(-l.a())*x - FT(l.c()) )/FT(l.b());
00410     }
00411   };
00412 
00413   template <typename K>
00414   class Compute_xmin_2
00415   {
00416     typedef typename K::FT              FT;
00417     typedef typename K::Iso_rectangle_2 Iso_rectangle_2;
00418     typedef FT                          Cartesian_coordinate_type;
00419     //typedef typename K::Cartesian_coordinate_type  Cartesian_coordinate_type;
00420 
00421   public:
00422     typedef FT               result_type;
00423 
00424     Cartesian_coordinate_type
00425     operator()(const Iso_rectangle_2& r) const
00426     {
00427       return (r.min)().x();
00428     }
00429   };
00430 
00431   template <typename K>
00432   class Compute_xmin_3
00433   {
00434     typedef typename K::FT              FT;
00435     typedef typename K::Iso_cuboid_3    Iso_cuboid_3;
00436     typedef FT                          Cartesian_coordinate_type;
00437     //typedef typename K::Cartesian_coordinate_type  Cartesian_coordinate_type;
00438 
00439   public:
00440     typedef FT               result_type;
00441 
00442     Cartesian_coordinate_type
00443     operator()(const Iso_cuboid_3& r) const
00444     {
00445       return (r.min)().x();
00446     }
00447   };
00448 
00449   template <typename K>
00450   class Compute_xmax_2
00451   {
00452     typedef typename K::FT              FT;
00453     typedef typename K::Iso_rectangle_2 Iso_rectangle_2;
00454     typedef FT                          Cartesian_coordinate_type;
00455     //typedef typename K::Cartesian_coordinate_type  Cartesian_coordinate_type;
00456 
00457   public:
00458     typedef FT               result_type;
00459 
00460     Cartesian_coordinate_type
00461     operator()(const Iso_rectangle_2& r) const
00462     {
00463       return (r.max)().x();
00464     }
00465   };
00466 
00467   template <typename K>
00468   class Compute_xmax_3
00469   {
00470     typedef typename K::FT              FT;
00471     typedef typename K::Iso_cuboid_3    Iso_cuboid_3;
00472     typedef FT                          Cartesian_coordinate_type;
00473     //typedef typename K::Cartesian_coordinate_type  Cartesian_coordinate_type;
00474 
00475   public:
00476     typedef FT               result_type;
00477 
00478     Cartesian_coordinate_type
00479     operator()(const Iso_cuboid_3& r) const
00480     {
00481       return (r.max)().x();
00482     }
00483   };
00484 
00485   template <typename K>
00486   class Compute_ymin_2
00487   {
00488     typedef typename K::FT              FT;
00489     typedef typename K::Iso_rectangle_2 Iso_rectangle_2;
00490     typedef FT                          Cartesian_coordinate_type;
00491     //typedef typename K::Cartesian_coordinate_type  Cartesian_coordinate_type;
00492 
00493   public:
00494     typedef FT               result_type;
00495 
00496     Cartesian_coordinate_type
00497     operator()(const Iso_rectangle_2& r) const
00498     {
00499       return (r.min)().y();
00500     }
00501   };
00502 
00503   template <typename K>
00504   class Compute_ymin_3
00505   {
00506     typedef typename K::FT              FT;
00507     typedef typename K::Iso_cuboid_3    Iso_cuboid_3;
00508     typedef FT                          Cartesian_coordinate_type;
00509     //typedef typename K::Cartesian_coordinate_type  Cartesian_coordinate_type;
00510 
00511   public:
00512     typedef FT               result_type;
00513 
00514     Cartesian_coordinate_type
00515     operator()(const Iso_cuboid_3& r) const
00516     {
00517       return (r.min)().y();
00518     }
00519   };
00520 
00521   template <typename K>
00522   class Compute_ymax_2
00523   {
00524     typedef typename K::FT              FT;
00525     typedef typename K::Iso_rectangle_2 Iso_rectangle_2;
00526     typedef FT                          Cartesian_coordinate_type;
00527     //typedef typename K::Cartesian_coordinate_type  Cartesian_coordinate_type;
00528 
00529   public:
00530     typedef FT               result_type;
00531 
00532     Cartesian_coordinate_type
00533     operator()(const Iso_rectangle_2& r) const
00534     {
00535       return (r.max)().y();
00536     }
00537   };
00538 
00539   template <typename K>
00540   class Compute_ymax_3
00541   {
00542     typedef typename K::FT              FT;
00543     typedef typename K::Iso_cuboid_3    Iso_cuboid_3;
00544     typedef FT                          Cartesian_coordinate_type;
00545     //typedef typename K::Cartesian_coordinate_type  Cartesian_coordinate_type;
00546 
00547   public:
00548     typedef FT               result_type;
00549 
00550     Cartesian_coordinate_type
00551     operator()(const Iso_cuboid_3& r) const
00552     {
00553       return (r.max)().y();
00554     }
00555   };
00556 
00557   template <typename K>
00558   class Compute_zmin_3
00559   {
00560     typedef typename K::FT              FT;
00561     typedef typename K::Iso_cuboid_3    Iso_cuboid_3;
00562     typedef FT                          Cartesian_coordinate_type;
00563     //typedef typename K::Cartesian_coordinate_type  Cartesian_coordinate_type;
00564 
00565   public:
00566     typedef FT               result_type;
00567 
00568     Cartesian_coordinate_type
00569     operator()(const Iso_cuboid_3& r) const
00570     {
00571       return (r.min)().z();
00572     }
00573   };
00574 
00575   template <typename K>
00576   class Compute_zmax_3
00577   {
00578     typedef typename K::FT              FT;
00579     typedef typename K::Iso_cuboid_3    Iso_cuboid_3;
00580     typedef FT                          Cartesian_coordinate_type;
00581     //typedef typename K::Cartesian_coordinate_type  Cartesian_coordinate_type;
00582 
00583   public:
00584     typedef FT               result_type;
00585 
00586     Cartesian_coordinate_type
00587     operator()(const Iso_cuboid_3& r) const
00588     {
00589       return (r.max)().z();
00590     }
00591   };
00592 
00593   template <typename K>
00594   class Construct_center_2 : Has_qrt
00595   {
00596     typedef typename K::Point_2   Point_2;
00597     typedef typename K::Circle_2  Circle_2;
00598   public:
00599     typedef Point_2          result_type;
00600 
00601     const Point_2 &
00602     operator()(const Circle_2& c) const
00603     { return c.rep().center(); }
00604   };
00605 
00606   template <typename K>
00607   class Construct_center_3 : Has_qrt
00608   {
00609     typedef typename K::Point_3   Point_3;
00610     typedef typename K::Sphere_3  Sphere_3;
00611     typedef typename K::Circle_3  Circle_3;
00612   public:
00613     typedef Point_3          result_type;
00614 
00615     const Point_3 &
00616     operator()(const Sphere_3& s) const
00617     { return s.rep().center(); }
00618 
00619     const Point_3 &
00620     operator()(const Circle_3& c) const
00621     { return c.rep().center(); }
00622 
00623   };
00624 
00625   template <typename K>
00626   class Construct_circle_2
00627   {
00628     typedef typename K::FT          FT;
00629     typedef typename K::Point_2     Point_2;
00630     typedef typename K::Circle_2    Circle_2;
00631     typedef typename Circle_2::Rep  Rep;
00632   public:
00633     typedef Circle_2         result_type;
00634 
00635     Rep // Circle_2
00636     operator()( Return_base_tag,
00637                 const Point_2& center, const FT& squared_radius,
00638                 Orientation orientation = COUNTERCLOCKWISE) const
00639     { return Rep(center, squared_radius, orientation); }
00640 
00641     Rep // Circle_2
00642     operator()( Return_base_tag,
00643                 const Point_2& p, const Point_2& q, const Point_2& r) const
00644     {
00645       typename K::Orientation_2 orientation;
00646       typename K::Compute_squared_distance_2 squared_distance;
00647       typename K::Construct_circumcenter_2 circumcenter;
00648       typename K::Orientation orient = orientation(p, q, r);
00649       CGAL_kernel_precondition( orient != COLLINEAR);
00650 
00651       Point_2 center = circumcenter(p, q, r);
00652 
00653       return Rep(center, squared_distance(p, center), orient);
00654     }
00655 
00656     Rep // Circle_2
00657     operator()( Return_base_tag,
00658                 const Point_2& p, const Point_2& q,
00659                 Orientation orientation = COUNTERCLOCKWISE) const
00660     {
00661       CGAL_kernel_precondition( orientation != COLLINEAR);
00662 
00663       typename K::Compute_squared_distance_2 squared_distance;
00664       typename K::Construct_midpoint_2 midpoint;
00665       if (p != q) {
00666         Point_2 center = midpoint(p, q);
00667         return Rep(center, squared_distance(p, center), orientation);
00668       } else
00669         return Rep(p, FT(0), orientation);
00670     }
00671 
00672     Rep // Circle_2
00673     operator()( Return_base_tag,
00674                 const Point_2& p, const Point_2& q,
00675                 const FT& bulge) const
00676     {
00677      
00678       typename K::Compute_squared_distance_2 squared_distance;
00679       const FT sqr_bulge = CGAL::square(bulge);
00680       const FT common = (FT(1) - sqr_bulge) / (FT(4)*bulge);
00681       const FT x_coord = (p.x() + q.x())/FT(2)
00682                          + common*(p.y() - q.y());
00683       const FT y_coord = (p.y() + q.y())/FT(2)
00684                           + common*(q.x() - p.x());
00685       
00686       const FT sqr_rad = squared_distance(p, q) 
00687                          * (FT(1)/sqr_bulge + FT(2) + sqr_bulge) / FT(16); 
00688 
00689       return Rep(Point_2(x_coord, y_coord), sqr_rad); 
00690     }
00691 
00692 
00693     Rep // Circle_2
00694     operator()( Return_base_tag, const Point_2& center,
00695                 Orientation orientation = COUNTERCLOCKWISE) const
00696     {
00697       CGAL_kernel_precondition( orientation != COLLINEAR );
00698 
00699       return Rep(center, FT(0), orientation);
00700     }
00701 
00702 
00703     Circle_2
00704     operator()( const Point_2& center, const FT& squared_radius,
00705                 Orientation orientation = COUNTERCLOCKWISE) const
00706     {
00707       return this->operator()(Return_base_tag(),
00708                               center, squared_radius, orientation);
00709     }
00710 
00711     Circle_2
00712     operator()( const Point_2& p, const Point_2& q, const Point_2& r) const
00713     {
00714       return this->operator()(Return_base_tag(), p, q, r);
00715     }
00716 
00717     Circle_2
00718     operator()( const Point_2& p, const Point_2& q,
00719                 Orientation orientation = COUNTERCLOCKWISE) const
00720     {
00721       return this->operator()(Return_base_tag(), p, q, orientation);
00722     }
00723 
00724     Circle_2
00725     operator()( const Point_2& p, const Point_2& q,
00726                 const FT& bulge) const
00727     {
00728       return this->operator()(Return_base_tag(), p, q, bulge);
00729     }
00730 
00731     Circle_2
00732     operator()( const Point_2& center,
00733                 Orientation orientation = COUNTERCLOCKWISE) const
00734     {
00735       return this->operator()(Return_base_tag(), center, orientation);
00736     }
00737   };
00738 
00739   template < typename K >
00740   class Construct_circle_3
00741   {
00742     typedef typename K::FT           FT;
00743     typedef typename K::Point_3      Point_3;
00744     typedef typename K::Plane_3      Plane_3;
00745     typedef typename K::Sphere_3     Sphere_3;
00746     typedef typename K::Circle_3     Circle_3;
00747     typedef typename K::Vector_3     Vector_3;
00748     typedef typename K::Direction_3  Direction_3;
00749     typedef typename Circle_3::Rep    Rep;
00750 
00751   public:
00752     typedef Circle_3                  result_type;
00753 
00754     Rep
00755     operator() (Return_base_tag, const Point_3& p,
00756                 const FT& sr, const Plane_3& plane) const
00757     { return Rep(p, sr, plane); }
00758 
00759     Rep
00760     operator() (Return_base_tag, const Point_3& p,
00761                 const FT& sr, const Vector_3& v) const
00762     { return Rep(p, sr, v); }
00763 
00764     Rep
00765     operator() (Return_base_tag, const Point_3& p,
00766                 const FT& sr, const Direction_3& d) const
00767     { return Rep(p, sr, d); }
00768 
00769     Rep
00770     operator() (Return_base_tag, const Sphere_3& s1,
00771                 const Sphere_3& s2) const
00772     { return Rep(s1, s2); }
00773 
00774     Rep
00775     operator() (Return_base_tag, const Plane_3& p,
00776                 const Sphere_3& s) const
00777     { return Rep(p, s); }
00778 
00779     Rep
00780     operator() (Return_base_tag, const Plane_3& p,
00781                 const Sphere_3& s, int a) const
00782     { return Rep(p, s, a); }
00783 
00784     Rep
00785     operator() (Return_base_tag, const Point_3& p1,
00786                 const Point_3& p2, const Point_3& p3) const
00787     { return Rep(p1, p2, p3); }
00788 
00789     Circle_3
00790     operator()(const Point_3& p, const FT& sr,
00791                const Plane_3& plane) const
00792     { return this->operator()(Return_base_tag(), p, sr, plane); }
00793 
00794     Circle_3
00795     operator() (const Point_3& p, const FT& sr,
00796                 const Vector_3& v) const
00797     { return this->operator()(Return_base_tag(), p, sr, v); }
00798 
00799     Circle_3
00800     operator() (const Point_3& p, const FT& sr,
00801                 const Direction_3& d) const
00802     { return this->operator()(Return_base_tag(), p, sr, d); }
00803 
00804     Circle_3
00805     operator() (const Sphere_3& s1, const Sphere_3& s2) const
00806     { return this->operator()(Return_base_tag(), s1, s2); }
00807 
00808     Circle_3
00809     operator() (const Plane_3& p, const Sphere_3& s) const
00810     { return this->operator()(Return_base_tag(), p, s); }
00811 
00812     Circle_3
00813     operator() (const Sphere_3& s, const Plane_3& p) const
00814     { return this->operator()(Return_base_tag(), p, s); }
00815 
00816     Circle_3
00817     operator() (const Plane_3& p, const Sphere_3& s, int a) const
00818     { return this->operator()(Return_base_tag(), p, s, a); }
00819 
00820     Circle_3
00821     operator() (const Sphere_3& s, const Plane_3& p, int a) const
00822     { return this->operator()(Return_base_tag(), p, s, a); }
00823 
00824     Circle_3
00825     operator()( const Point_3& p1, const Point_3& p2, const Point_3& p3) const
00826     { return this->operator()(Return_base_tag(), p1, p2, p3); }
00827   };
00828 
00829   template <typename K>
00830   class Construct_iso_cuboid_3
00831   {
00832     typedef typename K::RT            RT;
00833     typedef typename K::Point_3       Point_3;
00834     typedef typename K::Iso_cuboid_3  Iso_cuboid_3;
00835     typedef typename Iso_cuboid_3::Rep  Rep;
00836   public:
00837     typedef Iso_cuboid_3      result_type;
00838 
00839     Rep // Iso_cuboid_3
00840     operator()(Return_base_tag, const Point_3& p, const Point_3& q, int) const
00841     { return Rep(p, q, 0); }
00842 
00843     Rep // Iso_cuboid_3
00844     operator()(Return_base_tag, const Point_3& p, const Point_3& q) const
00845     { return Rep(p, q); }
00846 
00847     Rep // Iso_cuboid_3
00848     operator()(Return_base_tag, const Point_3 &left,   const Point_3 &right,
00849                const Point_3 &bottom, const Point_3 &top,
00850                const Point_3 &far_,   const Point_3 &close) const
00851     { return Rep(left, right, bottom, top, far_, close); }
00852 
00853     Rep // Iso_cuboid_3
00854     operator()(Return_base_tag, const RT& min_hx, const RT& min_hy, const RT& min_hz,
00855                const RT& max_hx, const RT& max_hy, const RT& max_hz,
00856                const RT& hw) const
00857     { return Rep(min_hx, min_hy, min_hz, max_hx, max_hy, max_hz, hw); }
00858 
00859     Rep // Iso_cuboid_3
00860     operator()(Return_base_tag, const RT& min_hx, const RT& min_hy, const RT& min_hz,
00861                const RT& max_hx, const RT& max_hy, const RT& max_hz) const
00862     { return Rep(min_hx, min_hy, min_hz, max_hx, max_hy, max_hz); }
00863 
00864 
00865     Iso_cuboid_3
00866     operator()(const Point_3& p, const Point_3& q, int) const
00867     { return this->operator()(Return_base_tag(), p, q, 0); }
00868 
00869     Iso_cuboid_3
00870     operator()(const Point_3& p, const Point_3& q) const
00871     { return this->operator()(Return_base_tag(), p, q); }
00872 
00873     Iso_cuboid_3
00874     operator()(const Point_3 &left,   const Point_3 &right,
00875                const Point_3 &bottom, const Point_3 &top,
00876                const Point_3 &far_,   const Point_3 &close) const
00877     { return this->operator()(Return_base_tag(), left, right, bottom, top, far_, close); }
00878 
00879     Iso_cuboid_3
00880     operator()(const RT& min_hx, const RT& min_hy, const RT& min_hz,
00881                const RT& max_hx, const RT& max_hy, const RT& max_hz,
00882                const RT& hw) const
00883     { return this->operator()(Return_base_tag(), min_hx, min_hy, min_hz, max_hx, max_hy, max_hz, hw); }
00884 
00885     Iso_cuboid_3
00886     operator()(const RT& min_hx, const RT& min_hy, const RT& min_hz,
00887                const RT& max_hx, const RT& max_hy, const RT& max_hz) const
00888     { return this->operator()(Return_base_tag(), min_hx, min_hy, min_hz, max_hx, max_hy, max_hz); }
00889   };
00890 
00891   template <typename K>
00892   class Construct_max_vertex_2 : Has_qrt
00893   {
00894     typedef typename K::Point_2          Point_2;
00895     typedef typename K::Segment_2        Segment_2;
00896     typedef typename K::Iso_rectangle_2  Iso_rectangle_2;
00897   public:
00898     typedef Point_2           result_type;
00899 
00900     const Point_2&
00901     operator()(const Iso_rectangle_2& r) const
00902     { return (r.rep().max)(); }
00903 
00904     const Point_2&
00905     operator()(const Segment_2& s) const
00906     { return (s.max)(); }
00907   };
00908 
00909 
00910   template <typename K>
00911   class Construct_min_vertex_2 : Has_qrt
00912   {
00913     typedef typename K::Point_2          Point_2;
00914     typedef typename K::Segment_2        Segment_2;
00915     typedef typename K::Iso_rectangle_2  Iso_rectangle_2;
00916   public:
00917     typedef Point_2           result_type;
00918 
00919     const Point_2&
00920     operator()(const Iso_rectangle_2& r) const
00921     { return (r.rep().min)(); }
00922 
00923     const Point_2&
00924     operator()(const Segment_2& s) const
00925     { return (s.min)(); }
00926   };
00927 
00928 
00929 
00930   template <typename K>
00931   class Construct_max_vertex_3
00932   {
00933     typedef typename K::Point_3          Point_3;
00934     typedef typename K::Segment_3        Segment_3;
00935     typedef typename K::Iso_cuboid_3     Iso_cuboid_3;
00936   public:
00937     typedef Point_3           result_type;
00938 
00939     Point_3
00940     operator()(const Iso_cuboid_3& r) const
00941     { return (r.rep().max)(); }
00942 
00943     const Point_3&
00944     operator()(const Segment_3& s) const
00945     { return (s.rep().max)(); }
00946   };
00947 
00948   template <typename K>
00949   class Construct_min_vertex_3
00950   {
00951     typedef typename K::Point_3          Point_3;
00952     typedef typename K::Segment_3        Segment_3;
00953     typedef typename K::Iso_cuboid_3     Iso_cuboid_3;
00954   public:
00955     typedef Point_3           result_type;
00956 
00957     Point_3
00958     operator()(const Iso_cuboid_3& r) const
00959     { return (r.rep().min)(); }
00960 
00961     const Point_3&
00962     operator()(const Segment_3& s) const
00963     { return (s.rep().min)(); }
00964   };
00965 
00966   template <typename K>
00967   class Construct_normal_3
00968   {
00969     typedef typename K::Point_3          Point_3;
00970     typedef typename K::Vector_3         Vector_3;
00971   public:
00972     typedef Vector_3           result_type;
00973 
00974     Vector_3
00975     operator()(const Point_3& p,const Point_3& q, const Point_3& r) const
00976     { 
00977       CGAL_kernel_precondition(! K().collinear_3_object()(p,q,r) ); 
00978       Vector_3 res = CGAL::cross_product(q-p, r-p);
00979       return res; }
00980   };
00981 
00982   template <typename K>
00983   class Construct_object_2
00984   {
00985     typedef typename K::Object_2   Object_2;
00986   public:
00987     typedef Object_2         result_type;
00988 
00989     template <class Cls>
00990     Object_2
00991     operator()( const Cls& c) const
00992     { return make_object(c); }
00993   };
00994 
00995   template <typename K>
00996   class Construct_object_3
00997   {
00998     typedef typename K::Object_3   Object_3;
00999   public:
01000     typedef Object_3         result_type;
01001 
01002     template <class Cls>
01003     Object_3
01004     operator()( const Cls& c) const
01005     { return make_object(c); }
01006   };
01007 
01008   template <typename K>
01009   class Construct_opposite_circle_2
01010   {
01011     typedef typename K::Circle_2   Circle_2;
01012   public:
01013     typedef Circle_2         result_type;
01014 
01015     Circle_2
01016     operator()( const Circle_2& c) const
01017     { return c.opposite(); }
01018   };
01019 
01020   template <typename K>
01021   class Construct_opposite_direction_2
01022   {
01023     typedef typename K::Direction_2    Direction_2;
01024     typedef typename Direction_2::Rep  Rep;
01025   public:
01026     typedef Direction_2      result_type;
01027 
01028     Direction_2
01029     operator()( const Direction_2& d) const
01030     {  return Rep(-d.dx(), -d.dy()); }
01031   };
01032 
01033   template <typename K>
01034   class Construct_opposite_direction_3
01035   {
01036     typedef typename K::Direction_3    Direction_3;
01037     typedef typename Direction_3::Rep  Rep;
01038   public:
01039     typedef Direction_3      result_type;
01040 
01041     Direction_3
01042     operator()( const Direction_3& d) const
01043     {  return Rep(-d.dx(), -d.dy(), -d.dz()); }
01044   };
01045 
01046   template <typename K>
01047   class Construct_opposite_line_2
01048   {
01049     typedef typename K::Line_2   Line_2;
01050   public:
01051     typedef Line_2           result_type;
01052 
01053     Line_2
01054     operator()( const Line_2& l) const
01055     { return Line_2( -l.a(), -l.b(), -l.c()); }
01056   };
01057 
01058   template <typename K>
01059   class Construct_opposite_line_3
01060   {
01061     typedef typename K::Line_3   Line_3;
01062   public:
01063     typedef Line_3           result_type;
01064 
01065     Line_3
01066     operator()( const Line_3& l) const
01067     { return l.rep().opposite(); }
01068   };
01069 
01070   template <typename K>
01071   class Construct_opposite_plane_3
01072   {
01073     typedef typename K::Plane_3   Plane_3;
01074   public:
01075     typedef Plane_3          result_type;
01076 
01077     Plane_3
01078     operator()( const Plane_3& p) const
01079     { return p.rep().opposite(); }
01080   };
01081 
01082   template <typename K>
01083   class Construct_opposite_ray_2
01084   {
01085     typedef typename K::Ray_2   Ray_2;
01086   public:
01087     typedef Ray_2            result_type;
01088 
01089     Ray_2
01090     operator()( const Ray_2& r) const
01091     { return r.opposite(); }
01092   };
01093 
01094   template <typename K>
01095   class Construct_opposite_ray_3
01096   {
01097     typedef typename K::Ray_3   Ray_3;
01098   public:
01099     typedef Ray_3            result_type;
01100 
01101     Ray_3
01102     operator()( const Ray_3& r) const
01103     { return r.opposite(); }
01104   };
01105 
01106   template <typename K>
01107   class Construct_opposite_segment_2
01108   {
01109     typedef typename K::Segment_2  Segment_2;
01110   public:
01111     typedef Segment_2        result_type;
01112 
01113     Segment_2
01114     operator()( const Segment_2& s) const
01115     { return Segment_2(s.target(), s.source()); }
01116   };
01117 
01118   template <typename K>
01119   class Construct_opposite_segment_3
01120   {
01121     typedef typename K::Segment_3  Segment_3;
01122   public:
01123     typedef Segment_3        result_type;
01124 
01125     Segment_3
01126     operator()( const Segment_3& s) const
01127     { return s.rep().opposite(); }
01128   };
01129 
01130   template <typename K>
01131   class Construct_opposite_sphere_3
01132   {
01133     typedef typename K::Sphere_3   Sphere_3;
01134   public:
01135     typedef Sphere_3         result_type;
01136 
01137     Sphere_3
01138     operator()( const Sphere_3& s) const
01139     { return s.rep().opposite(); }
01140   };
01141 
01142   template <typename K>
01143   class Construct_opposite_triangle_2
01144   {
01145     typedef typename K::Triangle_2  Triangle_2;
01146   public:
01147     typedef Triangle_2       result_type;
01148 
01149     Triangle_2
01150     operator()( const Triangle_2& t) const
01151     { return Triangle_2(t.vertex(0), t.vertex(2), t.vertex(1));}
01152   };
01153 
01154   template <typename K>
01155   class Construct_perpendicular_line_3
01156   {
01157     typedef typename K::Line_3    Line_3;
01158     typedef typename K::Point_3   Point_3;
01159     typedef typename K::Plane_3   Plane_3;
01160   public:
01161     typedef Line_3           result_type;
01162 
01163     Line_3
01164     operator()( const Plane_3& pl, const Point_3& p) const
01165     { return pl.rep().perpendicular_line(p); }
01166   };
01167 
01168   template <typename K>
01169   class Construct_perpendicular_plane_3
01170   {
01171     typedef typename K::Line_3    Line_3;
01172     typedef typename K::Point_3   Point_3;
01173     typedef typename K::Plane_3   Plane_3;
01174   public:
01175     typedef Plane_3          result_type;
01176 
01177     Plane_3
01178     operator()( const Line_3& l, const Point_3& p) const
01179     { return l.rep().perpendicular_plane(p); }
01180   };
01181 
01182   template <typename K>
01183   class Construct_plane_3
01184   {
01185     typedef typename K::RT           RT;
01186     typedef typename K::Point_3      Point_3;
01187     typedef typename K::Vector_3     Vector_3;
01188     typedef typename K::Direction_3  Direction_3;
01189     typedef typename K::Line_3       Line_3;
01190     typedef typename K::Ray_3        Ray_3;
01191     typedef typename K::Segment_3    Segment_3;
01192     typedef typename K::Plane_3      Plane_3;
01193     typedef typename K::Circle_3     Circle_3;
01194     typedef typename Plane_3::Rep    Rep;
01195   public:
01196     typedef Plane_3          result_type;
01197 
01198     Rep // Plane_3
01199     operator()(Return_base_tag, const RT& a, const RT& b, const RT& c, const RT& d) const
01200     { return Rep(a, b, c, d); }
01201 
01202     Rep // Plane_3
01203     operator()(Return_base_tag, const Point_3& p, const Point_3& q, const Point_3& r) const
01204     { return Rep(p, q, r); }
01205 
01206     Rep // Plane_3
01207     operator()(Return_base_tag, const Point_3& p, const Direction_3& d) const
01208     { return Rep(p, d); }
01209 
01210     Rep // Plane_3
01211     operator()(Return_base_tag, const Point_3& p, const Vector_3& v) const
01212     { return Rep(p, v); }
01213 
01214     Rep // Plane_3
01215     operator()(Return_base_tag, const Line_3& l, const Point_3& p) const
01216     { return Rep(l, p); }
01217 
01218     Rep // Plane_3
01219     operator()(Return_base_tag, const Ray_3& r, const Point_3& p) const
01220     { return Rep(r, p); }
01221 
01222     Rep // Plane_3
01223     operator()(Return_base_tag, const Segment_3& s, const Point_3& p) const
01224     { return Rep(s, p); }
01225 
01226     Rep // Plane_3
01227     operator()(Return_base_tag, const Circle_3 & c) const
01228     { return c.rep().supporting_plane(); }
01229 
01230     Plane_3
01231     operator()(const RT& a, const RT& b, const RT& c, const RT& d) const
01232     { return this->operator()(Return_base_tag(), a, b, c, d); }
01233 
01234     Plane_3
01235     operator()(const Point_3& p, const Point_3& q, const Point_3& r) const
01236     { return this->operator()(Return_base_tag(), p, q, r); }
01237 
01238     Plane_3
01239     operator()(const Point_3& p, const Direction_3& d) const
01240     { return this->operator()(Return_base_tag(), p, d); }
01241 
01242     Plane_3
01243     operator()(const Point_3& p, const Vector_3& v) const
01244     { return this->operator()(Return_base_tag(), p, v); }
01245 
01246     Plane_3
01247     operator()(const Line_3& l, const Point_3& p) const
01248     { return this->operator()(Return_base_tag(), l, p); }
01249 
01250     Plane_3
01251     operator()(const Ray_3& r, const Point_3& p) const
01252     { return this->operator()(Return_base_tag(), r, p); }
01253 
01254     Plane_3
01255     operator()(const Segment_3& s, const Point_3& p) const
01256     { return this->operator()(Return_base_tag(), s, p); }
01257 
01258     Plane_3
01259     operator()(const Circle_3 & c) const
01260     { return this->operator()(Return_base_tag(), c); }
01261 
01262   };
01263 
01264   template <typename K>
01265   class Construct_point_on_2
01266   {
01267     typedef typename K::Point_2    Point_2;
01268     typedef typename K::Segment_2  Segment_2;
01269     typedef typename K::Line_2     Line_2;
01270     typedef typename K::Ray_2      Ray_2;
01271   public:
01272     typedef Point_2          result_type;
01273 
01274     Point_2
01275     operator()( const Line_2& l, int i) const
01276     { return l.point(i); }
01277 
01278     Point_2
01279     operator()( const Segment_2& s, int i) const
01280     { return s.point(i); }
01281 
01282     Point_2
01283     operator()( const Ray_2& r, int i) const
01284     { return r.point(i); }
01285   };
01286 
01287   template <typename K>
01288   class Construct_point_on_3
01289   {
01290     typedef typename K::Point_3    Point_3;
01291     typedef typename K::Segment_3  Segment_3;
01292     typedef typename K::Line_3     Line_3;
01293     typedef typename K::Ray_3      Ray_3;
01294     typedef typename K::Plane_3    Plane_3;
01295   public:
01296     typedef Point_3          result_type;
01297 
01298     Point_3
01299     operator()( const Line_3& l, int i) const
01300     { return l.rep().point(i); }
01301 
01302     Point_3
01303     operator()( const Segment_3& s, int i) const
01304     { return s.point(i); }
01305 
01306     Point_3
01307     operator()( const Ray_3& r, int i) const
01308     { return r.rep().point(i); }
01309 
01310     Point_3
01311     operator()( const Plane_3& p) const
01312     { return p.rep().point(); }
01313   };
01314 
01315   template <typename K>
01316   class Construct_projected_xy_point_2
01317   {
01318     typedef typename K::Point_2    Point_2;
01319     typedef typename K::Point_3    Point_3;
01320     typedef typename K::Plane_3    Plane_3;
01321   public:
01322     typedef Point_2          result_type;
01323 
01324     Point_2
01325     operator()( const Plane_3& h, const Point_3& p) const
01326     {  return h.rep().to_2d(p); }
01327   };
01328 
01329   template <typename K>
01330   class Construct_ray_2
01331   {
01332     typedef typename K::Point_2      Point_2;
01333     typedef typename K::Vector_2     Vector_2;
01334     typedef typename K::Direction_2  Direction_2;
01335     typedef typename K::Line_2       Line_2;
01336     typedef typename K::Ray_2        Ray_2;
01337     typedef typename Ray_2::Rep   Rep;
01338   public:
01339     typedef Ray_2            result_type;
01340 
01341     Rep // Ray_2
01342     operator()(Return_base_tag, const Point_2& p, const Point_2& q) const
01343     {  return Rep(p, q); }
01344 
01345     Rep // Ray_2
01346     operator()(Return_base_tag, const Point_2& p, const Vector_2& v) const
01347     {  return Rep(p, K().construct_translated_point_2_object()(p,  v)); }
01348 
01349     Rep // Ray_2
01350     operator()(Return_base_tag, const Point_2& p, const Direction_2& d) const
01351     {  return Rep(p, K().construct_translated_point_2_object()(p, d.to_vector())); }
01352 
01353     Rep // Ray_2
01354     operator()(Return_base_tag, const Point_2& p, const Line_2& l) const
01355     {  return Rep(p, K().construct_translated_point_2_object()(p, l.to_vector())); }
01356 
01357 
01358     Ray_2
01359     operator()(const Point_2& p, const Point_2& q) const
01360     { return this->operator()(Return_base_tag(), p, q); }
01361 
01362     Ray_2
01363     operator()(const Point_2& p, const Vector_2& v) const
01364     { return this->operator()(Return_base_tag(), p, v); }
01365 
01366     Ray_2
01367     operator()(const Point_2& p, const Direction_2& d) const
01368     { return this->operator()(Return_base_tag(), p, d); }
01369 
01370     Ray_2
01371     operator()(const Point_2& p, const Line_2& l) const
01372     { return this->operator()(Return_base_tag(), p, l); }
01373   };
01374 
01375   template <typename K>
01376   class Construct_ray_3
01377   {
01378     typedef typename K::Point_3      Point_3;
01379     typedef typename K::Vector_3     Vector_3;
01380     typedef typename K::Direction_3  Direction_3;
01381     typedef typename K::Line_3       Line_3;
01382     typedef typename K::Ray_3        Ray_3;
01383     typedef typename Ray_3::Rep      Rep;
01384   public:
01385     typedef Ray_3            result_type;
01386 
01387     Rep // Ray_3
01388     operator()(Return_base_tag, const Point_3& p, const Point_3& q) const
01389     {  return Rep(p, q); }
01390 
01391     Rep // Ray_3
01392     operator()(Return_base_tag, const Point_3& p, const Vector_3& v) const
01393     {  return Rep(p, v); }
01394 
01395     Rep // Ray_3
01396     operator()(Return_base_tag, const Point_3& p, const Direction_3& d) const
01397     {  return Rep(p, d); }
01398 
01399     Rep // Ray_3
01400     operator()(Return_base_tag, const Point_3& p, const Line_3& l) const
01401     {  return Rep(p, l); }
01402 
01403 
01404     Ray_3
01405     operator()(const Point_3& p, const Point_3& q) const
01406     { return this->operator()(Return_base_tag(), p, q); }
01407 
01408     Ray_3
01409     operator()(const Point_3& p, const Vector_3& v) const
01410     { return this->operator()(Return_base_tag(), p, v); }
01411 
01412     Ray_3
01413     operator()(const Point_3& p, const Direction_3& d) const
01414     { return this->operator()(Return_base_tag(), p, d); }
01415 
01416     Ray_3
01417     operator()(const Point_3& p, const Line_3& l) const
01418     { return this->operator()(Return_base_tag(), p, l); }
01419   };
01420 
01421   template <typename K>
01422   class Construct_segment_2
01423   {
01424     typedef typename K::Segment_2  Segment_2;
01425     typedef typename Segment_2::Rep  Rep;
01426     typedef typename K::Point_2    Point_2;
01427   public:
01428     typedef Segment_2        result_type;
01429 
01430     Rep // Segment_2
01431     operator()(Return_base_tag, const Point_2& p, const Point_2& q) const
01432     {  return Rep(p, q); }
01433 
01434     Segment_2
01435     operator()( const Point_2& p, const Point_2& q) const
01436     { return this->operator()(Return_base_tag(), p, q); }
01437   };
01438 
01439   template <typename K>
01440   class Construct_segment_3
01441   {
01442     typedef typename K::Segment_3  Segment_3;
01443     typedef typename K::Point_3    Point_3;
01444     typedef typename Segment_3::Rep  Rep;
01445   public:
01446     typedef Segment_3        result_type;
01447 
01448     Rep // Segment_3
01449     operator()(Return_base_tag, const Point_3& p, const Point_3& q) const
01450     {  return Rep(p, q); }
01451 
01452     Segment_3
01453     operator()( const Point_3& p, const Point_3& q) const
01454     { return this->operator()(Return_base_tag(), p, q); }
01455   };
01456 
01457 
01458 
01459 
01460   template <typename K>
01461   class Construct_source_2 : Has_qrt
01462   {
01463     typedef typename K::Segment_2  Segment_2;
01464     typedef typename K::Ray_2      Ray_2;
01465     typedef typename K::Point_2    Point_2;
01466   public:
01467     typedef Point_2                result_type;
01468 
01469     const result_type&
01470     operator()(const Segment_2& s) const
01471     {  return s.rep().source(); }
01472 
01473     const result_type&
01474     operator()(const Ray_2& r) const
01475     {  return r.rep().source(); }
01476   };
01477 
01478   template <typename K>
01479   class Construct_source_3 : Has_qrt
01480   {
01481     typedef typename K::Segment_3  Segment_3;
01482     typedef typename K::Ray_3      Ray_3;
01483     typedef typename K::Point_3    Point_3;
01484   public:
01485     typedef Point_3                result_type;
01486 
01487     const result_type&
01488     operator()(const Segment_3& s) const
01489     {  return s.rep().source(); }
01490 
01491     const result_type&
01492     operator()(const Ray_3& r) const
01493     {  return r.rep().source(); }
01494   };
01495 
01496 
01497   template <typename K>
01498   class Construct_target_2 : Has_qrt
01499   {
01500     typedef typename K::Segment_2  Segment_2;
01501     typedef typename K::Point_2    Point_2;
01502   public:
01503     typedef Point_2                result_type;
01504 
01505     const result_type&
01506     operator()(const Segment_2& s) const
01507     {  return s.rep().target(); }
01508   };
01509 
01510   template <typename K>
01511   class Construct_target_3 : Has_qrt
01512   {
01513     typedef typename K::Segment_3  Segment_3;
01514     typedef typename K::Point_3    Point_3;
01515   public:
01516     typedef Point_3                result_type;
01517 
01518     const result_type&
01519     operator()(const Segment_3& s) const
01520     {  return s.rep().target(); }
01521   };
01522 
01523   template <typename K>
01524   class Construct_second_point_2 : Has_qrt
01525   {
01526     typedef typename K::Ray_2    Ray_2;
01527     typedef typename K::Point_2  Point_2;
01528   public:
01529     typedef Point_2              result_type;
01530 
01531     const result_type&
01532     operator()(const Ray_2& r) const
01533     {  return r.rep().second_point(); }
01534   };
01535 
01536   template <typename K>
01537   class Construct_second_point_3 // : Has_qrt
01538   {
01539     typedef typename K::Ray_3    Ray_3;
01540     typedef typename K::Point_3  Point_3;
01541   public:
01542     typedef Point_3              result_type;
01543 
01544     result_type // const result_type& // Homogeneous...
01545     operator()(const Ray_3& r) const
01546     {  return r.rep().second_point(); }
01547   };
01548 
01549   template <typename K>
01550   class Construct_sphere_3
01551   {
01552     typedef typename K::FT         FT;
01553     typedef typename K::Point_3    Point_3;
01554     typedef typename K::Sphere_3   Sphere_3;
01555     typedef typename K::Circle_3   Circle_3;
01556     typedef typename Sphere_3::Rep Rep;
01557   public:
01558     typedef Sphere_3               result_type;
01559 
01560     Rep // Sphere_3
01561     operator()(Return_base_tag, const Point_3& center, const FT& squared_radius,
01562                 Orientation orientation = COUNTERCLOCKWISE) const
01563     {  return Rep(center, squared_radius, orientation); }
01564 
01565     Rep // Sphere_3
01566     operator()(Return_base_tag, const Point_3& p, const Point_3& q,
01567                 const Point_3& r, const Point_3& s) const
01568     {  return Rep(p, q, r, s); }
01569 
01570     Rep // Sphere_3
01571     operator()(Return_base_tag, const Point_3& p, const Point_3& q, const Point_3& r,
01572                 Orientation orientation = COUNTERCLOCKWISE) const
01573     {  return Rep(p, q, r, orientation); }
01574 
01575     Rep // Sphere_3
01576     operator()(Return_base_tag, const Point_3& p, const Point_3& q,
01577                 Orientation orientation = COUNTERCLOCKWISE) const
01578     {  return Rep(p, q, orientation); }
01579 
01580     Rep // Sphere_3
01581     operator()(Return_base_tag, const Point_3& center,
01582                 Orientation orientation = COUNTERCLOCKWISE) const
01583     {  return Rep(center, orientation); }
01584 
01585     Rep
01586     operator() (Return_base_tag, const Circle_3 & c) const
01587     { return c.rep().diametral_sphere(); }
01588 
01589     Sphere_3
01590     operator()( const Point_3& center, const FT& squared_radius,
01591                 Orientation orientation = COUNTERCLOCKWISE) const
01592     { return this->operator()(Return_base_tag(), center, squared_radius, orientation); }
01593 
01594     Sphere_3
01595     operator()( const Point_3& p, const Point_3& q,
01596                 const Point_3& r, const Point_3& s) const
01597     { return this->operator()(Return_base_tag(), p, q, r, s); }
01598 
01599     Sphere_3
01600     operator()( const Point_3& p, const Point_3& q, const Point_3& r,
01601                 Orientation orientation = COUNTERCLOCKWISE) const
01602     { return this->operator()(Return_base_tag(), p, q, r, orientation); }
01603 
01604     Sphere_3
01605     operator()( const Point_3& p, const Point_3& q,
01606                 Orientation orientation = COUNTERCLOCKWISE) const
01607     { return this->operator()(Return_base_tag(), p, q, orientation); }
01608 
01609     Sphere_3
01610     operator()( const Point_3& center,
01611                 Orientation orientation = COUNTERCLOCKWISE) const
01612     { return this->operator()(Return_base_tag(), center, orientation); }
01613 
01614     Sphere_3
01615     operator() (const Circle_3 & c) const
01616     { return this->operator()(Return_base_tag(), c); }
01617 
01618   };
01619 
01620   template <typename K>
01621   class Construct_supporting_plane_3
01622   {
01623     typedef typename K::Triangle_3  Triangle_3;
01624     typedef typename K::Plane_3     Plane_3;
01625   public:
01626     typedef Plane_3          result_type;
01627 
01628     Plane_3
01629     operator()( const Triangle_3& t) const
01630     { return t.rep().supporting_plane(); }
01631 
01632   };
01633 
01634   template <typename K>
01635   class Construct_tetrahedron_3
01636   {
01637     typedef typename K::Tetrahedron_3   Tetrahedron_3;
01638     typedef typename K::Point_3         Point_3;
01639     typedef typename Tetrahedron_3::Rep Rep;
01640   public:
01641     typedef Tetrahedron_3    result_type;
01642 
01643     Rep // Tetrahedron_3
01644     operator()(Return_base_tag, const Point_3& p, const Point_3& q,
01645                 const Point_3& r, const Point_3& s) const
01646     { return Rep(p, q, r, s); }
01647 
01648     Tetrahedron_3
01649     operator()( const Point_3& p, const Point_3& q,
01650                 const Point_3& r, const Point_3& s) const
01651     { return this->operator()(Return_base_tag(), p, q, r, s); }
01652   };
01653 
01654   template <typename K>
01655   class Construct_triangle_2
01656   {
01657     typedef typename K::Triangle_2   Triangle_2;
01658     typedef typename Triangle_2::Rep  Rep;
01659     typedef typename K::Point_2      Point_2;
01660   public:
01661     typedef Triangle_2       result_type;
01662 
01663     Rep // Triangle_2
01664     operator()(Return_base_tag, const Point_2& p, const Point_2& q, const Point_2& r) const
01665     { return Rep(p, q, r); }
01666 
01667     Triangle_2
01668     operator()( const Point_2& p, const Point_2& q, const Point_2& r) const
01669     { return this->operator()(Return_base_tag(), p, q, r); }
01670   };
01671 
01672   template <typename K>
01673   class Construct_triangle_3
01674   {
01675     typedef typename K::Triangle_3   Triangle_3;
01676     typedef typename K::Point_3      Point_3;
01677     typedef typename Triangle_3::Rep Rep;
01678   public:
01679     typedef Triangle_3       result_type;
01680 
01681     Rep // Triangle_3
01682     operator()(Return_base_tag, const Point_3& p, const Point_3& q, const Point_3& r) const
01683     { return Rep(p, q, r); }
01684 
01685     Triangle_3
01686     operator()( const Point_3& p, const Point_3& q, const Point_3& r) const
01687     { return this->operator()(Return_base_tag(), p, q, r); }
01688   };
01689 
01690   template <typename K>
01691   class Construct_unit_normal_3
01692   {
01693     typedef typename K::Point_3          Point_3;
01694     typedef typename K::Vector_3         Vector_3;
01695   public:
01696     typedef Vector_3           result_type;
01697 
01698     Vector_3
01699     operator()(const Point_3& p,const Point_3& q, const Point_3& r) const
01700     { 
01701       CGAL_kernel_precondition(! K().collinear_3_object()(p,q,r) ); 
01702       Vector_3 res = CGAL::cross_product(q-p, r-p);
01703       res = res / CGAL::sqrt(res.squared_length());
01704       return res; 
01705         }
01706   };
01707 
01708   template <typename K>
01709   class Construct_vertex_3
01710   {
01711     typedef typename K::Point_3          Point_3;
01712     typedef typename K::Segment_3        Segment_3;
01713     typedef typename K::Iso_cuboid_3     Iso_cuboid_3;
01714     typedef typename K::Triangle_3       Triangle_3;
01715     typedef typename K::Tetrahedron_3    Tetrahedron_3;
01716   public:
01717     typedef Point_3          result_type;
01718 
01719     const Point_3 &
01720     operator()( const Segment_3& s, int i) const
01721     { return s.rep().vertex(i); }
01722 
01723     const Point_3 &
01724     operator()( const Triangle_3& t, int i) const
01725     { return t.rep().vertex(i); }
01726 
01727     Point_3
01728     operator()( const Iso_cuboid_3& r, int i) const
01729     { return r.rep().vertex(i); }
01730 
01731     const Point_3 &
01732     operator()( const Tetrahedron_3& t, int i) const
01733     { return t.rep().vertex(i); }
01734   };
01735 
01736   template <typename K>
01737   class Construct_cartesian_const_iterator_2
01738   {
01739     typedef typename K::Point_2          Point_2;
01740     typedef typename K::Vector_2         Vector_2;
01741     typedef typename K::Cartesian_const_iterator_2
01742     Cartesian_const_iterator_2;
01743 
01744   public:
01745     typedef Cartesian_const_iterator_2 result_type;
01746 
01747     Cartesian_const_iterator_2
01748     operator()( const Point_2& p) const
01749     {
01750       return p.rep().cartesian_begin();
01751     }
01752 
01753     Cartesian_const_iterator_2
01754     operator()( const Point_2& p, int) const
01755     {
01756       return p.rep().cartesian_end();
01757     }
01758 
01759     Cartesian_const_iterator_2
01760     operator()( const Vector_2& v) const
01761     {
01762       return v.rep().cartesian_begin();
01763     }
01764 
01765     Cartesian_const_iterator_2
01766     operator()( const Vector_2& v, int) const
01767     {
01768       return v.rep().cartesian_end();
01769     }
01770   };
01771 
01772   template <typename K>
01773   class Construct_cartesian_const_iterator_3
01774   {
01775     typedef typename K::Point_3          Point_3;
01776     typedef typename K::Vector_3         Vector_3;
01777     typedef typename K::Cartesian_const_iterator_3
01778     Cartesian_const_iterator_3;
01779 
01780   public:
01781     typedef Cartesian_const_iterator_3 result_type;
01782 
01783     Cartesian_const_iterator_3
01784     operator()( const Point_3& p) const
01785     {
01786       return p.rep().cartesian_begin();
01787     }
01788 
01789     Cartesian_const_iterator_3
01790     operator()( const Point_3& p, int) const
01791     {
01792       return p.rep().cartesian_end();
01793     }
01794 
01795     Cartesian_const_iterator_3
01796     operator()( const Vector_3& v) const
01797     {
01798       return v.rep().cartesian_begin();
01799     }
01800 
01801     Cartesian_const_iterator_3
01802     operator()( const Vector_3& v, int) const
01803     {
01804       return v.rep().cartesian_end();
01805     }
01806   };
01807 
01808   template <typename K>
01809   class Coplanar_3
01810   {
01811     typedef typename K::Point_3       Point_3;
01812     typedef typename K::Orientation_3 Orientation_3;
01813     Orientation_3 o;
01814   public:
01815     typedef typename K::Boolean       result_type;
01816 
01817     Coplanar_3() {}
01818     Coplanar_3(const Orientation_3& o_) : o(o_) {}
01819 
01820     result_type
01821     operator()( const Point_3& p, const Point_3& q,
01822                 const Point_3& r, const Point_3& s) const
01823     {
01824       return o(p, q, r, s) == COPLANAR;
01825     }
01826   };
01827 
01828   template <typename K>
01829   class Counterclockwise_in_between_2
01830   {
01831     typedef typename K::Direction_2  Direction_2;
01832   public:
01833     typedef typename K::Boolean      result_type;
01834 
01835     result_type
01836     operator()( const Direction_2& p, const Direction_2& q,
01837                 const Direction_2& r) const
01838     {
01839         if ( q < p)
01840             return ( p < r )||( r <= q );
01841         else
01842             return ( p < r )&&( r <= q );
01843     }
01844   };
01845 
01846   template <typename K>
01847   class Do_intersect_2
01848   {
01849   public:
01850     typedef typename K::Boolean     result_type;
01851 
01852     // There are 36 combinaisons, so I use a template.
01853     template <class T1, class T2>
01854     result_type
01855     operator()(const T1& t1, const T2& t2) const
01856     { return CGALi::do_intersect(t1, t2, K()); }
01857   };
01858 
01859   template <typename K>
01860   class Do_intersect_3
01861   {
01862   public:
01863     typedef typename K::Boolean     result_type;
01864 
01865     // There are x combinaisons, so I use a template.
01866     template <class T1, class T2>
01867     result_type
01868     operator()(const T1& t1, const T2& t2) const
01869     { return CGALi::do_intersect(t1, t2, K()); }
01870   };
01871 
01872   template <typename K>
01873   class Equal_2
01874   {
01875     typedef typename K::Point_2       Point_2;
01876     typedef typename K::Vector_2      Vector_2;
01877     typedef typename K::Direction_2   Direction_2;
01878     typedef typename K::Segment_2     Segment_2;
01879     typedef typename K::Ray_2         Ray_2;
01880     typedef typename K::Line_2        Line_2;
01881     typedef typename K::Triangle_2    Triangle_2;
01882     typedef typename K::Iso_rectangle_2 Iso_rectangle_2;
01883     typedef typename K::Circle_2      Circle_2;
01884 
01885   public:
01886     typedef typename K::Boolean       result_type;
01887 
01888     result_type
01889     operator()(const Point_2 &p, const Point_2 &q) const
01890     {
01891       return p.rep() == q.rep();
01892     }
01893 
01894     result_type
01895     operator()(const Vector_2 &v1, const Vector_2 &v2) const
01896     {
01897       return v1.rep() == v2.rep();
01898     }
01899 
01900     result_type
01901     operator()(const Vector_2 &v, const Null_vector &n) const
01902     {
01903       return v.rep() == n;
01904     }
01905 
01906     result_type
01907     operator()(const Direction_2 &d1, const Direction_2 &d2) const
01908     {
01909       return d1.rep() == d2.rep();
01910     }
01911 
01912     result_type
01913     operator()(const Segment_2 &s1, const Segment_2 &s2) const
01914     {
01915       return s1.source() == s2.source() && s1.target() == s2.target();
01916     }
01917 
01918     result_type
01919     operator()(const Line_2 &l1, const Line_2 &l2) const
01920     {
01921       return l1.rep() == l2.rep();
01922     }
01923 
01924     result_type
01925     operator()(const Ray_2& r1, const Ray_2& r2) const
01926     {
01927       return r1.source() == r2.source() && r1.direction() == r2.direction();
01928     }
01929 
01930     result_type
01931     operator()(const Circle_2& c1, const Circle_2& c2) const
01932     {
01933       return c1.center() == c2.center() &&
01934         c1.squared_radius() == c2.squared_radius() &&
01935         c1.orientation() == c2.orientation();
01936     }
01937 
01938     result_type
01939     operator()(const Triangle_2& t1, const Triangle_2& t2) const
01940     {
01941       int i;
01942       for(i=0; i<3; i++)
01943         if ( t1.vertex(0) == t2.vertex(i) )
01944           break;
01945 
01946       return (i<3) && t1.vertex(1) == t2.vertex(i+1)
01947                    && t1.vertex(2) == t2.vertex(i+2);
01948     }
01949 
01950     result_type
01951     operator()(const Iso_rectangle_2& i1, const Iso_rectangle_2& i2) const
01952     {
01953       return ((i1.min)() == (i2.min)()) && ((i1.max)() == (i2.max)());
01954     }
01955   };
01956 
01957   template <typename K>
01958   class Equal_3
01959   {
01960     typedef typename K::Point_3       Point_3;
01961     typedef typename K::Vector_3      Vector_3;
01962     typedef typename K::Direction_3   Direction_3;
01963     typedef typename K::Segment_3     Segment_3;
01964     typedef typename K::Line_3        Line_3;
01965     typedef typename K::Ray_3         Ray_3;
01966     typedef typename K::Triangle_3    Triangle_3;
01967     typedef typename K::Tetrahedron_3 Tetrahedron_3;
01968     typedef typename K::Sphere_3      Sphere_3;
01969     typedef typename K::Iso_cuboid_3  Iso_cuboid_3;
01970     typedef typename K::Plane_3       Plane_3;
01971     typedef typename K::Circle_3      Circle_3;
01972 
01973   public:
01974     typedef typename K::Boolean       result_type;
01975 
01976     // Point_3 is special case since the global operator== would recurse.
01977     result_type
01978     operator()(const Point_3 &p, const Point_3 &q) const
01979     {
01980       return p.x() == q.x() && p.y() == q.y() && p.z() == q.z();
01981     }
01982 
01983     result_type
01984     operator()(const Plane_3 &v1, const Plane_3 &v2) const
01985     {
01986       return v1.rep() == v2.rep();
01987     }
01988 
01989     result_type
01990     operator()(const Iso_cuboid_3 &v1, const Iso_cuboid_3 &v2) const
01991     {
01992       return v1.rep() == v2.rep();
01993     }
01994 
01995     result_type
01996     operator()(const Sphere_3 &v1, const Sphere_3 &v2) const
01997     {
01998       return v1.rep() == v2.rep();
01999     }
02000 
02001     result_type
02002     operator()(const Tetrahedron_3 &v1, const Tetrahedron_3 &v2) const
02003     {
02004       return v1.rep() == v2.rep();
02005     }
02006 
02007     result_type
02008     operator()(const Triangle_3 &v1, const Triangle_3 &v2) const
02009     {
02010       return v1.rep() == v2.rep();
02011     }
02012 
02013     result_type
02014     operator()(const Ray_3 &v1, const Ray_3 &v2) const
02015     {
02016       return v1.rep() == v2.rep();
02017     }
02018 
02019     result_type
02020     operator()(const Line_3 &v1, const Line_3 &v2) const
02021     {
02022       return v1.rep() == v2.rep();
02023     }
02024 
02025     result_type
02026     operator()(const Direction_3 &v1, const Direction_3 &v2) const
02027     {
02028       return v1.rep() == v2.rep();
02029     }
02030 
02031     result_type
02032     operator()(const Segment_3 &v1, const Segment_3 &v2) const
02033     {
02034       return v1.rep() == v2.rep();
02035     }
02036 
02037     result_type
02038     operator()(const Vector_3 &v1, const Vector_3 &v2) const
02039     {
02040       return v1.rep() == v2.rep();
02041     }
02042 
02043     result_type
02044     operator()(const Vector_3 &v, const Null_vector &n) const
02045     {
02046       return v.rep() == n;
02047     }
02048 
02049     result_type
02050     operator()(const Circle_3 &v1, const Circle_3 &v2) const
02051     {
02052       return v1.rep() == v2.rep();
02053     }
02054   };
02055 
02056   template <typename K>
02057   class Has_on_boundary_2
02058   {
02059     typedef typename K::Point_2          Point_2;
02060     typedef typename K::Iso_rectangle_2  Iso_rectangle_2;
02061     typedef typename K::Circle_2         Circle_2;
02062     typedef typename K::Triangle_2       Triangle_2;
02063   public:
02064     typedef typename K::Boolean          result_type;
02065 
02066     result_type
02067     operator()( const Circle_2& c, const Point_2& p) const
02068     { return c.has_on_boundary(p); }
02069 
02070     result_type
02071     operator()( const Triangle_2& t, const Point_2& p) const
02072     { return t.has_on_boundary(p); }
02073 
02074     result_type
02075     operator()( const Iso_rectangle_2& r, const Point_2& p) const
02076     { return K().bounded_side_2_object()(r,p) == ON_BOUNDARY; }
02077   };
02078 
02079   template <typename K>
02080   class Has_on_boundary_3
02081   {
02082     typedef typename K::Point_3          Point_3;
02083     typedef typename K::Iso_cuboid_3     Iso_cuboid_3;
02084     typedef typename K::Sphere_3         Sphere_3;
02085     typedef typename K::Tetrahedron_3    Tetrahedron_3;
02086     typedef typename K::Plane_3          Plane_3;
02087   public:
02088     typedef typename K::Boolean          result_type;
02089 
02090     result_type
02091     operator()( const Sphere_3& s, const Point_3& p) const
02092     { return s.rep().has_on_boundary(p); }
02093 
02094     result_type
02095     operator()( const Tetrahedron_3& t, const Point_3& p) const
02096     { return t.rep().has_on_boundary(p); }
02097 
02098     result_type
02099     operator()( const Iso_cuboid_3& c, const Point_3& p) const
02100     { return c.rep().has_on_boundary(p); }
02101 
02102   };
02103 
02104   template <typename K>
02105   class Has_on_bounded_side_2
02106   {
02107     typedef typename K::Point_2          Point_2;
02108     typedef typename K::Iso_rectangle_2  Iso_rectangle_2;
02109     typedef typename K::Circle_2         Circle_2;
02110     typedef typename K::Triangle_2       Triangle_2;
02111   public:
02112     typedef typename K::Boolean          result_type;
02113 
02114     result_type
02115     operator()( const Circle_2& c, const Point_2& p) const
02116     { return c.has_on_bounded_side(p); }
02117 
02118     result_type
02119     operator()( const Triangle_2& t, const Point_2& p) const
02120     { return t.has_on_bounded_side(p); }
02121 
02122     result_type
02123     operator()( const Iso_rectangle_2& r, const Point_2& p) const
02124     { return K().bounded_side_2_object()(r,p) == ON_BOUNDED_SIDE; }
02125   };
02126 
02127   template <typename K>
02128   class Has_on_bounded_side_3
02129   {
02130     typedef typename K::Point_3          Point_3;
02131     typedef typename K::Iso_cuboid_3     Iso_cuboid_3;
02132     typedef typename K::Sphere_3         Sphere_3;
02133     typedef typename K::Tetrahedron_3    Tetrahedron_3;
02134     typedef typename K::Circle_3         Circle_3;
02135   public:
02136     typedef typename K::Boolean          result_type;
02137 
02138     result_type
02139     operator()( const Sphere_3& s, const Point_3& p) const
02140     { return s.has_on_bounded_side(p); }
02141 
02142     result_type
02143     operator()( const Tetrahedron_3& t, const Point_3& p) const
02144     { return t.rep().has_on_bounded_side(p); }
02145 
02146     result_type
02147     operator()( const Iso_cuboid_3& c, const Point_3& p) const
02148     { return c.rep().has_on_bounded_side(p); }
02149 
02150     result_type
02151     operator()(const Circle_3& c, const Point_3& p) const
02152     {
02153       CGAL_kernel_precondition(
02154         K().has_on_3_object()(c.supporting_plane(),p)
02155       );
02156       return c.rep().has_on_bounded_side(p); 
02157     }
02158   };
02159 
02160   template <typename K>
02161   class Has_on_negative_side_2
02162   {
02163     typedef typename K::Point_2          Point_2;
02164     typedef typename K::Line_2           Line_2;
02165     typedef typename K::Circle_2         Circle_2;
02166     typedef typename K::Triangle_2       Triangle_2;
02167   public:
02168     typedef typename K::Boolean          result_type;
02169 
02170     result_type
02171     operator()( const Circle_2& c, const Point_2& p) const
02172     { return c.has_on_negative_side(p); }
02173 
02174     result_type
02175     operator()( const Triangle_2& t, const Point_2& p) const
02176     { return t.has_on_negative_side(p); }
02177 
02178     result_type
02179     operator()( const Line_2& l, const Point_2& p) const
02180     { return l.has_on_negative_side(p); }
02181   };
02182 
02183   template <typename K>
02184   class Has_on_negative_side_3
02185   {
02186     typedef typename K::Point_3          Point_3;
02187     typedef typename K::Plane_3          Plane_3;
02188     typedef typename K::Sphere_3         Sphere_3;
02189     typedef typename K::Tetrahedron_3    Tetrahedron_3;
02190   public:
02191     typedef typename K::Boolean          result_type;
02192 
02193     result_type
02194     operator()( const Sphere_3& s, const Point_3& p) const
02195     { return s.has_on_negative_side(p); }
02196 
02197     result_type
02198     operator()( const Tetrahedron_3& t, const Point_3& p) const
02199     { return t.rep().has_on_negative_side(p); }
02200 
02201     result_type
02202     operator()( const Plane_3& pl, const Point_3& p) const
02203     { return pl.rep().has_on_negative_side(p); }
02204   };
02205 
02206   template <typename K>
02207   class Has_on_positive_side_2
02208   {
02209     typedef typename K::Point_2          Point_2;
02210     typedef typename K::Line_2           Line_2;
02211     typedef typename K::Circle_2         Circle_2;
02212     typedef typename K::Triangle_2       Triangle_2;
02213   public:
02214     typedef typename K::Boolean          result_type;
02215 
02216     result_type
02217     operator()( const Circle_2& c, const Point_2& p) const
02218     { return c.has_on_positive_side(p); }
02219 
02220     result_type
02221     operator()( const Triangle_2& t, const Point_2& p) const
02222     { return t.has_on_positive_side(p); }
02223 
02224     result_type
02225     operator()( const Line_2& l, const Point_2& p) const
02226     { return l.has_on_positive_side(p); }
02227   };
02228 
02229   template <typename K>
02230   class Has_on_positive_side_3
02231   {
02232     typedef typename K::Point_3          Point_3;
02233     typedef typename K::Plane_3          Plane_3;
02234     typedef typename K::Sphere_3         Sphere_3;
02235     typedef typename K::Tetrahedron_3    Tetrahedron_3;
02236   public:
02237     typedef typename K::Boolean          result_type;
02238 
02239     result_type
02240     operator()( const Sphere_3& s, const Point_3& p) const
02241     { return s.has_on_positive_side(p); }
02242 
02243     result_type
02244     operator()( const Tetrahedron_3& t, const Point_3& p) const
02245     { return t.rep().has_on_positive_side(p); }
02246 
02247     result_type
02248     operator()( const Plane_3& pl, const Point_3& p) const
02249     { return pl.rep().has_on_positive_side(p); }
02250   };
02251 
02252   template <typename K>
02253   class Has_on_unbounded_side_2
02254   {
02255     typedef typename K::Point_2          Point_2;
02256     typedef typename K::Iso_rectangle_2  Iso_rectangle_2;
02257     typedef typename K::Circle_2         Circle_2;
02258     typedef typename K::Triangle_2       Triangle_2;
02259   public:
02260     typedef typename K::Boolean          result_type;
02261 
02262     result_type
02263     operator()( const Circle_2& c, const Point_2& p) const
02264     { return c.has_on_unbounded_side(p); }
02265 
02266     result_type
02267     operator()( const Triangle_2& t, const Point_2& p) const
02268     { return t.has_on_unbounded_side(p); }
02269 
02270     result_type
02271     operator()( const Iso_rectangle_2& r, const Point_2& p) const
02272     {
02273       return K().bounded_side_2_object()(r,p)== ON_UNBOUNDED_SIDE;
02274     }
02275 
02276   };
02277 
02278   template <typename K>
02279   class Has_on_unbounded_side_3
02280   {
02281     typedef typename K::Point_3          Point_3;
02282     typedef typename K::Iso_cuboid_3     Iso_cuboid_3;
02283     typedef typename K::Sphere_3         Sphere_3;
02284     typedef typename K::Circle_3         Circle_3;
02285     typedef typename K::Tetrahedron_3    Tetrahedron_3;
02286   public:
02287     typedef typename K::Boolean          result_type;
02288 
02289     result_type
02290     operator()( const Sphere_3& s, const Point_3& p) const
02291     { return s.has_on_unbounded_side(p); }
02292 
02293     result_type
02294     operator()( const Tetrahedron_3& t, const Point_3& p) const
02295     { return t.rep().has_on_unbounded_side(p); }
02296 
02297     result_type
02298     operator()( const Iso_cuboid_3& c, const Point_3& p) const
02299     { return c.rep().has_on_unbounded_side(p); }
02300 
02301     result_type
02302     operator()(const Circle_3& c, const Point_3& p) const
02303     {
02304       CGAL_kernel_precondition(
02305         K().has_on_3_object()(c.supporting_plane(),p)
02306       );
02307       return c.rep().has_on_unbounded_side(p); 
02308     }
02309   };
02310 
02311   template <typename K>
02312   class Has_on_2
02313   {
02314     typedef typename K::Point_2          Point_2;
02315     typedef typename K::Line_2           Line_2;
02316     typedef typename K::Ray_2            Ray_2;
02317     typedef typename K::Segment_2        Segment_2;
02318   public:
02319     typedef typename K::Boolean          result_type;
02320 
02321     result_type
02322     operator()( const Line_2& l, const Point_2& p) const
02323     { return l.has_on(p); }
02324 
02325     result_type
02326     operator()( const Ray_2& r, const Point_2& p) const
02327     { return r.has_on(p); }
02328 
02329     result_type
02330     operator()( const Segment_2& s, const Point_2& p) const
02331     { return s.has_on(p); }
02332   };
02333 
02334   template <typename K>
02335   class Intersect_2
02336   {
02337     typedef typename K::Object_2    Object_2;
02338   public:
02339     typedef Object_2                result_type;
02340 
02341     // 25 possibilities, so I keep the template.
02342     template <class T1, class T2>
02343     Object_2
02344     operator()(const T1& t1, const T2& t2) const
02345     { return CGALi::intersection(t1, t2, K()); }
02346   };
02347 
02348   template <typename K>
02349   class Intersect_3
02350   {
02351     typedef typename K::Object_3    Object_3;
02352     typedef typename K::Plane_3     Plane_3;
02353   public:
02354     typedef Object_3                result_type;
02355 
02356     // n possibilities, so I keep the template.
02357     template <class T1, class T2>
02358     Object_3
02359     operator()(const T1& t1, const T2& t2) const
02360     { return CGALi::intersection(t1, t2, K() ); }
02361 
02362     Object_3
02363     operator()(const Plane_3& pl1, const Plane_3& pl2, const Plane_3& pl3)const
02364     { return CGALi::intersection(pl1, pl2, pl3, K() ); }
02365   };
02366 
02367   template <typename K>
02368   class Is_degenerate_2
02369   {
02370     typedef typename K::Circle_2          Circle_2;
02371     typedef typename K::Iso_rectangle_2   Iso_rectangle_2;
02372     typedef typename K::Line_2            Line_2;
02373     typedef typename K::Ray_2             Ray_2;
02374     typedef typename K::Segment_2         Segment_2;
02375     typedef typename K::Triangle_2        Triangle_2;
02376     typedef typename K::Circle_3          Circle_3;
02377   public:
02378     typedef typename K::Boolean           result_type;
02379 
02380     result_type
02381     operator()( const Circle_2& c) const
02382     { return c.is_degenerate(); }
02383 
02384     result_type
02385     operator()( const Iso_rectangle_2& r) const
02386     { return (r.xmin() == r.xmax()) || (r.ymin() == r.ymax()); }
02387 
02388     result_type
02389     operator()( const Line_2& l) const
02390     { return CGAL_NTS is_zero(l.a())  && CGAL_NTS is_zero(l.b()); }
02391 
02392     result_type
02393     operator()( const Ray_2& r) const
02394     { return r.rep().is_degenerate(); }
02395 
02396     result_type
02397     operator()( const Segment_2& s) const
02398     { return s.source() == s.target(); }
02399 
02400     result_type
02401     operator()( const Triangle_2& t) const
02402     { return t.is_degenerate(); }
02403 
02404     result_type
02405     operator()( const Circle_3& c) const
02406     { return c.rep().is_degenerate(); }
02407   };
02408 
02409   template <typename K>
02410   class Is_degenerate_3
02411   {
02412     typedef typename K::Iso_cuboid_3      Iso_cuboid_3;
02413     typedef typename K::Line_3            Line_3;
02414     typedef typename K::Circle_3          Circle_3;
02415     typedef typename K::Plane_3           Plane_3;
02416     typedef typename K::Ray_3             Ray_3;
02417     typedef typename K::Segment_3         Segment_3;
02418     typedef typename K::Sphere_3          Sphere_3;
02419     typedef typename K::Triangle_3        Triangle_3;
02420     typedef typename K::Tetrahedron_3     Tetrahedron_3;
02421   public:
02422     typedef typename K::Boolean           result_type;
02423 
02424     result_type
02425     operator()( const Iso_cuboid_3& c) const
02426     { return c.rep().is_degenerate(); }
02427 
02428     result_type
02429     operator()( const Line_3& l) const
02430     { return l.rep().is_degenerate();  }
02431 
02432     result_type
02433     operator()( const Plane_3& pl) const
02434     { return pl.rep().is_degenerate(); }
02435 
02436     result_type
02437     operator()( const Ray_3& r) const
02438     { return r.rep().is_degenerate(); }
02439 
02440     result_type
02441     operator()( const Segment_3& s) const
02442     { return s.rep().is_degenerate(); }
02443 
02444     result_type
02445     operator()( const Sphere_3& s) const
02446     { return s.rep().is_degenerate(); }
02447 
02448     result_type
02449     operator()( const Triangle_3& t) const
02450     { return t.rep().is_degenerate(); }
02451 
02452     result_type
02453     operator()( const Tetrahedron_3& t) const
02454     { return t.rep().is_degenerate(); }
02455 
02456     result_type
02457     operator()( const Circle_3& t) const
02458     { return t.rep().is_degenerate(); }
02459 
02460   };
02461 
02462   template <typename K>
02463   class Is_horizontal_2
02464   {
02465     typedef typename K::Line_2    Line_2;
02466     typedef typename K::Segment_2 Segment_2;
02467     typedef typename K::Ray_2     Ray_2;
02468   public:
02469     typedef typename K::Boolean   result_type;
02470 
02471     result_type
02472     operator()( const Line_2& l) const
02473     { return CGAL_NTS is_zero(l.a()); }
02474 
02475     result_type
02476     operator()( const Segment_2& s) const
02477     { return s.is_horizontal(); }
02478 
02479     result_type
02480     operator()( const Ray_2& r) const
02481     { return r.is_horizontal(); }
02482   };
02483 
02484   template <typename K>
02485   class Is_vertical_2
02486   {
02487     typedef typename K::Line_2    Line_2;
02488     typedef typename K::Segment_2 Segment_2;
02489     typedef typename K::Ray_2     Ray_2;
02490   public:
02491     typedef typename K::Boolean   result_type;
02492 
02493     result_type
02494     operator()( const Line_2& l) const
02495     { return CGAL_NTS is_zero(l.b()); }
02496 
02497     result_type
02498     operator()( const Segment_2& s) const
02499     { return s.is_vertical(); }
02500 
02501     result_type
02502     operator()( const Ray_2& r) const
02503     { return r.is_vertical(); }
02504   };
02505 
02506   template <typename K>
02507   class Left_turn_2
02508   {
02509     typedef typename K::Point_2        Point_2;
02510     typedef typename K::Orientation_2  Orientation_2;
02511     Orientation_2 o;
02512   public:
02513     typedef typename K::Boolean        result_type;
02514 
02515     Left_turn_2() {}
02516     Left_turn_2(const Orientation_2& o_) : o(o_) {}
02517 
02518     result_type
02519     operator()(const Point_2& p, const Point_2& q, const Point_2& r) const
02520     { return o(p, q, r) == LEFT_TURN; }
02521   };
02522 
02523   template <typename K>
02524   class Less_rotate_ccw_2
02525   {
02526     typedef typename K::Point_2        Point_2;
02527     typedef typename K::Orientation_2  Orientation_2;
02528     typedef typename K::Collinear_are_ordered_along_line_2
02529     Collinear_are_ordered_along_line_2;
02530     Orientation_2 o;
02531     Collinear_are_ordered_along_line_2 co;
02532   public:
02533     typedef typename K::Boolean        result_type;
02534 
02535     Less_rotate_ccw_2() {}
02536     Less_rotate_ccw_2(const Orientation_2& o_,
02537                       const Collinear_are_ordered_along_line_2& co_)
02538       : o(o_), co(co_)
02539     {}
02540 
02541     result_type
02542     operator()(const Point_2& r, const Point_2& p, const Point_2& q) const
02543     {
02544       typename K::Orientation ori = o(r, p, q);
02545       if ( ori == LEFT_TURN )
02546         return true;
02547       else if ( ori == RIGHT_TURN )
02548         return false;
02549       else
02550         {
02551           if (p == r) return false;
02552           if (q == r) return true;
02553           if (p == q) return false;
02554           return co( r, q, p);
02555         }
02556     }
02557   };
02558 
02559   template <typename K>
02560   class Oriented_side_3
02561   {
02562     typedef typename K::Point_3        Point_3;
02563     typedef typename K::Tetrahedron_3  Tetrahedron_3;
02564     typedef typename K::Plane_3        Plane_3;
02565     typedef typename K::Sphere_3       Sphere_3;
02566   public:
02567     typedef typename K::Oriented_side  result_type;
02568 
02569     result_type
02570     operator()( const Sphere_3& s, const Point_3& p) const
02571     { return s.rep().oriented_side(p); }
02572 
02573     result_type
02574     operator()( const Plane_3& pl, const Point_3& p) const
02575     { return pl.rep().oriented_side(p); }
02576 
02577     result_type
02578     operator()( const Tetrahedron_3& t, const Point_3& p) const
02579     { return t.rep().oriented_side(p); }
02580   };
02581 
02582 } // namespace CommonKernelFunctors
02583 
02584 CGAL_END_NAMESPACE
02585 
02586 #endif // CGAL_KERNEL_FUNCTION_OBJECTS_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines