BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Arr_conic_traits_2.h
Go to the documentation of this file.
00001 // Copyright (c) 2005  Tel-Aviv University (Israel).
00002 // All rights reserved.
00003 //
00004 // This file is part of CGAL (www.cgal.org); you may redistribute it under
00005 // the terms of the Q Public License version 1.0.
00006 // See the file LICENSE.QPL distributed with CGAL.
00007 //
00008 // Licensees holding a valid commercial license may use this file in
00009 // accordance with the commercial license agreement provided with the software.
00010 //
00011 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00012 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00013 //
00014 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Arrangement_on_surface_2/include/CGAL/Arr_conic_traits_2.h $
00015 // $Id: Arr_conic_traits_2.h 50366 2009-07-05 12:56:48Z efif $
00016 // 
00017 //
00018 // Author(s)     : Ron Wein          <wein@post.tau.ac.il>
00019 
00020 #ifndef CGAL_ARR_CONIC_TRAITS_2_H
00021 #define CGAL_ARR_CONIC_TRAITS_2_H
00022 
00027 #include <CGAL/tags.h>
00028 #include <CGAL/Arr_tags.h>
00029 #include <CGAL/Arr_geometry_traits/Conic_arc_2.h>
00030 #include <CGAL/Arr_geometry_traits/Conic_x_monotone_arc_2.h>
00031 #include <CGAL/Arr_geometry_traits/Conic_point_2.h>
00032 
00033 #include <fstream>
00034 
00035 CGAL_BEGIN_NAMESPACE
00036 
00050 template <class Rat_kernel_, class Alg_kernel_, class Nt_traits_>
00051 class Arr_conic_traits_2 
00052 {
00053 public:
00054 
00055   typedef Rat_kernel_                     Rat_kernel;
00056   typedef Alg_kernel_                     Alg_kernel;
00057   typedef Nt_traits_                      Nt_traits;
00058 
00059   typedef typename Rat_kernel::FT         Rational;
00060   typedef typename Rat_kernel::Point_2    Rat_point_2;
00061   typedef typename Rat_kernel::Segment_2  Rat_segment_2;
00062   typedef typename Rat_kernel::Line_2     Rat_line_2;
00063   typedef typename Rat_kernel::Circle_2   Rat_circle_2;
00064 
00065   typedef typename Alg_kernel::FT         Algebraic;
00066 
00067   typedef typename Nt_traits::Integer     Integer;
00068 
00069   typedef Arr_conic_traits_2<Rat_kernel, Alg_kernel, Nt_traits>  Self;
00070 
00071   // Category tags:
00072   typedef Tag_true                        Has_left_category;
00073   typedef Tag_true                        Has_merge_category;
00074 
00075   typedef Arr_oblivious_side_tag          Arr_left_side_tag;
00076   typedef Arr_oblivious_side_tag          Arr_bottom_side_tag;
00077   typedef Arr_oblivious_side_tag          Arr_top_side_tag;
00078   typedef Arr_oblivious_side_tag          Arr_right_side_tag;
00079 
00080   // Traits objects:
00081   typedef _Conic_arc_2<Rat_kernel, Alg_kernel, Nt_traits> Curve_2;
00082   typedef _Conic_x_monotone_arc_2<Curve_2>                X_monotone_curve_2;
00083   typedef _Conic_point_2<Alg_kernel>                      Point_2;
00084   typedef unsigned int                                    Multiplicity;
00085 
00086 private:
00087 
00088   // Type definition for the intersection points mapping.
00089   typedef typename X_monotone_curve_2::Conic_id           Conic_id;
00090   typedef typename X_monotone_curve_2::Intersection_point_2
00091                                                           Intersection_point_2;
00092   typedef typename X_monotone_curve_2::Intersection_map   Intersection_map;
00093 
00094   mutable Intersection_map  inter_map;  // Mapping conic pairs to their
00095                                         // intersection points.
00096 
00097 public:
00098 
00102   Arr_conic_traits_2 ()
00103   {}
00104 
00106   static unsigned int get_index () 
00107   {
00108     static unsigned int index = 0;
00109     return (++index);
00110   }
00111 
00113 
00114 
00115   class Compare_x_2
00116   {
00117   public:
00126     Comparison_result operator() (const Point_2 & p1, const Point_2 & p2) const
00127     {
00128       Alg_kernel   ker;
00129       return (ker.compare_x_2_object() (p1, p2));
00130     }
00131   };
00132 
00134   Compare_x_2 compare_x_2_object () const
00135   {
00136     return Compare_x_2();
00137   }
00138 
00139   class Compare_xy_2
00140   {
00141   public:
00150     Comparison_result operator() (const Point_2& p1, const Point_2& p2) const
00151     {
00152       Alg_kernel   ker;
00153       return (ker.compare_xy_2_object() (p1, p2));
00154     }
00155   };
00156 
00158   Compare_xy_2 compare_xy_2_object () const
00159   {
00160     return Compare_xy_2();
00161   }
00162 
00163   class Construct_min_vertex_2
00164   {
00165   public:
00171     const Point_2& operator() (const X_monotone_curve_2 & cv) const
00172     {
00173       return (cv.left());
00174     }
00175   };
00176 
00178   Construct_min_vertex_2 construct_min_vertex_2_object () const
00179   {
00180     return Construct_min_vertex_2();
00181   }
00182 
00183   class Construct_max_vertex_2
00184   {
00185   public:
00191     const Point_2& operator() (const X_monotone_curve_2 & cv) const
00192     {
00193       return (cv.right());
00194     }
00195   };
00196 
00198   Construct_max_vertex_2 construct_max_vertex_2_object () const
00199   {
00200     return Construct_max_vertex_2();
00201   }
00202 
00203   class Is_vertical_2
00204   {
00205   public:
00211     bool operator() (const X_monotone_curve_2& cv) const
00212     {
00213       return (cv.is_vertical());
00214     }
00215   };
00216 
00218   Is_vertical_2 is_vertical_2_object () const
00219   {
00220     return Is_vertical_2();
00221   }
00222 
00223   class Compare_y_at_x_2
00224   {
00225   public:
00235     Comparison_result operator() (const Point_2 & p,
00236                                   const X_monotone_curve_2 & cv) const
00237     {
00238       Alg_kernel   ker;
00239 
00240       if (cv.is_vertical())
00241       {
00242         // A special treatment for vertical segments:
00243         // In case p has the same x c-ordinate of the vertical segment, compare
00244         // it to the segment endpoints to determine its position.
00245         Comparison_result res1 = ker.compare_y_2_object() (p, cv.left());
00246         Comparison_result res2 = ker.compare_y_2_object() (p, cv.right());
00247 
00248         if (res1 == res2)
00249           return (res1);
00250         else
00251           return (EQUAL);
00252       }
00253 
00254       // Check whether the point is exactly on the curve.
00255       if (cv.contains_point(p))
00256         return (EQUAL);
00257 
00258       // Get a point q on the x-monotone arc with the same x coordinate as p.
00259       Comparison_result  x_res; 
00260       Point_2            q;
00261 
00262       if ((x_res = ker.compare_x_2_object() (p, cv.left())) == EQUAL)
00263       {
00264         q = cv.left();
00265       }
00266       else
00267       {
00268         CGAL_precondition (x_res != SMALLER);
00269 
00270         if ((x_res = ker.compare_x_2_object() (p, cv.right())) == EQUAL)
00271         {
00272           q = cv.right();
00273         }
00274         else
00275         {
00276           CGAL_precondition (x_res != LARGER);
00277 
00278           q = cv.point_at_x (p);
00279         }
00280       }
00281 
00282       // Compare p with the a point of the curve with the same x coordinate.
00283       return (ker.compare_y_2_object() (p, q));
00284     }
00285   };
00286 
00288   Compare_y_at_x_2 compare_y_at_x_2_object () const
00289   {
00290     return Compare_y_at_x_2();
00291   }
00292 
00293   class Compare_y_at_x_left_2
00294   {
00295   public:
00307     Comparison_result operator() (const X_monotone_curve_2& cv1,
00308                                   const X_monotone_curve_2& cv2,
00309                                   const Point_2& p) const
00310     {
00311       // Make sure that p lies on both curves, and that both are defined to its
00312       // left (so their left endpoint is lexicographically smaller than p).
00313       CGAL_precondition (cv1.contains_point (p) &&
00314                          cv2.contains_point (p));
00315 
00316       CGAL_precondition_code (
00317         Alg_kernel   ker;
00318       );
00319       CGAL_precondition (ker.compare_xy_2_object() (p, 
00320                                                     cv1.left()) == LARGER &&
00321                          ker.compare_xy_2_object() (p,
00322                                                     cv2.left()) == LARGER);
00323 
00324       // If one of the curves is vertical, it is below the other one.
00325       if (cv1.is_vertical())
00326       {
00327         if (cv2.is_vertical())
00328           // Both are vertical:
00329           return (EQUAL);
00330         else
00331           return (SMALLER);
00332       }
00333       else if (cv2.is_vertical())
00334       {
00335         return (LARGER);
00336       }
00337 
00338       // Compare the two curves immediately to the left of p:
00339       return (cv1.compare_to_left (cv2, p));
00340     }
00341   };
00342 
00344   Compare_y_at_x_left_2 compare_y_at_x_left_2_object () const
00345   {
00346     return Compare_y_at_x_left_2();
00347   }
00348 
00349   class Compare_y_at_x_right_2
00350   {
00351   public:
00363     Comparison_result operator() (const X_monotone_curve_2& cv1,
00364                                   const X_monotone_curve_2& cv2,
00365                                   const Point_2& p) const
00366     {
00367       // Make sure that p lies on both curves, and that both are defined to its
00368       // left (so their left endpoint is lexicographically smaller than p).
00369       CGAL_precondition (cv1.contains_point (p) &&
00370                          cv2.contains_point (p));
00371 
00372       CGAL_precondition_code (
00373         Alg_kernel   ker;
00374       );
00375 
00376       CGAL_precondition (ker.compare_xy_2_object() (p, 
00377                                                     cv1.right()) == SMALLER &&
00378                          ker.compare_xy_2_object() (p,
00379                                                     cv2.right()) == SMALLER);
00380 
00381       // If one of the curves is vertical, it is above the other one.
00382       if (cv1.is_vertical())
00383       {
00384         if (cv2.is_vertical())
00385           // Both are vertical:
00386           return (EQUAL);
00387         else
00388           return (LARGER);
00389       }
00390       else if (cv2.is_vertical())
00391       {
00392         return (SMALLER);
00393       }
00394 
00395       // Compare the two curves immediately to the right of p:
00396       return (cv1.compare_to_right (cv2, p));
00397     }
00398   };
00399 
00401   Compare_y_at_x_right_2 compare_y_at_x_right_2_object () const
00402   {
00403     return Compare_y_at_x_right_2();
00404   }
00405 
00406   class Equal_2
00407   {
00408   public:
00415     bool operator() (const X_monotone_curve_2& cv1,
00416                      const X_monotone_curve_2& cv2) const
00417     {
00418       if (&cv1 == &cv2)
00419         return (true);
00420 
00421       return (cv1.equals (cv2));
00422     }
00423 
00430     bool operator() (const Point_2& p1, const Point_2& p2) const
00431     {
00432       if (&p1 == &p2)
00433         return (true);
00434 
00435       Alg_kernel   ker;
00436       return (ker.compare_xy_2_object() (p1, p2) == EQUAL);
00437     }
00438   };
00439 
00441   Equal_2 equal_2_object () const
00442   {
00443     return Equal_2();
00444   }
00446 
00448 
00449 
00450   class Make_x_monotone_2
00451   {
00452     typedef Arr_conic_traits_2 <Rat_kernel_, Alg_kernel_, Nt_traits_>    Self;
00453   public:
00454 
00463     template<class OutputIterator>
00464     OutputIterator operator() (const Curve_2& cv, OutputIterator oi) const
00465     {
00466       // Increment the serial number of the curve cv, which will serve as its
00467       // unique identifier.
00468       unsigned int  index = Self::get_index();
00469       Conic_id      conic_id (index);
00470       
00471       // Find the points of vertical tangency to cv and act accordingly.
00472       typename Curve_2::Point_2  vtan_ps[2];
00473       int                        n_vtan_ps;
00474 
00475       n_vtan_ps = cv.vertical_tangency_points (vtan_ps);
00476 
00477       if (n_vtan_ps == 0)
00478       {    
00479         // In case the given curve is already x-monotone:
00480         *oi = make_object (X_monotone_curve_2 (cv, conic_id));
00481         ++oi;
00482         return (oi);
00483       }
00484 
00485       // Split the conic arc into x-monotone sub-curves. 
00486       if (cv.is_full_conic())
00487       {
00488         // Make sure we have two vertical tangency points.
00489         CGAL_assertion(n_vtan_ps == 2);
00490 
00491         // In case the curve is a full conic, split it into two x-monotone
00492         // arcs, one going from ps[0] to ps[1], and the other from ps[1] to
00493         // ps[0].
00494         *oi = make_object (X_monotone_curve_2 (cv, vtan_ps[0], vtan_ps[1], 
00495                                                conic_id));
00496         ++oi;
00497         *oi = make_object (X_monotone_curve_2 (cv, vtan_ps[1], vtan_ps[0], 
00498                                                conic_id));
00499         ++oi;
00500       }
00501       else
00502       {
00503         if (n_vtan_ps == 1)
00504         {
00505           // Split the arc into two x-monotone sub-curves: one going from the
00506           // arc source to ps[0], and the other from ps[0] to the target.
00507           *oi = make_object (X_monotone_curve_2 (cv, cv.source(), vtan_ps[0], 
00508                                                  conic_id));
00509           ++oi;
00510           *oi = make_object (X_monotone_curve_2 (cv, vtan_ps[0], cv.target(), 
00511                                                  conic_id));
00512           ++oi;
00513         }
00514         else
00515         {
00516           CGAL_assertion (n_vtan_ps == 2);
00517 
00518           // Identify the first point we encounter when going from cv's source
00519           // to its target, and the second point we encounter. Note that the
00520           // two endpoints must both be below the line connecting the two
00521           // tangnecy points (or both lies above it).
00522           int                   ind_first = 0;
00523           int                   ind_second = 1;
00524           Alg_kernel_           ker;
00525           typename Alg_kernel_::Line_2  line =
00526             ker.construct_line_2_object() (vtan_ps[0], vtan_ps[1]);
00527           const Comparison_result       start_pos =
00528             ker.compare_y_at_x_2_object() (cv.source(), line);
00529           const Comparison_result       order_vpts =
00530             ker.compare_x_2_object() (vtan_ps[0], vtan_ps[1]);
00531 
00532           CGAL_assertion (start_pos != EQUAL &&
00533                           ker.compare_y_at_x_2_object() (cv.target(),
00534                                                          line) == start_pos);
00535           CGAL_assertion (order_vpts != EQUAL);
00536 
00537           if ((cv.orientation() == COUNTERCLOCKWISE &&
00538                start_pos == order_vpts) ||
00539               (cv.orientation() == CLOCKWISE &&
00540                start_pos != order_vpts))
00541           {
00542             ind_first = 1;
00543             ind_second = 0;
00544           }
00545 
00546           // Split the arc into three x-monotone sub-curves.
00547           *oi = make_object (X_monotone_curve_2 (cv,
00548                                                  cv.source(), 
00549                                                  vtan_ps[ind_first], 
00550                                                  conic_id));
00551           ++oi;
00552           
00553           *oi = make_object (X_monotone_curve_2 (cv,
00554                                                  vtan_ps[ind_first], 
00555                                                  vtan_ps[ind_second], 
00556                                                  conic_id));
00557           ++oi;
00558           
00559           *oi = make_object (X_monotone_curve_2 (cv,
00560                                                  vtan_ps[ind_second],
00561                                                  cv.target(),
00562                                                  conic_id));
00563           ++oi;
00564         }
00565       }
00566 
00567       return (oi);
00568     }
00569   };
00570 
00572   Make_x_monotone_2 make_x_monotone_2_object () const
00573   {
00574     return Make_x_monotone_2();
00575   }
00576 
00577   class Split_2
00578   {
00579   public:
00588     void operator() (const X_monotone_curve_2& cv, const Point_2 & p,
00589                      X_monotone_curve_2& c1, X_monotone_curve_2& c2) const
00590     {
00591       cv.split (p, c1, c2);
00592       return;
00593     }
00594   };
00595 
00597   Split_2 split_2_object () const
00598   {
00599     return Split_2();
00600   }
00601 
00602   class Intersect_2
00603   {
00604   private:
00605 
00606     Intersection_map&  _inter_map;       // The map of intersection points.
00607 
00608   public:
00609 
00611     Intersect_2 (Intersection_map& map) :
00612       _inter_map (map)
00613     {}
00614 
00624     template<class OutputIterator>
00625     OutputIterator operator() (const X_monotone_curve_2& cv1,
00626                                const X_monotone_curve_2& cv2,
00627                                OutputIterator oi) const
00628     {
00629       return (cv1.intersect (cv2, _inter_map, oi));
00630     }
00631   };
00632 
00634   Intersect_2 intersect_2_object () const
00635   {
00636     return (Intersect_2 (inter_map));
00637   }
00638 
00639   class Are_mergeable_2
00640   {
00641   public:
00649     bool operator() (const X_monotone_curve_2& cv1,
00650                      const X_monotone_curve_2& cv2) const
00651     {
00652       return (cv1.can_merge_with (cv2));
00653     }
00654   };
00655 
00657   Are_mergeable_2 are_mergeable_2_object () const
00658   {
00659     return Are_mergeable_2();
00660   }
00661 
00662   class Merge_2
00663   {
00664   public:
00673     void operator() (const X_monotone_curve_2& cv1,
00674                      const X_monotone_curve_2& cv2,
00675                      X_monotone_curve_2& c) const
00676     {
00677       c = cv1;
00678       c.merge (cv2);
00679 
00680       return;
00681     }
00682   };
00683 
00685   Merge_2 merge_2_object () const
00686   {
00687     return Merge_2();
00688   }
00689 
00691 
00693 
00694   typedef double                          Approximate_number_type;
00695 
00696   class Approximate_2
00697   {
00698   public:
00699 
00708     Approximate_number_type operator() (const Point_2& p,
00709                                         int i) const
00710     {
00711       CGAL_precondition (i == 0 || i == 1);
00712 
00713       if (i == 0)
00714         return (CGAL::to_double(p.x()));
00715       else
00716         return (CGAL::to_double(p.y()));
00717     }
00718   };
00719 
00721   Approximate_2 approximate_2_object () const
00722   {
00723     return Approximate_2();
00724   }
00725 
00726   class Construct_x_monotone_curve_2
00727   {
00728   public:
00729 
00737     X_monotone_curve_2 operator() (const Point_2& p,
00738                                    const Point_2& q) const
00739     {
00740       return (X_monotone_curve_2 (p, q));
00741     }
00742   };
00743 
00745   Construct_x_monotone_curve_2 construct_x_monotone_curve_2_object () const
00746   {
00747     return Construct_x_monotone_curve_2();
00748   }
00750 
00752 
00753  
00754   class Compare_endpoints_xy_2
00755   {
00756   public:
00757 
00765     Comparison_result operator() (const X_monotone_curve_2& cv) const
00766     {
00767       if (cv.is_directed_right())
00768         return (SMALLER);
00769       else
00770         return (LARGER);
00771     }
00772   };
00773 
00775   Compare_endpoints_xy_2 compare_endpoints_xy_2_object() const
00776   {
00777     return Compare_endpoints_xy_2();
00778   }
00779 
00780   class Construct_opposite_2
00781   {
00782   public:
00783 
00789     X_monotone_curve_2 operator() (const X_monotone_curve_2& cv) const
00790     {
00791       return (cv.flip());
00792     }
00793   };
00794 
00796   Construct_opposite_2 construct_opposite_2_object() const
00797   {
00798     return Construct_opposite_2();
00799   }
00801 };
00802 
00803 CGAL_END_NAMESPACE
00804 
00805 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines