BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Segment_Delaunay_graph_site_2.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines