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