|
BWAPI
|
00001 // Copyright (c) 2006 Fernando Luis Cacciola Carballal. All rights reserved. 00002 // 00003 // This file is part of CGAL (www.cgal.org); you may redistribute it under 00004 // the terms of the Q Public License version 1.0. 00005 // See the file LICENSE.QPL distributed with CGAL. 00006 // 00007 // Licensees holding a valid commercial license may use this file in 00008 // accordance with the commercial license agreement provided with the software. 00009 // 00010 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00011 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00012 // 00013 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Straight_skeleton_2/include/CGAL/predicates/Straight_skeleton_pred_ftC2.h $ 00014 // $Id: Straight_skeleton_pred_ftC2.h 46494 2008-10-27 16:30:51Z afabri $ 00015 // 00016 // Author(s) : Fernando Cacciola <fernando_cacciola@ciudad.com.ar> 00017 // 00018 #ifndef CGAL_STRAIGHT_SKELETON_PREDICATES_FTC2_H 00019 #define CGAL_STRAIGHT_SKELETON_PREDICATES_FTC2_H 1 00020 00021 #include <CGAL/constructions/Straight_skeleton_cons_ftC2.h> 00022 #include <CGAL/Uncertain.h> 00023 #include <CGAL/certified_quotient_predicates.h> 00024 00025 CGAL_BEGIN_NAMESPACE 00026 00027 namespace CGAL_SS_i 00028 { 00029 00030 // Just like the uncertified collinear() returns true IFF r lies in the line p->q 00031 // NOTE: r might be in the ray from p or q containing q or p, that is, there is no ordering implied, just that 00032 // the three points are along the same line, in any order. 00033 template<class K> 00034 inline 00035 Uncertain<bool> certified_collinearC2( Point_2<K> const& p 00036 , Point_2<K> const& q 00037 , Point_2<K> const& r 00038 ) 00039 { 00040 return CGAL_NTS certified_is_equal( ( q.x() - p.x() ) * ( r.y() - p.y() ) 00041 , ( r.x() - p.x() ) * ( q.y() - p.y() ) 00042 ); 00043 } 00044 00045 00046 // Just like the uncertified collinear_are_ordered_along_lineC2() returns true IFF, given p,q,r along the same line, 00047 // q is in the closed segment [p,r]. 00048 template<class K> 00049 inline 00050 Uncertain<bool> certified_collinear_are_ordered_along_lineC2( Point_2<K> const& p 00051 , Point_2<K> const& q 00052 , Point_2<K> const& r 00053 ) 00054 { 00055 if ( CGAL_NTS certainly(p.x() < q.x()) ) return !(r.x() < q.x()); 00056 if ( CGAL_NTS certainly(q.x() < p.x()) ) return !(q.x() < r.x()); 00057 if ( CGAL_NTS certainly(p.y() < q.y()) ) return !(r.y() < q.y()); 00058 if ( CGAL_NTS certainly(q.y() < p.y()) ) return !(q.y() < r.y()); 00059 00060 if ( CGAL_NTS certainly(p.x() == q.x()) && CGAL_NTS certainly(p.y() == q.y()) ) return true; 00061 00062 return Uncertain<bool>::indeterminate(); 00063 } 00064 00065 // Returns true IFF segments e0,e1 share the same supporting line 00066 template<class K> 00067 Uncertain<bool> are_edges_collinearC2( Segment_2<K> const& e0, Segment_2<K> const& e1 ) 00068 { 00069 return certified_collinearC2(e0.source(),e0.target(),e1.source()) 00070 & certified_collinearC2(e0.source(),e0.target(),e1.target()) ; 00071 } 00072 00073 // Returns true IFF the supporting lines for segments e0,e1 are parallel (or the same) 00074 template<class K> 00075 inline 00076 Uncertain<bool> are_edges_parallelC2( Segment_2<K> const& e0, Segment_2<K> const& e1 ) 00077 { 00078 Uncertain<Sign> s = certified_sign_of_determinant2x2(e0.target().x() - e0.source().x() 00079 ,e0.target().y() - e0.source().y() 00080 ,e1.target().x() - e1.source().x() 00081 ,e1.target().y() - e1.source().y() 00082 ) ; 00083 00084 return ( s == Uncertain<Sign>(ZERO) ) ; 00085 } 00086 00087 00088 // Returns true IFF the parallel segments are equally oriented. 00089 // Precondition: the segments must be parallel. 00090 // the three points are along the same line, in any order. 00091 template<class K> 00092 inline 00093 Uncertain<bool> are_parallel_edges_equally_orientedC2( Segment_2<K> const& e0, Segment_2<K> const& e1 ) 00094 { 00095 return CGAL_NTS certified_sign( (e0.target() - e0.source()) * (e1.target() - e1.source()) ) == POSITIVE; 00096 } 00097 00098 00099 // Returns true IFF segments e0,e1 share the same supporting line but do not overlap except at the vetices, and have the same orientation. 00100 // NOTE: If e1 goes back over e0 (a degenerate antenna or alley) this returns false. 00101 template<class K> 00102 Uncertain<bool> are_edges_orderly_collinearC2( Segment_2<K> const& e0, Segment_2<K> const& e1 ) 00103 { 00104 return are_edges_collinearC2(e0,e1) & are_parallel_edges_equally_orientedC2(e0,e1); 00105 } 00106 00107 template <class FT> 00108 inline 00109 Uncertain<Sign> certified_side_of_oriented_lineC2(const FT &a, const FT &b, const FT &c, const FT &x, const FT &y) 00110 { 00111 return CGAL_NTS certified_sign(a*x+b*y+c); 00112 } 00113 00114 00115 // 00116 // Constructs a Trisegment_2 which stores 3 edges (segments) such that 00117 // if two of them are collinear, they are put first, as e0, e1. 00118 // Stores also the number of collinear edges. which should be 0 or 2. 00119 // 00120 // If the collinearity test is indeterminate for any pair of edges the 00121 // resulting sorted trisegment is itself indeterminate 00122 // (encoded as a collinear count of -1) 00123 // 00124 template<class K> 00125 Uncertain<Trisegment_collinearity> certified_trisegment_collinearity ( Segment_2<K> const& e0 00126 , Segment_2<K> const& e1 00127 , Segment_2<K> const& e2 00128 ) 00129 { 00130 Uncertain<bool> is_01 = are_edges_orderly_collinearC2(e0,e1); 00131 if ( is_certain(is_01) ) 00132 { 00133 Uncertain<bool> is_02 = are_edges_orderly_collinearC2(e0,e2); 00134 if ( is_certain(is_02) ) 00135 { 00136 Uncertain<bool> is_12 = are_edges_orderly_collinearC2(e1,e2); 00137 if ( is_certain(is_12) ) 00138 { 00139 if ( CGAL_NTS logical_and(is_01 , !is_02 , !is_12 ) ) 00140 return TRISEGMENT_COLLINEARITY_01; 00141 else if ( CGAL_NTS logical_and(is_02 , !is_01 , !is_12 ) ) 00142 return TRISEGMENT_COLLINEARITY_02; 00143 else if ( CGAL_NTS logical_and(is_12 , !is_01 , !is_02 ) ) 00144 return TRISEGMENT_COLLINEARITY_12; 00145 else if ( CGAL_NTS logical_and(!is_01 , !is_02, !is_12 ) ) 00146 return TRISEGMENT_COLLINEARITY_NONE; 00147 else 00148 return TRISEGMENT_COLLINEARITY_ALL; 00149 } 00150 } 00151 } 00152 00153 return Uncertain<Trisegment_collinearity>::indeterminate(); 00154 } 00155 00156 00157 00158 // Given 3 oriented straight line segments: e0, e1, e2 00159 // returns true if there exist some positive offset distance 't' for which the 00160 // leftward-offsets of their supporting lines intersect at a single point. 00161 // 00162 // NOTE: This function can handle the case of collinear and/or parallel segments. 00163 // 00164 // If two segments are collinear but equally oriented (that is, they share a degenerate vertex) the event exists and 00165 // is well defined, In that case, the degenerate vertex can be even a contour vertex or a skeleton node. If it is a skeleton 00166 // node, it is properly defined by the trisegment tree that corresponds to the node. 00167 // A trisegment tree stores not only the "current event" trisegment but also the trisegments for the left/right seed vertices, 00168 // recursivey in case the seed vertices are skeleton nodes as well. 00169 // Those seeds are used to determine the actual position of the degenerate vertex in case of collinear edges (since that point is 00170 // not given by the collinear edges alone) 00171 // 00172 template<class K, class FT> 00173 Uncertain<bool> exist_offset_lines_isec2 ( intrusive_ptr< Trisegment_2<K> > const& tri, optional<FT> const& aMaxTime ) 00174 { 00175 00176 typedef Rational<FT> Rational ; 00177 typedef optional<Rational> Optional_rational ; 00178 typedef Quotient<FT> Quotient ; 00179 00180 Uncertain<bool> rResult = Uncertain<bool>::indeterminate(); 00181 00182 if ( tri->collinearity() != TRISEGMENT_COLLINEARITY_ALL ) 00183 { 00184 CGAL_STSKEL_TRAITS_TRACE( ( tri->collinearity() == TRISEGMENT_COLLINEARITY_NONE ? " normal edges" : " collinear edges" ) ) ; 00185 00186 Optional_rational t = compute_offset_lines_isec_timeC2(tri) ; 00187 if ( t ) 00188 { 00189 Uncertain<bool> d_is_zero = CGAL_NTS certified_is_zero(t->d()) ; 00190 if ( is_certain(d_is_zero) ) 00191 { 00192 if ( !d_is_zero ) 00193 { 00194 Quotient tq = t->to_quotient() ; 00195 00196 rResult = CGAL_NTS certified_is_positive(tq) ; 00197 00198 if ( aMaxTime && CGAL_NTS certainly(rResult) ) 00199 rResult = CGAL_NTS certified_is_smaller_or_equal(tq,Quotient(*aMaxTime)); 00200 00201 CGAL_STSKEL_TRAITS_TRACE("\nEvent time: " << *t << ". Event " << ( rResult ? "exist." : "doesn't exist." ) ) ; 00202 } 00203 else 00204 { 00205 CGAL_STSKEL_TRAITS_TRACE("\nDenominator exactly zero, Event doesn't exist." ) ; 00206 rResult = false; 00207 } 00208 } 00209 else 00210 CGAL_STSKEL_TRAITS_TRACE("\nDenominator is probably zero (but not exactly), event existance is indeterminate." ) ; 00211 } 00212 else 00213 CGAL_STSKEL_TRAITS_TRACE("\nEvent time overflowed, event existance is indeterminate." ) ; 00214 } 00215 else 00216 { 00217 CGAL_STSKEL_TRAITS_TRACE("\nAll the edges are collinear. Event doesn't exist." ) ; 00218 rResult = false; 00219 } 00220 00221 return rResult ; 00222 } 00223 00224 // Given 2 triples of oriented straight line segments: (m0,m1,m2) and (n0,n1,n2), such that 00225 // for each triple there exists distances 'mt' and 'nt' for which the offsets lines (at mt and nt resp.), 00226 // (m0',m1',m2') and (n0',n1',n2') intersect each in a single point; returns the relative order of mt w.r.t nt. 00227 // That is, indicates which offset triple intersects first (closer to the source lines) 00228 // PRECONDITION: There exist distances mt and nt for which each offset triple intersect at a single point. 00229 template<class K> 00230 Uncertain<Comparison_result> compare_offset_lines_isec_timesC2 ( intrusive_ptr< Trisegment_2<K> > const& m 00231 , intrusive_ptr< Trisegment_2<K> > const& n 00232 ) 00233 { 00234 typedef typename K::FT FT ; 00235 00236 typedef Trisegment_2<K> Trisegment_2 ; 00237 00238 typedef Rational<FT> Rational ; 00239 typedef Quotient<FT> Quotient ; 00240 typedef optional<Rational> Optional_rational ; 00241 00242 Uncertain<Comparison_result> rResult = Uncertain<Comparison_result>::indeterminate(); 00243 00244 Optional_rational mt_ = compute_offset_lines_isec_timeC2(m); 00245 Optional_rational nt_ = compute_offset_lines_isec_timeC2(n); 00246 00247 if ( mt_ && nt_ ) 00248 { 00249 Quotient mt = mt_->to_quotient(); 00250 Quotient nt = nt_->to_quotient(); 00251 00252 if ( CGAL_NTS certified_is_positive(mt) && CGAL_NTS certified_is_positive(nt) ) 00253 rResult = CGAL_NTS certified_compare(mt,nt); 00254 } 00255 00256 return rResult ; 00257 00258 } 00259 00260 00261 // Returns true if the point aP is on the positive side of the line supporting the edge 00262 // 00263 template<class K> 00264 Uncertain<bool> is_edge_facing_pointC2 ( optional< Point_2<K> > const& aP, Segment_2<K> const& aEdge ) 00265 { 00266 typedef typename K::FT FT ; 00267 00268 Uncertain<bool> rResult = Uncertain<bool>::indeterminate(); 00269 if ( aP ) 00270 { 00271 FT a,b,c ; 00272 line_from_pointsC2(aEdge.source().x(),aEdge.source().y(),aEdge.target().x(),aEdge.target().y(),a,b,c); 00273 rResult = certified_side_of_oriented_lineC2(a,b,c,aP->x(),aP->y()) == make_uncertain(POSITIVE) ; 00274 } 00275 return rResult ; 00276 } 00277 00278 // Given a triple of oriented straight line segments: (e0,e1,e2) such that their offsets 00279 // at some distance intersects in a point (x,y), returns true if (x,y) is on the positive side of the line supporting aEdge 00280 // 00281 template<class K> 00282 inline Uncertain<bool> is_edge_facing_offset_lines_isecC2 ( intrusive_ptr< Trisegment_2<K> > const& tri, Segment_2<K> const& aEdge ) 00283 { 00284 return is_edge_facing_pointC2(construct_offset_lines_isecC2(tri),aEdge); 00285 } 00286 00287 // Given an event trisegment and two oriented straight line segments e0 and e1, returns the oriented side of the event point 00288 // w.r.t the (positive) bisector [e0,e1]. 00289 // 00290 // The (positive) bisector [e0,e1] is a ray starting at the vertex (e0,e1) (called "v01") 00291 // 00292 // If e0,e1 are consecutive in the input polygon, v01 = e0.target() = e1.source(). 00293 // If they are not consecutive in the input polygon they must had become consecutive at some known previous event. In this 00294 // case, the point of the "v01_event" trisegment intersection determines v01 which is to the position of the very first 00295 // vertex shared between e0,e1 (at the time they first become consecutive). 00296 // 00297 // A point *exactly on* the bisector is an offset vertex (e0*,e1*) (that is, belongs to both e0* and e1*). 00298 // A point to the positive side of the bisector belongs to e0* but not e1* 00299 // A point to the negative side of the bisector belongs to e1* but not e0* 00300 // 00301 // If e0,e1 intersect in a single point the bisector is an angular bisector. 00302 // 00303 // One of e0 or e1 is considered the primary edge. 00304 // 00305 // If e0,e1 are parallel a line perpendicular to the primary edge passing through "v01" is used "as bisector". 00306 // 00307 // If e0,e1 are collinear then this perpendicular line is a perpendicular bisector of the two segments. 00308 // 00309 // If e0,e1 are parallel but not collinear then the actual bisector is an equidistant line parallel to e0 and e1. 00310 // e0* and e1* overlap and are known to be connected sharing a known vertex v01, which is somewhere along the parallel 00311 // line which is the bisector of e0 and e1. 00312 // Given a line perpendicular to e0 through v01, a point to its positive side belongs to e0* while a point to its negative side does not. 00313 // Given a line perpendicular to e1 through v01, a point to its negative side belongs to e1* while a point to its positive side does not. 00314 // 00315 // This predicate is used to determine the validity of a split or edge event. 00316 // 00317 // A split event is the coallision of a reflex wavefront and some opposite offset egde. Unless the three segments 00318 // don't actually collide (there is no event), the split point is along the supporting line of the offset edge. 00319 // Testing its validity amounts to determining if the split point is inside the closed offset segment instead of 00320 // the two open rays before and after the offset segment endpoints. 00321 // The offset edge is bounded by its previous and next adjacent edges at the time of the event. Thus, the bisectors 00322 // of this edge and its previous/next adjacent edges (at the time of the event) detemine the offset vertices that 00323 // bound the opposite edge. 00324 // If the opposite edge is 'e' and its previous/next edges are "preve"/"nexte" then the split point is inside the offset 00325 // egde if it is NOT to the positive side of [preve,e] *and* NOT to the negative side o [e,nexte]. 00326 // (so this predicate answer half the question, at one and other side independenty). 00327 // If the split point is exacty over any of this bisectors then the split point ocurres exactly and one (or both) endpoints 00328 // of the opposite edge (so it is a pseudo-split event since the opposite edge is not itself split in two halfeves) 00329 // When this predicate is called to test (prev,e), e is the primary edge but since it is pass as e1, primary_is_0=false. 00330 // This causes the case of parallel but not collinear edges to return positive when the split point is before the source point of e* 00331 // (a positive result means invalid split). 00332 // Likewise, primary_is_0 must be true when testing (e,nexte) to return negative if the split point is past the target endpoint of e*. 00333 // (in the other cases there is no need to discrminate which is 'e' in the call since the edjes do not overlap). 00334 // 00335 // An edge event is a coallision of three *consecutive* edges, say, e1,e2 and e3. 00336 // The coallision causes e2 (the edge in the middle) to collapse and e1,e3 to become consecutive and form a new vertex. 00337 // In all cases there is an edge before e1, say e0, and after e3, say e4. 00338 // Testing for the validity of an edge event amounts to determine that (e1,e3) (the new vertex) is not before (e0,e1) nor 00339 // past (e3,e4). 00340 // Thus, and edge event is valid if the new vertex NOT to the positive side of [e0,e1] *and* NOT to the negative side o [e3,e4]. 00341 // 00342 // PRECONDITIONS: 00343 // There exist a single point 'p' corresponding to the event as given by the trisegment 00344 // e0 and e1 are known to be consectuve at the time of the event (even if they are not consecutive in the input polygon) 00345 // If e0 and e1 are not consecutive in the input, v01_event is the event that defined they very first offset vertex. 00346 // If e0 and e1 are consecutive, v01_event is null. 00347 // 00348 template<class K> 00349 Uncertain<Oriented_side> 00350 oriented_side_of_event_point_wrt_bisectorC2 ( intrusive_ptr< Trisegment_2<K> > const& event 00351 , Segment_2<K> const& e0 00352 , Segment_2<K> const& e1 00353 , intrusive_ptr< Trisegment_2<K> > const& v01_event // can be null 00354 , bool primary_is_0 00355 ) 00356 { 00357 typedef typename K::FT FT ; 00358 00359 typedef Point_2 <K> Point_2 ; 00360 typedef Line_2 <K> Line_2 ; 00361 typedef Trisegment_2<K> Trisegment_2 ; 00362 00363 Uncertain<Oriented_side> rResult = Uncertain<Oriented_side>::indeterminate(); 00364 00365 try 00366 { 00367 Point_2 p = validate(construct_offset_lines_isecC2(event)); 00368 00369 Line_2 l0 = validate(compute_normalized_line_ceoffC2(e0)) ; 00370 Line_2 l1 = validate(compute_normalized_line_ceoffC2(e1)) ; 00371 00372 CGAL_STSKEL_TRAITS_TRACE("Getting oriented side of point " << p2str(p) 00373 << " w.r.t bisector [" 00374 << s2str(e0) << ( primary_is_0 ? "*" : "" ) 00375 << "," 00376 << s2str(e1) << ( primary_is_0 ? "" : "*" ) 00377 << "]" 00378 ) ; 00379 00380 // Degenerate bisector? 00381 if ( certainly( are_edges_parallelC2(e0,e1) ) ) 00382 { 00383 CGAL_STSKEL_TRAITS_TRACE("Bisector is not angular." ) ; 00384 00385 // b01 is degenerate so we don't have an *angular bisector* but a *perpendicular* bisector. 00386 // We need to compute the actual bisector line. 00387 CGAL_assertion( v01_event || ( !v01_event && e0.target() == e1.source() ) ) ; 00388 00389 Point_2 v01 = v01_event ? validate( construct_offset_lines_isecC2(v01_event) ) : e1.source() ; 00390 00391 CGAL_STSKEL_TRAITS_TRACE("v01=" << p2str(v01) << ( v01_event ? " (from skelton node)" : "" ) ) ; 00392 00393 // (a,b,c) is a line perpedincular to the primary edge through v01. 00394 // If e0 and e1 are collinear this line is the actual perpendicular bisector. 00395 // 00396 // If e0 and e1 are parallel but not collinear (then neccesarrily facing each other) this line 00397 // is NOT the bisector, but the serves to determine the side of the point (projected along the primary ege) w.r.t vertex v01. 00398 00399 FT a, b, c ; 00400 perpendicular_through_pointC2( primary_is_0 ? l0.a() : l1.a() 00401 , primary_is_0 ? l0.b() : l1.b() 00402 , v01.x(), v01.y() 00403 , a, b, c 00404 ); 00405 00406 rResult = certified_side_of_oriented_lineC2(a,b,c,p.x(),p.y()); 00407 00408 CGAL_STSKEL_TRAITS_TRACE("Point is at " << rResult << " side of degenerate bisector through v01 " << p2str(v01)) ; 00409 } 00410 else // Valid (non-degenerate) angular bisector 00411 { 00412 // Scale distance from to the lines. 00413 FT sd_p_l0 = validate(l0.a() * p.x() + l0.b() * p.y() + l0.c()) ; 00414 FT sd_p_l1 = validate(l1.a() * p.x() + l1.b() * p.y() + l1.c()) ; 00415 00416 CGAL_STSKEL_TRAITS_TRACE("sd_p_l1=" << n2str(sd_p_l1) ) ; 00417 CGAL_STSKEL_TRAITS_TRACE("sd_p_l0=" << n2str(sd_p_l0) ) ; 00418 00419 Uncertain<bool> equal = CGAL_NTS certified_is_equal(sd_p_l0,sd_p_l1) ; 00420 if ( is_certain(equal) ) 00421 { 00422 if ( equal ) 00423 { 00424 CGAL_STSKEL_TRAITS_TRACE("Point is exactly at bisector"); 00425 00426 rResult = ON_ORIENTED_BOUNDARY; 00427 } 00428 else 00429 { 00430 Uncertain<bool> smaller = CGAL_NTS certified_is_smaller( validate(l0.a()*l1.b()), validate(l1.a()*l0.b()) ) ; 00431 if ( is_certain(smaller) ) 00432 { 00433 // Reflex bisector? 00434 if ( smaller ) 00435 { 00436 rResult = CGAL_NTS certified_is_smaller(sd_p_l0,sd_p_l1) ? ON_NEGATIVE_SIDE 00437 : ON_POSITIVE_SIDE ; 00438 00439 CGAL_STSKEL_TRAITS_TRACE("\nEvent point is at " << rResult << " side of reflex bisector" ) ; 00440 } 00441 else 00442 { 00443 rResult = CGAL_NTS certified_is_larger (sd_p_l0,sd_p_l1) ? ON_NEGATIVE_SIDE 00444 : ON_POSITIVE_SIDE ; 00445 00446 CGAL_STSKEL_TRAITS_TRACE("\nEvent point is at " << rResult << " side of convex bisector" ) ; 00447 } 00448 } 00449 } 00450 } 00451 } 00452 } 00453 catch( std::overflow_error const& ) 00454 { 00455 CGAL_STSKEL_TRAITS_TRACE("Unable to compute value due to overflow."); 00456 } 00457 catch( CGAL::Uncertain_conversion_exception const& ) 00458 { 00459 CGAL_STSKEL_TRAITS_TRACE("Indeterminate boolean expression."); 00460 } 00461 00462 return rResult ; 00463 00464 } 00465 00466 00467 // Given 2 triples of oriented straight line segments (l0,l1,l2) and (r0,r1,r2), such that 00468 // the offsets at time 'tl' for triple 'l' intersects in a point (lx,ly) and 00469 // the offsets at time 'tr' for triple 'r' intersects in a point (rx,ry) 00470 // returns true if "tl==tr" and "(lx,ly)==(rx,ry)" 00471 // PRECONDITIONS: 00472 // There exist single points at which the offset lines for 'l' and 'r' at 'tl', 'tr' intersect. 00473 // 00474 template<class K> 00475 Uncertain<bool> are_events_simultaneousC2 ( intrusive_ptr< Trisegment_2<K> > const& l, intrusive_ptr< Trisegment_2<K> > const& r ) 00476 { 00477 typedef typename K::FT FT ; 00478 00479 typedef Point_2<K> Point_2 ; 00480 typedef Line_2<K> Line_2 ; 00481 00482 typedef Trisegment_2<K> Trisegment_2 ; 00483 00484 typedef Rational<FT> Rational ; 00485 typedef Quotient<FT> Quotient ; 00486 00487 typedef optional<Rational> Optional_rational ; 00488 typedef optional<Point_2> Optional_point_2 ; 00489 00490 Uncertain<bool> rResult = Uncertain<bool>::indeterminate(); 00491 00492 Optional_rational lt_ = compute_offset_lines_isec_timeC2(l); 00493 Optional_rational rt_ = compute_offset_lines_isec_timeC2(r); 00494 00495 if ( lt_ && rt_ ) 00496 { 00497 Quotient lt = lt_->to_quotient(); 00498 Quotient rt = rt_->to_quotient(); 00499 00500 if ( CGAL_NTS certified_is_positive(lt) && CGAL_NTS certified_is_positive(rt) ) 00501 { 00502 Uncertain<bool> equal_times = CGAL_NTS certified_is_equal(lt,rt); 00503 00504 if ( is_certain(equal_times) ) 00505 { 00506 if ( equal_times ) 00507 { 00508 Optional_point_2 li = construct_offset_lines_isecC2(l); 00509 Optional_point_2 ri = construct_offset_lines_isecC2(r); 00510 00511 if ( li && ri ) 00512 rResult = CGAL_NTS logical_and( CGAL_NTS certified_is_equal(li->x(),ri->x()) 00513 , CGAL_NTS certified_is_equal(li->y(),ri->y()) 00514 ) ; 00515 } 00516 else rResult = false; 00517 } 00518 } 00519 00520 } 00521 return rResult; 00522 } 00523 00524 } // namespace CGAL_SS_i 00525 00526 CGAL_END_NAMESPACE 00527 00528 #endif // CGAL_STRAIGHT_SKELETON_PREDICATES_FTC2_H //
1.7.6.1