BWAPI
|
00001 // Copyright (c) 2000,2001 Utrecht University (The Netherlands), 00002 // ETH Zurich (Switzerland), Freie Universitaet Berlin (Germany), 00003 // INRIA Sophia-Antipolis (France), Martin-Luther-University Halle-Wittenberg 00004 // (Germany), Max-Planck-Institute Saarbruecken (Germany), RISC Linz (Austria), 00005 // and Tel-Aviv University (Israel). All rights reserved. 00006 // 00007 // This file is part of CGAL (www.cgal.org); you can redistribute it and/or 00008 // modify it under the terms of the GNU Lesser General Public License as 00009 // published by the Free Software Foundation; version 2.1 of the License. 00010 // See the file LICENSE.LGPL distributed with CGAL. 00011 // 00012 // Licensees holding a valid commercial license may use this file in 00013 // accordance with the commercial license agreement provided with the software. 00014 // 00015 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00016 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00017 // 00018 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Kernel_d/include/CGAL/Kernel_d/Ray_d.h $ 00019 // $Id: Ray_d.h 42932 2008-04-17 10:13:31Z spion $ 00020 // 00021 // 00022 // Author(s) : Michael Seel 00023 00024 #ifndef CGAL_RAY_D_H 00025 #define CGAL_RAY_D_H 00026 00027 #include <CGAL/Kernel_d/Pair_d.h> 00028 #include <CGAL/Kernel_d/Segment_d.h> 00029 #include <CGAL/Kernel_d/Line_d.h> 00030 #include <CGAL/Dimension.h> 00031 00032 CGAL_BEGIN_NAMESPACE 00033 00034 template <class R> 00035 std::istream& operator>>(std::istream&, Ray_d<R>&); 00036 template <class R> 00037 std::ostream& operator<<(std::ostream&, const Ray_d<R>&); 00038 00039 00040 /*{\Manpage {Ray_d}{R}{Rays in d-space}{r}}*/ 00041 00042 template <class p_R> 00043 class Ray_d : public Handle_for< Pair_d<p_R> > { 00044 typedef Pair_d<p_R> Pair; 00045 typedef Handle_for<Pair> Base; 00046 typedef Ray_d<p_R> Self; 00047 00048 using Base::ptr; 00049 00050 /*{\Mdefinition 00051 An instance of data type |Ray_d| is a ray in $d$-dimensional 00052 Euclidian space. It starts in a point called the source of |\Mvar| and 00053 it goes to infinity.}*/ 00054 00055 public: 00056 00057 typedef CGAL::Dynamic_dimension_tag Ambient_dimension; 00058 typedef CGAL::Dimension_tag<1> Feature_dimension; 00059 00060 /*{\Mtypes 4}*/ 00061 typedef p_R R; 00062 /*{\Mtypemember the representation type.}*/ 00063 typedef typename p_R::RT RT; 00064 /*{\Mtypemember the ring type.}*/ 00065 typedef typename p_R::FT FT; 00066 /*{\Mtypemember the field type.}*/ 00067 typedef typename p_R::LA LA; 00068 /*{\Mtypemember the linear algebra layer.}*/ 00069 00070 typedef typename Vector_d<R>::Base_vector Base_vector; 00071 00072 friend class Line_d<R>; 00073 friend class Segment_d<R>; 00074 00075 private: 00076 Ray_d(const Base& b) : Base(b) {} 00077 public: 00078 /*{\Mcreation 3}*/ 00079 00080 Ray_d() : Base( Pair() ) {} 00081 /*{\Mcreate introduces some ray in $d$-dimensional space }*/ 00082 00083 Ray_d(const Point_d<R>& p, const Point_d<R>& q) 00084 /*{\Mcreate introduces a ray through |p| and |q| and starting at |p|. 00085 \precond $p$ and $q$ are distinct and have the same dimension. }*/ 00086 : Base( Pair(p,q) ) 00087 { CGAL_assertion_msg(!ptr()->is_degenerate(), 00088 "Ray_d::constructor: the two points must be different." ); 00089 CGAL_assertion_msg((p.dimension()==q.dimension()), 00090 "Ray_d::constructor: the two points must have the same dimension." ); 00091 } 00092 00093 Ray_d(const Point_d<R>& p, const Direction_d<R>& dir) 00094 /*{\Mcreate introduces a ray starting in |p| with direction |dir|. 00095 \precond |p| and |dir| have the same dimension and |dir| is not 00096 trivial.}*/ 00097 : Base( Pair(p,p+dir.vector()) ) 00098 { CGAL_assertion_msg((p.dimension()==dir.dimension()), 00099 "Ray_d::constructor: the p and dir must have the same dimension." ); 00100 CGAL_assertion_msg(!dir.is_degenerate(), 00101 "Ray_d::constructor: dir must be non-degenerate." ); 00102 } 00103 00104 Ray_d(const Segment_d<R>& s) 00105 /*{\Mcreate introduces a ray through |s.source()| and |s.target()| and 00106 starting at |s.source()|. \precond $s$ is not trivial. }*/ 00107 : Base( s ) 00108 { CGAL_assertion_msg(!s.is_degenerate(), 00109 "Ray_d::constructor: segment is trivial."); 00110 } 00111 00112 Ray_d(const Ray_d<R>& r) : Base(r) {} 00113 00114 /*{\Moperations 3 3}*/ 00115 00116 int dimension() const { return (ptr()->_p[0].dimension()); } 00117 /*{\Mop returns the dimension of the underlying space.}*/ 00118 00119 Point_d<R> source() const { return (ptr()->_p[0]); } 00120 /*{\Mop returns the source point of |\Mvar|. }*/ 00121 00122 Point_d<R> point(int i) const 00123 /*{\Mop returns a point on |\Mvar|. |point(0)| is the source. 00124 |point(i)|, with $i>0$, is different from the source. \precond $i 00125 \geq 0$.}*/ 00126 { return (ptr()->_p[i%2]); } 00127 00128 Direction_d<R> direction() const 00129 /*{\Mop returns the direction of |\Mvar|. }*/ 00130 { return ptr()->direction(); } 00131 00132 inline Line_d<R> supporting_line() const; 00133 /*{\Mop returns the supporting line of |\Mvar|.}*/ 00134 00135 Ray_d<R> opposite() const 00136 /*{\Mop returns the ray with direction opposite to |\Mvar| 00137 and starting in |source|.}*/ 00138 { return Ray_d<R>(source(),-direction()); } 00139 00140 Ray_d<R> transform(const Aff_transformation_d<R>& t) const 00141 /*{\Mop returns $t(l)$. }*/ 00142 { return Ray_d<R>(point(0).transform(t),point(1).transform(t)); } 00143 00144 Ray_d<R> operator+(const Vector_d<R>& v) const 00145 /*{\Mbinop returns |\Mvar+v|, i.e., |\Mvar| translated by vector $v$.}*/ 00146 { return Ray_d<R>(point(0)+v, point(1)+v); } 00147 00148 bool has_on(const Point_d<R>& p) const 00149 /*{\Mop A point is on |r|, iff it is equal to the source of |r|, or if it is 00150 in the interior of |r|.}*/ 00151 { typename R::Position_on_line_d pos; FT l; 00152 if (pos(p,point(0),point(1),l)) return (FT(0)<=l); 00153 return false; 00154 } 00155 00156 /*{\Mtext \headerline{Non-Member Functions}}*/ 00157 00158 bool operator==(const Ray_d<R>& r1) const 00159 { if ( this->identical(r1) ) return true; 00160 if ( dimension() != r1.dimension() ) return false; 00161 return source() == r1.source() && 00162 direction() == r1.direction(); 00163 } 00164 00165 bool operator!=(const Ray_d<R>& r1) 00166 { return !operator==(r1); } 00167 00168 friend std::istream& operator>> <> 00169 (std::istream&, Ray_d<R>&); 00170 friend std::ostream& operator<< <> 00171 (std::ostream&, const Ray_d<R>&); 00172 00173 }; // end of class 00174 00175 template <class R> 00176 bool parallel(const Ray_d<R>& r1, const Ray_d<R>& r2) 00177 /*{\Mfunc returns true if the unoriented supporting lines of |r1| and |r2| 00178 are parallel and false otherwise. }*/ 00179 { return (r1.direction() == r2.direction()) || 00180 (r1.direction() == -(r2.direction())); 00181 } 00182 00183 template <class R> 00184 std::istream& operator>>(std::istream& I, Ray_d<R>& r) 00185 { r.copy_on_write(); r.ptr()->read(I); 00186 CGAL_assertion_msg(r.point(0)!=r.point(1), 00187 "Line_d::operator>>: trivial ray."); 00188 CGAL_assertion_msg(r.point(0).dimension()==r.point(1).dimension(), 00189 "Ray_d::operator>>: dimensions disagree."); 00190 return I; 00191 } 00192 00193 template <class R> 00194 std::ostream& operator<<(std::ostream& O, const Ray_d<R>& r) 00195 { r.ptr()->print(O,"Ray_d"); return O; } 00196 00197 /*{\Mimplementation 00198 Rays are implemented by a pair of points as an item type. All 00199 operations like creation, initialization, tests, direction 00200 calculation, input and output on a ray $r$ take time 00201 $O(|r.dimension()|)$. |dimension()|, coordinate and point access, and 00202 identity test take constant time. The space requirement is 00203 $O(|r.dimension()|)$.}*/ 00204 00205 00206 CGAL_END_NAMESPACE 00207 #endif // CGAL_RAYHD_H 00208 //----------------------- end of file ---------------------------------- 00209