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/HyperplaneCd.h $ 00019 // $Id: HyperplaneCd.h 42940 2008-04-17 13:32:52Z spion $ 00020 // 00021 // Author(s) : Michael Seel 00022 00023 #ifndef CGAL_HYPERPLANECD_H 00024 #define CGAL_HYPERPLANECD_H 00025 00026 #include <CGAL/basic.h> 00027 00028 CGAL_BEGIN_NAMESPACE 00029 #define PointCd PointCd2 00030 00031 template <class FT, class LA> 00032 std::istream& operator>>(std::istream&, HyperplaneCd<FT,LA>&); 00033 template <class FT, class LA> 00034 std::ostream& operator<<(std::ostream&, const HyperplaneCd<FT,LA>&); 00035 00036 template <class _FT, class _LA> 00037 class HyperplaneCd : public Handle_for< Tuple_d<_FT,_LA> > { 00038 typedef Tuple_d<_FT,_LA> Tuple; 00039 typedef Handle_for<Tuple> Base; 00040 typedef HyperplaneCd<_FT,_LA> Self; 00041 00042 using Base::ptr; 00043 00044 const typename _LA::Vector& vector_rep() const { return ptr()->v; } 00045 _FT& entry(int i) { return ptr()->v[i]; } 00046 const _FT& entry(int i) const { return ptr()->v[i]; } 00047 void invert_rep() { ptr()->invert(); } 00048 00049 public: 00050 typedef _FT RT; 00051 typedef _FT FT; 00052 typedef _LA LA; 00053 typedef typename Tuple::const_iterator Coefficient_const_iterator; 00054 00055 HyperplaneCd(int d = 0) : Base( Tuple(d+1) ) {} 00056 00057 template <class InputIterator> 00058 HyperplaneCd(int d, InputIterator first, InputIterator last, const FT& D) 00059 : Base( Tuple(d+1,first,last,D) ) {} 00060 00061 template <class InputIterator> 00062 HyperplaneCd(int d, InputIterator first, InputIterator last) 00063 : Base( Tuple(d+1,first,last) ) {} 00064 00065 template <class ForwardIterator> 00066 void 00067 construct_from_points(ForwardIterator first, ForwardIterator last, 00068 const PointCd<FT,LA>& o, Oriented_side side) 00069 { 00070 // inline due to template parameter 00071 TUPLE_DIM_CHECK(first,last,hyperplane::construction); 00072 CGAL_assertion_msg((first->dimension()==o.dimension()), 00073 "hyperplane::construction: dimensions disagree."); 00074 00075 int d = first->dimension(); // we are in $d$ - dimensional space 00076 int m = std::distance(first,last); // |P| has $m$ points 00077 typename LA::Matrix A(m,d + 1); 00078 00079 for (int i = 0; i < m; i++) { /* define $i$-th equation */ 00080 for (int j = 0; j < d; j++) 00081 A(i,j) = first->cartesian(j); // $j$ - th coord of $i$-th point 00082 A(i,d) = 1; 00083 ++first; 00084 } 00085 typename LA::Matrix spanning_vecs; // columns span solution 00086 int dim = LA::homogeneous_linear_solver(A,spanning_vecs); 00087 00088 CGAL_assertion_msg(dim != 0, 00089 "HyperplaneCd::constructor: set P is full dimensional."); 00090 00091 if (side == ON_ORIENTED_BOUNDARY) 00092 { ptr()->v = spanning_vecs.column(0); return; } 00093 00094 FT sum = 0; int j; 00095 for (j = 0; j < dim; j++) { 00096 for (int i = 0; i < d; i++) 00097 sum += spanning_vecs(i,j)*o.cartesian(i); 00098 sum += spanning_vecs(d,j); 00099 if (sum != FT(0)) break; 00100 } 00101 00102 CGAL_assertion_msg(j != dim, 00103 "HyperplaneCd::constructor: cannot use o to determine side."); 00104 00105 ptr()->v = spanning_vecs.column(j); 00106 if ( ( CGAL_NTS sign(sum) > 0 && side == ON_NEGATIVE_SIDE ) || 00107 ( CGAL_NTS sign(sum) < 0 && side == ON_POSITIVE_SIDE ) ) 00108 invert_rep(); 00109 } 00110 00111 template <class ForwardIterator> 00112 HyperplaneCd(ForwardIterator first, ForwardIterator last, 00113 const PointCd<FT,LA>& o, 00114 Oriented_side side = ON_ORIENTED_BOUNDARY) 00115 : Base( Tuple(o.dimension()+1) ) 00116 { construct_from_points(first,last,o,side); } 00117 00118 HyperplaneCd(const PointCd<FT,LA>& p, const DirectionCd<FT,LA>& dir) 00119 : Base( Tuple(p.dimension()+1) ) 00120 { 00121 int d = p.dimension(); 00122 CGAL_assertion_msg((dir.dimension() == d), 00123 "HyperplaneCd::constructor: parameter dimensions disagree."); 00124 00125 FT sum = 0; 00126 for (int i = 0; i < d; i++) { 00127 sum += dir.delta(i)*p.cartesian(i); 00128 entry(i) = dir.delta(i); 00129 } 00130 entry(d) = -sum; 00131 } 00132 00133 HyperplaneCd(const FT& a, const FT& b, const FT& c) : 00134 Base( Tuple(a,b,c,MatchHelper()) ) {} 00135 00136 HyperplaneCd(int a, int b, int c) : 00137 Base( Tuple(FT(a),FT(b),FT(c),MatchHelper()) ) {} 00138 00139 HyperplaneCd(const FT& a, const FT& b, const FT& c, const FT& d) : 00140 Base( Tuple(a,b,c,d) ) {} 00141 00142 HyperplaneCd(int a, int b, int c, int d) : 00143 Base( Tuple(FT(a),FT(b),FT(c),FT(d)) ) {} 00144 00145 HyperplaneCd(const HyperplaneCd<FT,LA>& h) : Base(h) {} 00146 ~HyperplaneCd() {} 00147 00148 int dimension() const { return ptr()->size()-1; } 00149 00150 FT operator[](int i) const 00151 { CGAL_assertion_msg((0<=i && i<=(dimension())), 00152 "HyperplaneCd::op[]: index out of range."); 00153 return entry(i); } 00154 00155 FT coefficient(int i) const { return entry(i); } 00156 00157 const typename LA::Vector& coefficient_vector() const 00158 { return vector_rep(); } 00159 00160 Coefficient_const_iterator coefficients_begin() const 00161 { return ptr()->begin(); } 00162 Coefficient_const_iterator coefficients_end() const 00163 { return ptr()->end(); } 00164 00165 inline VectorCd<FT,LA> orthogonal_vector() const; 00166 00167 DirectionCd<FT,LA> orthogonal_direction() const 00168 { return orthogonal_vector().direction(); } 00169 00170 FT value_at(const PointCd<FT,LA>& p) const 00171 { CGAL_assertion_msg((dimension()==p.dimension()), 00172 "HyperplaneCd::value_at: dimensions disagree."); 00173 FT res(0); 00174 for (int i=0; i<dimension(); ++i) 00175 res += coefficient(i)*p.cartesian(i); 00176 res += coefficient(dimension()); 00177 return res; 00178 } 00179 00180 Oriented_side oriented_side(const PointCd<FT,LA>& p) const 00181 { 00182 CGAL_assertion_msg(dimension()==p.dimension(), 00183 "HyperplaneCd::oriented_side: dimensions do not agree."); 00184 return CGAL_NTS sign(value_at(p)); 00185 } 00186 00187 bool has_on(const PointCd<FT,LA>& p) const 00188 { return (oriented_side(p) == ON_ORIENTED_BOUNDARY); } 00189 00190 bool has_on_boundary(const PointCd<FT,LA>& p) const 00191 { return (oriented_side(p) == ON_ORIENTED_BOUNDARY); } 00192 00193 bool has_on_positive_side(const PointCd<FT,LA>& p) const 00194 { return (oriented_side(p) == ON_POSITIVE_SIDE); } 00195 00196 bool has_on_negative_side(const PointCd<FT,LA>& p) const 00197 { return (oriented_side(p) == ON_NEGATIVE_SIDE); } 00198 00199 HyperplaneCd<FT,LA> transform(const Aff_transformationCd<FT,LA>& t) const 00200 { Aff_transformationCd<FT,LA> t_inv = t.inverse(); 00201 typename LA::Vector res = LA::transpose(t_inv.matrix())*vector_rep(); 00202 if ( t_inv.is_odd() ) res = -res; 00203 return HyperplaneCd<FT,LA>(dimension(),res.begin(),res.end()); } 00204 00205 static Comparison_result weak_cmp( 00206 const HyperplaneCd<FT,LA>&, const HyperplaneCd<FT,LA>&); 00207 static Comparison_result strong_cmp( 00208 const HyperplaneCd<FT,LA>&, const HyperplaneCd<FT,LA>&); 00209 00210 bool operator==(const HyperplaneCd<FT,LA>& h2) const 00211 { if (this->identical(h2)) return true; 00212 if (dimension()!=h2.dimension()) return false; 00213 return HyperplaneCd<FT,LA>::strong_cmp(*this,h2) == EQUAL; 00214 } 00215 bool operator!=(const HyperplaneCd<FT,LA>& h2) const 00216 { return !operator==(h2); } 00217 00218 friend std::istream& operator>> <> 00219 (std::istream&, HyperplaneCd<FT,LA>&); 00220 friend std::ostream& operator<< <> 00221 (std::ostream&, const HyperplaneCd<FT,LA>&); 00222 00223 }; // end of class HyperplaneCd 00224 00225 template <class FT, class LA> 00226 bool weak_equality(const HyperplaneCd<FT,LA>& h1, 00227 const HyperplaneCd<FT,LA>& h2) 00228 /*{\Mfunc test for weak equality. }*/ 00229 { if (h1.identical(h2)) return true; 00230 if (h1.dimension()!=h2.dimension()) return false; 00231 return HyperplaneCd<FT,LA>::weak_cmp(h1,h2) == EQUAL; 00232 } 00233 00234 #undef PointCd 00235 CGAL_END_NAMESPACE 00236 #endif // CGAL_HYPERPLANECD_H 00237 //----------------------- end of file ----------------------------------