|
BWAPI
|
00001 // Copyright (c) 2003,2004,2005,2006 INRIA Sophia-Antipolis (France) and 00002 // Notre Dame University (U.S.A.). 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/Segment_Delaunay_graph_2/include/CGAL/Segment_Delaunay_graph_2/Basic_predicates_C2.h $ 00015 // $Id: Basic_predicates_C2.h 45156 2008-08-26 13:40:26Z spion $ 00016 // 00017 // 00018 // Author(s) : Menelaos Karavelas <mkaravel@cse.nd.edu> 00019 00020 00021 00022 00023 #ifndef CGAL_SEGMENT_DELAUNAY_GRAPH_2_BASIC_PREDICATES_C2_H 00024 #define CGAL_SEGMENT_DELAUNAY_GRAPH_2_BASIC_PREDICATES_C2_H 00025 00026 00027 #include <CGAL/Segment_Delaunay_graph_2/basic.h> 00028 #include <CGAL/enum.h> 00029 #include <CGAL/Segment_Delaunay_graph_2/Sqrt_extension_1.h> 00030 #include <CGAL/Segment_Delaunay_graph_2/Sqrt_extension_2.h> 00031 00032 00033 00034 CGAL_BEGIN_NAMESPACE 00035 00036 CGAL_SEGMENT_DELAUNAY_GRAPH_2_BEGIN_NAMESPACE 00037 00038 template<class K> 00039 struct Basic_predicates_C2 00040 { 00041 public: 00042 //------------------------------------------------------------------- 00043 // TYPES 00044 //------------------------------------------------------------------- 00045 00046 typedef typename K::RT RT; 00047 typedef typename K::FT FT; 00048 typedef typename K::Point_2 Point_2; 00049 typedef typename K::Segment_2 Segment_2; 00050 typedef typename K::Site_2 Site_2; 00051 typedef typename K::Oriented_side Oriented_side; 00052 typedef typename K::Comparison_result Comparison_result; 00053 typedef typename K::Sign Sign; 00054 typedef typename K::Orientation Orientation; 00055 typedef typename K::Boolean Boolean; 00056 00057 typedef CGAL::Sqrt_extension_1<RT> Sqrt_1; 00058 typedef CGAL::Sqrt_extension_2<RT> Sqrt_2; 00059 typedef CGAL::Sqrt_extension_2<Sqrt_1> Sqrt_3; 00060 private: 00061 typedef typename Algebraic_structure_traits<RT>::Algebraic_category RT_Category; 00062 typedef typename Algebraic_structure_traits<FT>::Algebraic_category FT_Category; 00063 public: 00064 typedef Boolean_tag<CGAL::is_same_or_derived<Field_with_sqrt_tag,RT_Category>::value> RT_Has_sqrt; 00065 typedef Boolean_tag<CGAL::is_same_or_derived<Field_with_sqrt_tag,FT_Category>::value> FT_Has_sqrt; 00066 00067 static const RT_Has_sqrt& rt_has_sqrt() { 00068 static RT_Has_sqrt has_sqrt; 00069 return has_sqrt; 00070 } 00071 00072 static const FT_Has_sqrt& ft_has_sqrt() { 00073 static FT_Has_sqrt has_sqrt; 00074 return has_sqrt; 00075 } 00076 00077 00078 class Line_2 00079 { 00080 private: 00081 RT a_, b_, c_; 00082 00083 public: 00084 Line_2() : a_(1), b_(0), c_(0) {} 00085 Line_2(const RT& a, const RT& b, const RT& c) 00086 : a_(a), b_(b), c_(c) {} 00087 00088 RT a() const { return a_; } 00089 RT b() const { return b_; } 00090 RT c() const { return c_; } 00091 00092 00093 Oriented_side oriented_side(const Point_2& p) const 00094 { 00095 Sign s = CGAL::sign(a_ * p.x() + b_ * p.y() + c_); 00096 if ( s == ZERO ) { return ON_ORIENTED_BOUNDARY; } 00097 return (s == POSITIVE) ? ON_POSITIVE_SIDE : ON_NEGATIVE_SIDE; 00098 } 00099 }; 00100 00101 class Homogeneous_point_2 00102 { 00103 private: 00104 RT hx_, hy_, hw_; 00105 00106 public: 00107 Homogeneous_point_2() : hx_(0), hy_(0), hw_(1) {} 00108 Homogeneous_point_2(const RT& hx, const RT& hy, const RT& hw) 00109 : hx_(hx), hy_(hy), hw_(hw) 00110 { 00111 CGAL_precondition( !(CGAL::is_zero(hw_)) ); 00112 } 00113 00114 Homogeneous_point_2(const Point_2& p) 00115 : hx_(p.x()), hy_(p.y()), hw_(1) {} 00116 00117 Homogeneous_point_2(const Homogeneous_point_2& other) 00118 : hx_(other.hx_), hy_(other.hy_), hw_(other.hw_) {} 00119 00120 RT hx() const { return hx_; } 00121 RT hy() const { return hy_; } 00122 RT hw() const { return hw_; } 00123 00124 FT x() const { return hx_ / hw_; } 00125 FT y() const { return hy_ / hw_; } 00126 }; 00127 00128 public: 00129 //------------------------------------------------------------------- 00130 // CONVERSIONS 00131 //------------------------------------------------------------------- 00132 00133 static FT compute_sqrt(const FT& x, const Tag_true&) 00134 { 00135 return CGAL::sqrt( x ); 00136 } 00137 00138 static FT compute_sqrt(const FT& x, const Tag_false&) 00139 { 00140 return FT( CGAL::sqrt( CGAL::to_double(x) ) ); 00141 } 00142 00143 static 00144 FT to_ft(const Sqrt_1& x) 00145 { 00146 FT sqrt_c = compute_sqrt( x.c(), ft_has_sqrt() ); 00147 return x.a() + x.b() * sqrt_c; 00148 } 00149 00150 static 00151 FT to_ft(const Sqrt_3& x) 00152 { 00153 FT sqrt_e = compute_sqrt( to_ft(x.e()), ft_has_sqrt() ); 00154 FT sqrt_f = compute_sqrt( to_ft(x.f()), ft_has_sqrt() ); 00155 FT sqrt_ef = sqrt_e * sqrt_f; 00156 return to_ft(x.a()) + to_ft(x.b()) * sqrt_e 00157 + to_ft(x.c()) * sqrt_f + to_ft(x.d()) * sqrt_ef; 00158 } 00159 00160 public: // compute_supporting_line(q.supporting_segment(), a1, b1, c1); 00161 // compute_supporting_line(r.supporting_segment(), a2, b2, c2); 00162 00163 //------------------------------------------------------------------- 00164 // BASIC CONSTRUCTIONS 00165 //------------------------------------------------------------------- 00166 00167 #if 1 00168 static 00169 Line_2 compute_supporting_line(const Site_2& s) 00170 { 00171 RT a, b, c; 00172 compute_supporting_line(s, a, b, c); 00173 return Line_2(a, b, c); 00174 } 00175 00176 static 00177 void compute_supporting_line(const Site_2& s, 00178 RT& a, RT& b, RT& c) 00179 { 00180 a = s.source().y() - s.target().y(); 00181 b = s.target().x() - s.source().x(); 00182 c = s.source().x() * s.target().y() - s.target().x() * s.source().y(); 00183 } 00184 #else 00185 static 00186 Line_2 compute_supporting_line(const Segment_2& s) 00187 { 00188 RT a, b, c; 00189 compute_supporting_line(s, a, b, c); 00190 return Line_2(a, b, c); 00191 } 00192 00193 static 00194 void compute_supporting_line(const Segment_2& s, 00195 RT& a, RT& b, RT& c) 00196 { 00197 a = s.source().y() - s.target().y(); 00198 b = s.target().x() - s.source().x(); 00199 c = s.source().x() * s.target().y() - s.target().x() * s.source().y(); 00200 } 00201 #endif 00202 00203 static 00204 Homogeneous_point_2 00205 compute_projection(const Line_2& l, const Point_2& p) 00206 { 00207 RT ab = l.a() * l.b(); 00208 00209 RT hx = CGAL::square(l.b()) * p.x() 00210 - ab * p.y() - l.a() * l.c(); 00211 RT hy = CGAL::square(l.a()) * p.y() 00212 - ab * p.x() - l.b() * l.c(); 00213 RT hw = CGAL::square(l.a()) + CGAL::square(l.b()); 00214 00215 return Homogeneous_point_2(hx, hy, hw); 00216 } 00217 00218 00219 static 00220 Homogeneous_point_2 00221 projection_on_line(const Line_2& l, const Point_2& p) 00222 { 00223 RT ab = l.a() * l.b(); 00224 00225 RT hx = CGAL::square(l.b()) * p.x() 00226 - ab * p.y() - l.a() * l.c(); 00227 RT hy = CGAL::square(l.a()) * p.y() 00228 - ab * p.x() - l.b() * l.c(); 00229 RT hw = CGAL::square(l.a()) + CGAL::square(l.b()); 00230 00231 return Homogeneous_point_2(hx, hy, hw); 00232 } 00233 00234 00235 static 00236 Homogeneous_point_2 00237 midpoint(const Point_2& p1, const Point_2& p2) 00238 { 00239 RT hx = p1.x() + p2.x(); 00240 RT hy = p1.y() + p2.y(); 00241 RT hw = RT(2); 00242 00243 return Homogeneous_point_2(hx, hy, hw); 00244 } 00245 00246 static 00247 Homogeneous_point_2 00248 midpoint(const Homogeneous_point_2& p1, 00249 const Homogeneous_point_2& p2) 00250 { 00251 RT hx = p1.hx() * p2.hw() + p2.hx() * p1.hw(); 00252 RT hy = p1.hy() * p2.hw() + p2.hy() * p1.hw(); 00253 RT hw = RT(2) * p1.hw() * p2.hw(); 00254 00255 return Homogeneous_point_2(hx, hy, hw); 00256 } 00257 00258 static 00259 Line_2 compute_perpendicular(const Line_2& l, const Point_2& p) 00260 { 00261 RT a, b, c; 00262 a = -l.b(); 00263 b = l.a(); 00264 c = l.b() * p.x() - l.a() * p.y(); 00265 return Line_2(a, b, c); 00266 } 00267 00268 static 00269 Line_2 opposite_line(const Line_2& l) 00270 { 00271 return Line_2(-l.a(), -l.b(), -l.c()); 00272 } 00273 00274 static 00275 RT compute_squared_distance(const Point_2& p, const Point_2& q) 00276 { 00277 return CGAL::square(p.x() - q.x()) + CGAL::square(p.y() - q.y()); 00278 } 00279 00280 static 00281 std::pair<RT,RT> 00282 compute_squared_distance(const Point_2& p, const Line_2& l) 00283 { 00284 RT d2 = CGAL::square(l.a() * p.x() + l.b() * p.y() + l.c()); 00285 RT n2 = CGAL::square(l.a()) + CGAL::square(l.b()); 00286 return std::pair<RT,RT>(d2, n2); 00287 } 00288 00289 public: 00290 //------------------------------------------------------------------- 00291 // BASIC PREDICATES 00292 //------------------------------------------------------------------- 00293 static 00294 Comparison_result 00295 compare_squared_distances_to_line(const Line_2& l, const Point_2& p, 00296 const Point_2& q) 00297 { 00298 RT d2_lp = CGAL::square(l.a() * p.x() + l.b() * p.y() + l.c()); 00299 RT d2_lq = CGAL::square(l.a() * q.x() + l.b() * q.y() + l.c()); 00300 00301 return CGAL::compare(d2_lp, d2_lq); 00302 } 00303 00304 static 00305 Comparison_result 00306 compare_squared_distances_to_lines(const Point_2& p, 00307 const Line_2& l1, 00308 const Line_2& l2) 00309 { 00310 RT d2_l1 = CGAL::square(l1.a() * p.x() + l1.b() * p.y() + l1.c()); 00311 00312 RT d2_l2 = CGAL::square(l2.a() * p.x() + l2.b() * p.y() + l2.c()); 00313 00314 RT n1 = CGAL::square(l1.a()) + CGAL::square(l1.b()); 00315 RT n2 = CGAL::square(l2.a()) + CGAL::square(l2.b()); 00316 00317 return CGAL::compare(d2_l1 * n2, d2_l2 * n1); 00318 } 00319 00320 static 00321 Oriented_side 00322 oriented_side_of_line(const Line_2& l, const Point_2& p) 00323 { 00324 return CGAL::sign(l.a() * p.x() + l.b() * p.y() + l.c()); 00325 } 00326 00327 static 00328 Oriented_side 00329 oriented_side_of_line(const Line_2& l, const Homogeneous_point_2& p) 00330 { 00331 Sign s1 = 00332 CGAL::sign(l.a() * p.hx() + l.b() * p.hy() + l.c() * p.hw()); 00333 Sign s_hw = CGAL::sign(p.hw()); 00334 00335 return s1 * s_hw; 00336 } 00337 00338 00339 static 00340 bool is_on_positive_halfspace(const Line_2& l, const Segment_2& s) 00341 { 00342 Oriented_side os1, os2; 00343 00344 os1 = oriented_side_of_line(l, s.source()); 00345 os2 = oriented_side_of_line(l, s.target()); 00346 00347 return ( (os1 == ON_POSITIVE_SIDE && os2 != ON_NEGATIVE_SIDE) || 00348 (os1 != ON_NEGATIVE_SIDE && os2 == ON_POSITIVE_SIDE) ); 00349 } 00350 00351 }; 00352 00353 00354 CGAL_SEGMENT_DELAUNAY_GRAPH_2_END_NAMESPACE 00355 00356 CGAL_END_NAMESPACE 00357 00358 00359 #endif // CGAL_SEGMENT_DELAUNAY_GRAPH_2_BASIC_PREDICATES_C2_H
1.7.6.1