BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Arr_segment_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_segment_traits_2.h $
00015 // $Id: Arr_segment_traits_2.h 50374 2009-07-05 15:04:52Z efif $
00016 // 
00017 //
00018 // Author(s)     : Ron Wein          <wein@post.tau.ac.il>
00019 //                 Efi Fogel         <efif@post.tau.ac.il>
00020 
00021 #ifndef CGAL_ARR_SEGMENT_TRAITS_2_H
00022 #define CGAL_ARR_SEGMENT_TRAITS_2_H
00023 
00028 #include <CGAL/tags.h>
00029 #include <CGAL/intersections.h>
00030 #include <CGAL/Arr_tags.h>
00031 #include <CGAL/Arr_geometry_traits/Segment_assertions.h>
00032 #include <fstream>
00033 
00034 CGAL_BEGIN_NAMESPACE
00035 
00036 template <class Kernel_> class Arr_segment_2;
00037 
00048 template <class Kernel_>
00049 class Arr_segment_traits_2 : public Kernel_
00050 {
00051   friend class Arr_segment_2<Kernel_>;
00052 
00053 public:
00054 
00055   typedef Kernel_                         Kernel;
00056   typedef typename Kernel::FT             FT;
00057 
00058   typedef typename Algebraic_structure_traits<FT>::Is_exact 
00059                                           Has_exact_division;
00060 
00061   // Category tags:
00062   typedef Tag_true                        Has_left_category;
00063   typedef Tag_true                        Has_merge_category;
00064  
00065   typedef Arr_oblivious_side_tag          Arr_left_side_tag;
00066   typedef Arr_oblivious_side_tag          Arr_bottom_side_tag;
00067   typedef Arr_oblivious_side_tag          Arr_top_side_tag;
00068   typedef Arr_oblivious_side_tag          Arr_right_side_tag;
00069  
00070   typedef typename Kernel::Line_2         Line_2;
00071   typedef CGAL::Segment_assertions<Arr_segment_traits_2<Kernel> >
00072                                           Segment_assertions;
00073 
00077   class _Segment_cached_2
00078   {
00079   public:
00080 
00081     typedef typename Kernel::Line_2                Line_2;
00082     typedef typename Kernel::Segment_2             Segment_2;
00083     typedef typename Kernel::Point_2               Point_2;
00084 
00085   protected:
00086 
00087     Line_2    l;                // The line that supports the segment.
00088     Point_2   ps;               // The source point of the segment.
00089     Point_2   pt;               // The target point of the segment.
00090     bool      is_pt_max;        // Is the target (lexicographically) larger
00091                                 // than the source.
00092     bool      is_vert;          // Is this a vertical segment.
00093     bool      is_degen;         // Is the segment degenerate (a single point).
00094 
00095   public:
00096 
00100     _Segment_cached_2 () :
00101       is_vert(false),
00102       is_degen(true)
00103     {}
00104 
00110     _Segment_cached_2 (const Segment_2& seg)
00111     {
00112       Kernel   kernel;
00113 
00114       typename Kernel_::Construct_vertex_2
00115         construct_vertex = kernel.construct_vertex_2_object();
00116 
00117       ps = construct_vertex(seg, 0);
00118       pt = construct_vertex(seg, 1);
00119 
00120       Comparison_result  res = kernel.compare_xy_2_object()(ps, pt);
00121       is_degen = (res == EQUAL);
00122       is_pt_max = (res == SMALLER);
00123 
00124       CGAL_precondition_msg (! is_degen,
00125                              "Cannot contruct a degenerate segment.");
00126 
00127       l = kernel.construct_line_2_object()(seg);
00128       is_vert = kernel.is_vertical_2_object()(seg);
00129     }
00130 
00137     _Segment_cached_2 (const Point_2& source, const Point_2& target) :
00138       ps (source),
00139       pt (target)
00140     {
00141       Kernel   kernel;
00142 
00143       Comparison_result  res = kernel.compare_xy_2_object()(ps, pt);
00144       is_degen = (res == EQUAL);
00145       is_pt_max = (res == SMALLER);
00146 
00147       CGAL_precondition_msg (! is_degen,
00148                              "Cannot contruct a degenerate segment.");
00149 
00150       l = kernel.construct_line_2_object()(source, target);
00151       is_vert = kernel.is_vertical_2_object()(l);
00152     }
00153 
00161     _Segment_cached_2 (const Line_2& supp_line,
00162                        const Point_2& source, const Point_2& target) :
00163       l (supp_line),
00164       ps (source),
00165       pt (target)
00166     {
00167       Kernel   kernel;
00168 
00169       CGAL_precondition(
00170         Segment_assertions::_assert_is_point_on(source, l,
00171                                                 Has_exact_division()) &&
00172         Segment_assertions::_assert_is_point_on(target,l,
00173                                                 Has_exact_division())
00174         );
00175 
00176       is_vert = kernel.is_vertical_2_object()(l);
00177 
00178       Comparison_result  res = kernel.compare_xy_2_object()(ps, pt);
00179       is_degen = (res == EQUAL);
00180       is_pt_max = (res == SMALLER);
00181 
00182       CGAL_precondition_msg (! is_degen,
00183                              "Cannot contruct a degenerate segment.");
00184     }
00185 
00191     const _Segment_cached_2& operator= (const Segment_2& seg)
00192     {
00193       Kernel   kernel;
00194 
00195       typename Kernel_::Construct_vertex_2
00196         construct_vertex = kernel.construct_vertex_2_object();
00197 
00198       ps = construct_vertex(seg, 0);
00199       pt = construct_vertex(seg, 1);
00200 
00201       Comparison_result  res = kernel.compare_xy_2_object()(ps, pt);
00202       is_degen = (res == EQUAL);
00203       is_pt_max = (res == SMALLER);
00204 
00205       CGAL_precondition_msg (! is_degen,
00206                              "Cannot contruct a degenerate segment.");
00207 
00208       l = kernel.construct_line_2_object()(seg);
00209       is_vert = kernel.is_vertical_2_object()(seg);
00210 
00211       return (*this);
00212     }
00213 
00217     const Point_2& left () const
00218     {
00219       return (is_pt_max ? ps : pt);
00220     }
00221 
00227     void set_left (const Point_2& p)
00228     {
00229       CGAL_precondition (! is_degen);
00230       CGAL_precondition_code (
00231         Kernel    kernel;
00232       );
00233       CGAL_precondition 
00234         (Segment_assertions::_assert_is_point_on (p, l, 
00235                                                   Has_exact_division()) &&
00236          kernel.compare_xy_2_object() (p, right()) == SMALLER);
00237 
00238       if (is_pt_max)
00239         ps = p;
00240       else
00241         pt = p;
00242     }
00243 
00247     const Point_2& right () const
00248     {
00249       return (is_pt_max ? pt : ps);
00250     }
00251 
00257     void set_right (const Point_2& p)
00258     {
00259       CGAL_precondition (! is_degen);
00260       CGAL_precondition_code (
00261         Kernel    kernel;
00262       );
00263       CGAL_precondition 
00264         (Segment_assertions::_assert_is_point_on (p, l, 
00265                                                   Has_exact_division()) &&
00266          kernel.compare_xy_2_object() (p, left()) == LARGER);
00267 
00268       if (is_pt_max)
00269         pt = p;
00270       else
00271         ps = p;
00272     }
00273 
00277     const Line_2& line () const
00278     {
00279       CGAL_precondition (! is_degen);
00280       return (l);
00281     }
00282 
00286     bool is_vertical () const
00287     {
00288       CGAL_precondition (! is_degen);
00289       return (is_vert);
00290     }
00291 
00295     bool is_directed_right () const
00296     {
00297       return (is_pt_max);
00298     }
00299 
00305     bool is_in_x_range (const Point_2& p) const
00306     {
00307       Kernel                          kernel;
00308       typename Kernel_::Compare_x_2   compare_x = kernel.compare_x_2_object();
00309       const Comparison_result         res1 = compare_x (p, left());
00310 
00311       if (res1 == SMALLER)
00312         return (false);
00313       else if (res1 == EQUAL)
00314         return (true);
00315 
00316       const Comparison_result         res2 = compare_x (p, right());
00317 
00318       return (res2 != LARGER);
00319     }
00320 
00326     bool is_in_y_range (const Point_2& p) const
00327     {
00328       Kernel                          kernel;
00329       typename Kernel_::Compare_y_2   compare_y = kernel.compare_y_2_object();
00330       const Comparison_result         res1 = compare_y (p, left());
00331 
00332       if (res1 == SMALLER)
00333         return (false);
00334       else if (res1 == EQUAL)
00335         return (true);
00336 
00337       const Comparison_result         res2 = compare_y (p, right());
00338 
00339       return (res2 != LARGER);
00340     }
00341   };
00342 
00343 public:
00344 
00345   // Traits objects
00346   typedef typename Kernel::Point_2        Point_2;
00347   typedef Arr_segment_2<Kernel>           X_monotone_curve_2;
00348   typedef Arr_segment_2<Kernel>           Curve_2;
00349   typedef unsigned int                    Multiplicity;
00350 
00351 public:
00352 
00356   Arr_segment_traits_2 ()
00357   {}
00358 
00360 
00361 
00362   class Compare_x_2
00363   {
00364   public:
00373     Comparison_result operator() (const Point_2& p1, const Point_2& p2) const
00374     {
00375       Kernel    kernel;
00376 
00377       return (kernel.compare_x_2_object()(p1, p2));
00378     }
00379   };
00380 
00382   Compare_x_2 compare_x_2_object () const
00383   {
00384     return Compare_x_2();
00385   }
00386 
00387   class Compare_xy_2
00388   {
00389   public:
00398     Comparison_result operator() (const Point_2& p1, const Point_2& p2) const
00399     {
00400       Kernel    kernel;
00401       return (kernel.compare_xy_2_object()(p1, p2));
00402     }
00403   };
00404 
00406   Compare_xy_2 compare_xy_2_object () const
00407   {
00408     return Compare_xy_2();
00409   }
00410 
00411   class Construct_min_vertex_2
00412   {
00413   public:
00419     const Point_2& operator() (const X_monotone_curve_2& cv) const
00420     {
00421       return (cv.left());
00422     }
00423   };
00424 
00426   Construct_min_vertex_2 construct_min_vertex_2_object () const
00427   {
00428     return Construct_min_vertex_2();
00429   }
00430 
00431   class Construct_max_vertex_2
00432   {
00433   public:
00439     const Point_2& operator() (const X_monotone_curve_2& cv) const
00440     {
00441       return (cv.right());
00442     }
00443   };
00444 
00446   Construct_max_vertex_2 construct_max_vertex_2_object () const
00447   {
00448     return Construct_max_vertex_2();
00449   }
00450 
00451   class Is_vertical_2
00452   {
00453   public:
00459     bool operator() (const X_monotone_curve_2& cv) const
00460     {
00461       return (cv.is_vertical());
00462     }
00463   };
00464 
00466   Is_vertical_2 is_vertical_2_object () const
00467   {
00468     return Is_vertical_2();
00469   }
00470 
00471   class Compare_y_at_x_2
00472   {
00473   public:
00483     Comparison_result operator() (const Point_2& p,
00484                                   const X_monotone_curve_2& cv) const
00485     {
00486       CGAL_precondition (cv.is_in_x_range (p));
00487 
00488       Kernel    kernel;
00489 
00490       if (! cv.is_vertical())
00491       {
00492         // Compare p with the segment's supporting line.
00493         return (kernel.compare_y_at_x_2_object()(p, cv.line()));
00494       }
00495       else
00496       {
00497         // Compare with the vertical segment's end-points.
00498         typename Kernel::Compare_y_2  compare_y = kernel.compare_y_2_object();
00499         Comparison_result res1 = compare_y (p, cv.left());
00500         Comparison_result res2 = compare_y (p, cv.right());
00501 
00502         if (res1 == res2)
00503           return (res1);
00504         else
00505           return (EQUAL);
00506       }
00507     }
00508   };
00509 
00511   Compare_y_at_x_2 compare_y_at_x_2_object () const
00512   {
00513     return Compare_y_at_x_2();
00514   }
00515 
00516   class Compare_y_at_x_left_2
00517   {
00518   public:
00530     Comparison_result operator() (const X_monotone_curve_2& cv1,
00531                                   const X_monotone_curve_2& cv2,
00532                                   const Point_2& p) const
00533     {
00534       Kernel                        kernel;
00535 
00536       // Make sure that p lies on both curves, and that both are defined to its
00537       // left (so their left endpoint is lexicographically smaller than p).
00538       CGAL_precondition_code (
00539         typename Kernel::Compare_xy_2 compare_xy = 
00540                                                   kernel.compare_xy_2_object();
00541       );
00542 
00543       CGAL_precondition 
00544         (Segment_assertions::_assert_is_point_on (p, cv1, 
00545                                                   Has_exact_division()) &&
00546          Segment_assertions::_assert_is_point_on (p, cv2,
00547                                                   Has_exact_division()));
00548 
00549       CGAL_precondition (compare_xy(cv1.left(), p) == SMALLER &&
00550                          compare_xy(cv2.left(), p) == SMALLER);
00551 
00552       // Compare the slopes of the two segments to determine thir relative
00553       // position immediately to the left of q.
00554       // Notice we use the supporting lines in order to compare the slopes,
00555       // and that we swap the order of the curves in order to obtain the
00556       // correct result to the left of p.
00557       return (kernel.compare_slope_2_object()(cv2.line(), cv1.line()));
00558     }
00559   };
00560 
00562   Compare_y_at_x_left_2 compare_y_at_x_left_2_object () const
00563   {
00564     return Compare_y_at_x_left_2();
00565   }
00566 
00567   class Compare_y_at_x_right_2
00568   {
00569   public:
00581     Comparison_result operator() (const X_monotone_curve_2& cv1,
00582                                   const X_monotone_curve_2& cv2,
00583                                   const Point_2& p) const
00584     {
00585       Kernel                        kernel;
00586 
00587       // Make sure that p lies on both curves, and that both are defined to its
00588       // right (so their right endpoint is lexicographically larger than p).
00589       CGAL_precondition_code (
00590         typename Kernel::Compare_xy_2 compare_xy = 
00591                                                  kernel.compare_xy_2_object();
00592       );
00593 
00594       CGAL_precondition
00595         (Segment_assertions::_assert_is_point_on (p, cv1, 
00596                                                   Has_exact_division()) &&
00597          Segment_assertions::_assert_is_point_on (p, cv2,
00598                                                   Has_exact_division()));
00599 
00600       CGAL_precondition (compare_xy(cv1.right(), p) == LARGER &&
00601                          compare_xy(cv2.right(), p) == LARGER);
00602 
00603       // Compare the slopes of the two segments to determine thir relative
00604       // position immediately to the left of q.
00605       // Notice we use the supporting lines in order to compare the slopes.
00606       return (kernel.compare_slope_2_object()(cv1.line(), cv2.line()));
00607     }
00608   };
00609 
00611   Compare_y_at_x_right_2 compare_y_at_x_right_2_object () const
00612   {
00613     return Compare_y_at_x_right_2();
00614   }
00615 
00616   class Equal_2
00617   {
00618   public:
00625     bool operator() (const X_monotone_curve_2& cv1,
00626                      const X_monotone_curve_2& cv2) const
00627     {
00628       Kernel                    kernel;
00629       typename Kernel::Equal_2  equal = kernel.equal_2_object();
00630 
00631       return (equal(cv1.left(), cv2.left()) &&
00632               equal(cv1.right(), cv2.right()));
00633     }
00634 
00641     bool operator() (const Point_2& p1, const Point_2& p2) const
00642     {
00643       Kernel    kernel;
00644       return (kernel.equal_2_object()(p1, p2));
00645     }
00646   };
00647 
00649   Equal_2 equal_2_object () const
00650   {
00651     return Equal_2();
00652   }
00654 
00656 
00657 
00658   class Make_x_monotone_2
00659   {
00660   public:
00669     template<class OutputIterator>
00670     OutputIterator operator() (const Curve_2& cv, OutputIterator oi) const
00671     {
00672       // Wrap the segment with an object.
00673       *oi = make_object (cv);
00674       ++oi;
00675       return (oi);
00676     }
00677   };
00678 
00680   Make_x_monotone_2 make_x_monotone_2_object () const
00681   {
00682     return Make_x_monotone_2();
00683   }
00684 
00685   class Split_2
00686   {
00687   public:
00696     void operator() (const X_monotone_curve_2& cv, const Point_2& p,
00697                      X_monotone_curve_2& c1, X_monotone_curve_2& c2) const
00698     {
00699       // Make sure that p lies on the interior of the curve.
00700       CGAL_precondition_code (
00701         Kernel                        kernel;
00702         typename Kernel::Compare_xy_2 compare_xy = 
00703                                                  kernel.compare_xy_2_object();
00704       );
00705 
00706       CGAL_precondition
00707         (Segment_assertions::_assert_is_point_on (p, cv,
00708                                                   Has_exact_division()) &&
00709          compare_xy(cv.left(), p) == SMALLER &&
00710          compare_xy(cv.right(), p) == LARGER);
00711 
00712       // Perform the split.
00713       c1 = cv;
00714       c1.set_right (p);
00715 
00716       c2 = cv;
00717       c2.set_left (p);
00718 
00719       return;
00720     }
00721   };
00722 
00724   Split_2 split_2_object () const
00725   {
00726     return Split_2();
00727   }
00728 
00729   class Intersect_2
00730   {
00731   public:
00741     template<class OutputIterator>
00742     OutputIterator operator() (const X_monotone_curve_2& cv1,
00743                                const X_monotone_curve_2& cv2,
00744                                OutputIterator oi) const
00745     {
00746       // Intersect the two supporting lines.
00747       Kernel       kernel;
00748       CGAL::Object obj = kernel.intersect_2_object()(cv1.line(), cv2.line());
00749 
00750       if (obj.is_empty())
00751       {
00752         // The supporting line are parallel lines and do not intersect:
00753         return (oi);
00754       }
00755 
00756       // Check if we have a single intersection point.
00757       const Point_2  *ip = object_cast<Point_2> (&obj);
00758       
00759       if (ip != NULL)
00760       {
00761         // Check if the intersection point ip lies on both segments.
00762         const bool    ip_on_cv1 = cv1.is_vertical() ? cv1.is_in_y_range(*ip) :
00763                                                       cv1.is_in_x_range(*ip);
00764 
00765         if (ip_on_cv1)
00766         {
00767           const bool  ip_on_cv2 = cv2.is_vertical() ? cv2.is_in_y_range(*ip) :
00768                                                       cv2.is_in_x_range(*ip);
00769 
00770           if (ip_on_cv2)
00771           {
00772             // Create a pair representing the point with its multiplicity,
00773             // which is always 1 for line segments.
00774             std::pair<Point_2, Multiplicity>   ip_mult (*ip, 1);
00775             *oi = make_object (ip_mult);
00776             oi++;
00777           }
00778         }
00779         return (oi);
00780       }
00781 
00782       // In this case, the two supporting lines overlap.
00783       // The overlapping segment is therefore [p_l,p_r], where p_l is the
00784       // rightmost of the two left endpoints and p_r is the leftmost of the
00785       // two right endpoints.
00786       typename Kernel::Compare_xy_2  compare_xy = kernel.compare_xy_2_object();
00787       Point_2                        p_l, p_r;
00788 
00789       if (compare_xy (cv1.left(), cv2.left()) == SMALLER)
00790         p_l = cv2.left();
00791       else
00792         p_l = cv1.left();
00793 
00794       if (compare_xy (cv1.right(), cv2.right()) == SMALLER)
00795         p_r = cv1.right();
00796       else
00797         p_r = cv2.right();
00798 
00799       // Examine the resulting segment.
00800       const Comparison_result        res = compare_xy (p_l, p_r);
00801 
00802       if (res == SMALLER)
00803       {
00804         // We have discovered an overlapping segment:
00805         if(cv1.is_directed_right() == cv2.is_directed_right())
00806         {
00807           // cv1 and cv2 have the same directions, maintain this direction
00808           // in the overlap segment
00809           if(cv1.is_directed_right())
00810           {
00811             X_monotone_curve_2  overlap_seg (cv1.line(), p_l, p_r);
00812             *oi = make_object (overlap_seg);
00813             oi++;
00814           }
00815           else
00816           {
00817             X_monotone_curve_2  overlap_seg (cv1.line(), p_r, p_l);
00818             *oi = make_object (overlap_seg);
00819             oi++;
00820           }
00821         }
00822         else
00823         {
00824           // cv1 and cv2 have opposite directions, the overlap segment
00825           // will be directed from left to right
00826           X_monotone_curve_2  overlap_seg (cv1.line(), p_l, p_r);
00827           *oi = make_object (overlap_seg);
00828           oi++;
00829         }
00830       }
00831       else if (res == EQUAL)
00832       {
00833         // The two segment have the same supporting line, but they just share
00834         // a common endpoint. Thus we have an intersection point, but we leave
00835         // the multiplicity of this point undefined.
00836         std::pair<Point_2, Multiplicity>   ip_mult (p_r, 0);
00837         *oi = make_object (ip_mult);
00838         oi++;
00839       }
00840 
00841       return (oi);
00842     }
00843   };
00844 
00846   Intersect_2 intersect_2_object () const
00847   {
00848     return Intersect_2();
00849   }
00850 
00851   class Are_mergeable_2
00852   {
00853   public:
00861     bool operator() (const X_monotone_curve_2& cv1,
00862                      const X_monotone_curve_2& cv2) const
00863     {
00864       Kernel                    kernel;
00865       typename Kernel::Equal_2  equal = kernel.equal_2_object();
00866 
00867       // Check if the two curves have the same supporting line.
00868       if (! equal (cv1.line(), cv2.line()) && 
00869           ! equal (cv1.line(), 
00870                    kernel.construct_opposite_line_2_object() (cv2.line())))
00871         return (false);
00872 
00873       // Check if the left endpoint of one curve is the right endpoint of the
00874       // other.
00875       return (equal (cv1.right(), cv2.left()) ||
00876               equal (cv2.right(), cv1.left()));
00877     }
00878   };
00879 
00881   Are_mergeable_2 are_mergeable_2_object () const
00882   {
00883     return Are_mergeable_2();
00884   }
00885 
00886   class Merge_2
00887   {
00888   public:
00897     void operator() (const X_monotone_curve_2& cv1,
00898                      const X_monotone_curve_2& cv2,
00899                      X_monotone_curve_2& c) const
00900     {
00901       Kernel                    kernel;
00902       typename Kernel::Equal_2  equal = kernel.equal_2_object();
00903 
00904       CGAL_precondition
00905         (equal (cv1.line(), cv2.line()) ||
00906          equal (cv1.line(),
00907                 kernel.construct_opposite_line_2_object() (cv2.line())));
00908 
00909       // Check which curve extends to the right of the other.
00910       if (equal (cv1.right(), cv2.left()))
00911       {
00912         // cv2 extends cv1 to the right.
00913         c = cv1;
00914         c.set_right (cv2.right());
00915       }
00916       else
00917       {
00918         CGAL_precondition (equal (cv2.right(), cv1.left()));
00919 
00920         // cv1 extends cv2 to the right.
00921         c = cv2;
00922         c.set_right (cv1.right());
00923       }
00924 
00925       return;
00926     }
00927   };
00928 
00930   Merge_2 merge_2_object () const
00931   {
00932     return Merge_2();
00933   }
00935 
00937 
00938   typedef double                          Approximate_number_type;
00939 
00940   class Approximate_2
00941   {
00942   public:
00943 
00952     Approximate_number_type operator() (const Point_2& p,
00953                                         int i) const
00954     {
00955       CGAL_precondition (i == 0 || i == 1);
00956       return (i == 0) ? (CGAL::to_double(p.x())) : (CGAL::to_double(p.y()));
00957     }
00958   };
00959 
00961   Approximate_2 approximate_2_object () const
00962   {
00963     return Approximate_2();
00964   }
00965 
00966   class Construct_x_monotone_curve_2
00967   {
00968   public:
00969 
00977     X_monotone_curve_2 operator() (const Point_2& p,
00978                                    const Point_2& q) const
00979     {
00980       return (X_monotone_curve_2 (p, q));
00981     }
00982   };
00983 
00985   Construct_x_monotone_curve_2 construct_x_monotone_curve_2_object () const
00986   {
00987     return Construct_x_monotone_curve_2();
00988   }
00990 
00991 
00993 
00994  
00995   class Compare_endpoints_xy_2
00996   {
00997   public:
00998 
01006     Comparison_result operator() (const X_monotone_curve_2& cv) const
01007     {
01008       return (cv.is_directed_right()) ? (SMALLER) : (LARGER);
01009     }
01010   };
01011 
01013   Compare_endpoints_xy_2 compare_endpoints_xy_2_object() const
01014   {
01015     return Compare_endpoints_xy_2();
01016   }
01017 
01018   class Construct_opposite_2
01019   {
01020   public:
01021 
01027     X_monotone_curve_2 operator() (const X_monotone_curve_2& cv) const
01028     {
01029       return (cv.flip());
01030     }
01031   };
01032 
01034   Construct_opposite_2 construct_opposite_2_object() const
01035   {
01036     return Construct_opposite_2();
01037   }
01039 };
01040 
01045 template <class Kernel_>
01046 class Arr_segment_2 :
01047     public Arr_segment_traits_2<Kernel_>::_Segment_cached_2
01048 {
01049   typedef Kernel_                                                  Kernel;
01050   typedef typename Arr_segment_traits_2<Kernel>::_Segment_cached_2 Base;
01051   typedef typename Kernel::Segment_2                               Segment_2;
01052   typedef typename Kernel::Point_2                                 Point_2;
01053   typedef typename Kernel::Line_2                                  Line_2;
01054 
01055 public:
01056 
01060   Arr_segment_2 () :
01061     Base()
01062   {}
01063     
01069   Arr_segment_2 (const Segment_2& seg) :
01070     Base(seg)
01071   {}
01072 
01079   Arr_segment_2 (const Point_2& source, const Point_2& target) :
01080     Base(source,target)
01081   {}
01082 
01091   Arr_segment_2 (const Line_2& line,
01092                  const Point_2& source, const Point_2& target) :
01093     Base(line,source,target)
01094   {}
01095 
01099   operator Segment_2 () const
01100   {
01101     Kernel     kernel;
01102     Segment_2  seg = kernel.construct_segment_2_object() (this->ps, this->pt);
01103     return (seg);
01104   }
01105 
01109   Bbox_2 bbox() const
01110   {
01111     Kernel     kernel;
01112     Segment_2  seg = kernel.construct_segment_2_object() (this->ps, this->pt);
01113     return (kernel.construct_bbox_2_object() (seg));
01114   }
01115 
01119   const Point_2& source() const
01120   { 
01121     return (this->ps);
01122   }
01123 
01127   const Point_2& target() const
01128   {
01129     return (this->pt);
01130   }
01131 
01133   Arr_segment_2 flip () const
01134   {
01135     Arr_segment_2   opp;
01136     opp.l = this->l;
01137     opp.ps = this->pt;
01138     opp.pt = this->ps;
01139     opp.is_pt_max = !(this->is_pt_max);
01140     opp.is_vert = this->is_vert;
01141     opp.is_degen = this->is_degen;
01142     
01143     return (opp);
01144   }
01145 };
01146 
01150 template <class Kernel, class OutputStream>
01151 OutputStream& operator<< (OutputStream& os, const Arr_segment_2<Kernel>& seg)
01152 {
01153   os << static_cast<typename Kernel::Segment_2>(seg);
01154   return (os);
01155 }
01156 
01160 template <class Kernel, class InputStream>
01161 InputStream& operator>> (InputStream& is, Arr_segment_2<Kernel>& seg)
01162 {
01163   typename Kernel::Segment_2   kernel_seg;
01164   is >> kernel_seg;
01165   seg = kernel_seg;
01166   return (is);
01167 }
01168 
01169 CGAL_END_NAMESPACE
01170 
01171 #endif
01172 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines