|
BWAPI
|
00001 // Copyright (c) 2003,2004,2005 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_site_2.h $ 00015 // $Id: Segment_Delaunay_graph_site_2.h 46222 2008-10-13 09:56:02Z afabri $ 00016 // 00017 // 00018 // Author(s) : Menelaos Karavelas <mkaravel@cse.nd.edu> 00019 00020 00021 00022 #ifndef CGAL_SEGMENT_DELAUNAY_GRAPH_SITE_H 00023 #define CGAL_SEGMENT_DELAUNAY_GRAPH_SITE_H 00024 00025 #include <iostream> 00026 #include <CGAL/assertions.h> 00027 00028 #include <CGAL/Segment_Delaunay_graph_2/basic.h> 00029 00030 #include <CGAL/Segment_Delaunay_graph_2/Constructions_C2.h> 00031 00032 CGAL_BEGIN_NAMESPACE 00033 00038 template <class Gt> 00039 class Segment_Delaunay_graph_site_2 00040 { 00041 public: 00042 typedef Gt Geom_traits; 00043 typedef typename Geom_traits::Point_2 Point_2; 00044 typedef typename Geom_traits::Segment_2 Segment_2; 00045 00046 protected: 00047 typedef typename Geom_traits::FT FT; 00048 typedef typename Geom_traits::RT RT; 00049 typedef Segment_Delaunay_graph_site_2<Geom_traits> Self; 00050 00051 public: 00052 Segment_Delaunay_graph_site_2() : type_(0) {} 00053 00054 static Self construct_site_2(const Point_2& p) { 00055 Self t; 00056 t.initialize_site(p); 00057 return t; 00058 } 00059 00060 // constructs segment site using the segment (p1,p2) 00061 static Self construct_site_2(const Point_2& p1, const Point_2& p2) { 00062 Self t; 00063 t.initialize_site(p1, p2); 00064 return t; 00065 } 00066 00067 // constructs point site using the point of intersection of the 00068 // segments (p1,p2) and (q1,q2) 00069 static Self construct_site_2(const Point_2& p1, const Point_2& p2, 00070 const Point_2& q1, const Point_2& q2) { 00071 Self t; 00072 t.initialize_site(p1, p2, q1, q2); 00073 return t; 00074 } 00075 00076 // constructs segment site using the points of intersection of the 00077 // segment-pairs (p1,p2)-(q1,q2) and (p1,p2)-(q3,q4) as endpoints; 00078 // the segment (p1,p2) is a segment that supports the actual segment 00079 static Self construct_site_2(const Point_2& p1, const Point_2& p2, 00080 const Point_2& q1, const Point_2& q2, 00081 const Point_2& r1, const Point_2& r2) { 00082 Self t; 00083 t.initialize_site(p1, p2, q1, q2, r1, r2); 00084 return t; 00085 } 00086 00087 // constructs segment site using either the source or the target of 00088 // (p1,p2) (that depends on the boolean is_first_exact) and the 00089 // intersection of (p1,p2) with (q1,q2) as the other endpoint 00090 static Self construct_site_2(const Point_2& p1, const Point_2& p2, 00091 const Point_2& q1, const Point_2& q2, 00092 bool is_first_exact) { 00093 Self t; 00094 t.initialize_site(p1, p2, q1, q2, is_first_exact); 00095 return t; 00096 } 00097 00098 public: 00099 bool is_defined() const { return type_ != 0; } 00100 bool is_point() const { return (type_ & 3) == 1; } 00101 bool is_segment() const { return (type_ & 3) == 2; } 00102 bool is_input() const { return !(type_ & 12); } 00103 bool is_input(unsigned int i) const { 00104 CGAL_precondition( is_segment() && i < 2 ); 00105 if ( i == 0 ) { return !(type_ & 4); } 00106 return !(type_ & 8); 00107 } 00108 00109 const Point_2& source_of_supporting_site() const { 00110 CGAL_precondition( is_segment() ); 00111 return p_[0]; 00112 } 00113 00114 const Point_2& target_of_supporting_site() const { 00115 CGAL_precondition( is_segment() ); 00116 return p_[1]; 00117 } 00118 00119 const Point_2& source_of_supporting_site(unsigned int i) const { 00120 CGAL_precondition( is_point() && !is_input() ); 00121 return (i == 0) ? p_[2] : p_[4]; 00122 } 00123 00124 const Point_2& target_of_supporting_site(unsigned int i) const { 00125 CGAL_precondition( is_point() && !is_input() ); 00126 return (i == 0) ? p_[3] : p_[5]; 00127 } 00128 00129 const Point_2& source_of_crossing_site(unsigned int i) const { 00130 CGAL_precondition( is_segment() && !is_input(i) ); 00131 return (i == 0) ? p_[2] : p_[4]; 00132 } 00133 00134 const Point_2& target_of_crossing_site(unsigned int i) const { 00135 CGAL_precondition( is_segment() && !is_input(i) ); 00136 return (i == 0) ? p_[3] : p_[5]; 00137 } 00138 00139 Point_2 point() const { 00140 CGAL_precondition ( is_point() ); 00141 if ( !is_input() ) { 00142 return compute_intersection_point(p_[2], p_[3], p_[4], p_[5]); 00143 } else { 00144 return p_[0]; 00145 } 00146 } 00147 00148 Segment_2 segment() const { 00149 CGAL_precondition ( is_segment() ); 00150 return Segment_2( source(), target() ); 00151 } 00152 00153 Point_2 source() const { 00154 CGAL_precondition ( is_segment() ); 00155 return compute_source(); 00156 } 00157 00158 Point_2 target() const { 00159 CGAL_precondition ( is_segment() ); 00160 return compute_target(); 00161 } 00162 00163 Self supporting_site() const { 00164 CGAL_precondition( is_segment() ); 00165 return construct_site_2(p_[0], p_[1]); 00166 } 00167 00168 Self supporting_site(unsigned int i) const { 00169 CGAL_precondition( is_point() && i < 2); 00170 CGAL_precondition( !is_input() ); 00171 if ( i == 0 ) { return construct_site_2(p_[2], p_[3]); } 00172 return construct_site_2(p_[4], p_[5]); 00173 } 00174 00175 Self crossing_site(unsigned int i) const { 00176 CGAL_precondition( is_segment() && !is_input() ); 00177 CGAL_precondition( i < 2 && !is_input(i) ); 00178 if ( i == 0 ) { 00179 return construct_site_2(p_[2], p_[3]); 00180 } else { 00181 return construct_site_2(p_[4], p_[5]); 00182 } 00183 } 00184 00185 Self source_site() const { 00186 CGAL_precondition( is_segment() ); 00187 if ( is_input() || is_input(0) ) { 00188 return construct_site_2(p_[0]); 00189 } else { 00190 return construct_site_2(p_[0], p_[1], p_[2], p_[3]); 00191 } 00192 } 00193 00194 Self target_site() const { 00195 CGAL_precondition( is_segment() ); 00196 if ( is_input() || is_input(1) ) { 00197 return construct_site_2(p_[1]); 00198 } else { 00199 return construct_site_2(p_[0], p_[1], p_[4], p_[5]); 00200 } 00201 } 00202 00203 protected: 00204 void initialize_site(const Point_2& p) 00205 { 00206 type_ = 1; 00207 p_[0] = p; 00208 } 00209 00210 void initialize_site(const Point_2& p1, const Point_2& p2) 00211 { 00212 type_ = 2; 00213 p_[0] = p1; 00214 p_[1] = p2; 00215 } 00216 void initialize_site(const Point_2& p1, const Point_2& p2, 00217 const Point_2& q1, const Point_2& q2) 00218 { 00219 // MK: Sort the segments s1 and s2 in lexicographical order so 00220 // that the computation of the intersection point is always 00221 // done in the same manner (?) 00222 type_ = 5; 00223 p_[2] = p1; 00224 p_[3] = p2; 00225 p_[4] = q1; 00226 p_[5] = q2; 00227 } 00228 00229 00230 void initialize_site(const Point_2& p1, const Point_2& p2, 00231 const Point_2& q1, const Point_2& q2, 00232 const Point_2& r1, const Point_2& r2) 00233 { 00234 type_ = 14; 00235 p_[0] = p1; 00236 p_[1] = p2; 00237 p_[2] = q1; 00238 p_[3] = q2; 00239 p_[4] = r1; 00240 p_[5] = r2; 00241 } 00242 00243 void initialize_site(const Point_2& p1, const Point_2& p2, 00244 const Point_2& q1, const Point_2& q2, 00245 bool is_first_exact) 00246 { 00247 type_ = (is_first_exact ? 10 : 6); 00248 p_[0] = p1; 00249 p_[1] = p2; 00250 if ( is_first_exact ) { 00251 p_[4] = q1; 00252 p_[5] = q2; 00253 } else { 00254 p_[2] = q1; 00255 p_[3] = q2; 00256 } 00257 } 00258 00259 Point_2 compute_source() const { 00260 CGAL_precondition( is_segment() ); 00261 if ( is_input() || is_input(0) ) { 00262 return p_[0]; 00263 } else { 00264 return compute_intersection_point(p_[0], p_[1], p_[2], p_[3]); 00265 } 00266 } 00267 00268 Point_2 compute_target() const { 00269 CGAL_precondition( is_segment() ); 00270 if ( is_input() || is_input(1) ) { 00271 return p_[1]; 00272 } else { 00273 return compute_intersection_point(p_[0], p_[1], p_[4], p_[5]); 00274 } 00275 } 00276 00277 // computes the point of intersection of the segments p1p2 and p3p4 00278 static Point_2 00279 compute_intersection_point(const Point_2& p1, const Point_2& p2, 00280 const Point_2& p3, const Point_2& p4) 00281 { 00282 RT x1 = p1.x(), y1 = p1.y(); 00283 RT x2 = p2.x(), y2 = p2.y(); 00284 RT x3 = p3.x(), y3 = p3.y(); 00285 RT x4 = p4.x(), y4 = p4.y(); 00286 00287 RT D = determinant(x2 - x1, x4 - x3, y2 - y1, y4 - y3); 00288 RT Dt = determinant(x3 - x1, x4 - x3, y3 - y1, y4 - y3); 00289 00290 RT t = Dt / D; 00291 00292 return Point_2(x1 + (x2 - x1) * t, y1 + (y2 - y1) * t); 00293 } 00294 00295 protected: 00296 Point_2 p_[6]; 00297 char type_; 00298 }; 00299 00300 //------------------------------------------------------------------------- 00301 00302 template <class R> 00303 std::ostream& 00304 operator<<(std::ostream& os, 00305 const Segment_Delaunay_graph_site_2<R>& s) 00306 { 00307 if (!s.is_defined()) 00308 return os << "u"; 00309 if (s.is_point()) 00310 return os << "p " << s.point (); 00311 return os << "s " << s.segment (); 00312 } 00313 00314 template <class R> 00315 std::istream & 00316 operator>>(std::istream &is, 00317 Segment_Delaunay_graph_site_2<R>& t) 00318 { 00319 typedef Segment_Delaunay_graph_site_2<R> Site_2; 00320 typedef typename Site_2::Point_2 Point_2; 00321 00322 char type; 00323 if (is >> type) { 00324 if (type == 'p') { 00325 Point_2 p; 00326 is >> p; 00327 t = Site_2::construct_site_2(p); 00328 } else if (type == 's') { 00329 Point_2 p1, p2; 00330 is >> p1 >> p2; 00331 t = Site_2::construct_site_2(p1, p2); 00332 } 00333 } 00334 return is; 00335 } 00336 00337 template < class R, class Stream > 00338 Stream& 00339 operator<<(Stream& str, Segment_Delaunay_graph_site_2<R>& t) 00340 { 00341 if ( t.is_defined() ) { 00342 if ( t.is_point() ) { 00343 str << "p " << t.point(); 00344 } else { 00345 str << "s " << t.segment().source() << " " 00346 << t.segment().target(); 00347 } 00348 } 00349 00350 return str; 00351 } 00352 00353 00354 CGAL_END_NAMESPACE 00355 00356 #endif // CGAL_SEGMENT_DELAUNAY_GRAPH_SITE_H
1.7.6.1