|
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/Aff_transformationCd.h $ 00019 // $Id: Aff_transformationCd.h 42940 2008-04-17 13:32:52Z spion $ 00020 // 00021 // Author(s) : Michael Seel 00022 00023 #ifndef CGAL_AFF_TRANSFORMATIONCD_H 00024 #define CGAL_AFF_TRANSFORMATIONCD_H 00025 00026 #include <CGAL/basic.h> 00027 #include <CGAL/aff_transformation_tags.h> 00028 #include <CGAL/Handle_for.h> 00029 #include <CGAL/rational_rotation.h> 00030 00031 CGAL_BEGIN_NAMESPACE 00032 00033 template <class FT, class LA > class Aff_transformationCd; 00034 template <class FT, class LA > class Aff_transformationCd_rep; 00035 00036 template <class FT, class LA> 00037 class Aff_transformationCd_rep 00038 { 00039 friend class Aff_transformationCd<FT,LA>; 00040 typedef typename LA::Matrix Matrix; 00041 Matrix M_; 00042 public: 00043 Aff_transformationCd_rep(int d) : M_(d+1) {} 00044 Aff_transformationCd_rep(const Matrix& M_init) : M_(M_init) {} 00045 ~Aff_transformationCd_rep() {} 00046 }; 00047 00048 template <class _FT, class _LA> 00049 class Aff_transformationCd : 00050 public Handle_for< Aff_transformationCd_rep<_FT,_LA> > { 00051 00052 typedef Aff_transformationCd_rep<_FT,_LA> Rep; 00053 typedef Handle_for<Rep> Base; 00054 typedef Aff_transformationCd<_FT,_LA> Self; 00055 00056 using Base::ptr; 00057 00058 public: 00059 typedef _FT RT; 00060 typedef _FT FT; 00061 typedef _LA LA; 00062 typedef typename _LA::Matrix Matrix; 00063 typedef typename _LA::Vector Vector; 00064 00065 Aff_transformationCd(int d = 0) : Base( Rep(d) ) {} 00066 00067 Aff_transformationCd(int d, Identity_transformation) : Base( Rep(d) ) 00068 { for (int i = 0; i <= d; ++i) ptr()->M_(i,i) = FT(1); } 00069 00070 Aff_transformationCd(const Matrix& M) : Base( Rep(M) ) 00071 { CGAL_assertion_msg((M.row_dimension()==M.column_dimension()), 00072 "Aff_transformationCd:: initialization matrix not quadratic."); 00073 int d = M.row_dimension(),i; 00074 for (i=0; i<d-1; ++i) CGAL_assertion(M(d-1,i)==FT(0)); 00075 CGAL_assertion(M(d-1,d-1)==FT(1)); 00076 } 00077 00078 template <typename Forward_iterator> 00079 Aff_transformationCd(Scaling, Forward_iterator start, Forward_iterator end) : 00080 Base( Rep(std::distance(start,end)-1) ) 00081 /*{\Mcreate introduces the transformation of $d$-space specified by a 00082 diagonal matrix with entries |set [start,end)| on the diagonal 00083 (a scaling of the space). \precond |set [start,end)| is a vector of 00084 dimension $d+1$.}*/ 00085 { int i=0; while (start != end) { ptr()->M_(i,i) = *start++;++i; } } 00086 00087 00088 Aff_transformationCd(Translation, const VectorCd<RT,LA>& v) : 00089 Base( Rep(v.dimension()) ) 00090 { int d = v.dimension(); 00091 for (int i = 0; i < d; ++i) { 00092 ptr()->M_(i,i) = FT(1); 00093 ptr()->M_(i,d) = v.cartesian(i); 00094 } 00095 ptr()->M_(d,d) = FT(1); 00096 } 00097 00098 Aff_transformationCd(int d, Scaling, const RT& num, const RT& den) 00099 : Base( Rep(d) ) 00100 { Matrix& M = ptr()->M_; 00101 for (int i = 0; i < d; ++i) M(i,i) = num/den; 00102 M(d,d) = FT(1); 00103 } 00104 00105 Aff_transformationCd(int d, Rotation, 00106 const RT& sin_num, const RT& cos_num, const RT& den, 00107 int e1 = 0, int e2 = 1) : Base( Rep(d) ) 00108 { 00109 CGAL_assertion_msg((sin_num*sin_num + cos_num*cos_num == den*den), 00110 "planar_rotation: rotation parameters disobey precondition."); 00111 CGAL_assertion_msg((0<=e1 && e1<=e2 && e2<d), 00112 "planar_rotation: base vector indices wrong."); 00113 Matrix& M = ptr()->M_; 00114 for (int i=0; i<d; i++) M(i,i) = 1; 00115 M(e1,e1) = cos_num/den; M(e1,e2) = -sin_num/den; 00116 M(e2,e1) = sin_num/den; M(e2,e2) = cos_num/den; 00117 M(d,d) = FT(1); 00118 } 00119 00120 Aff_transformationCd(int d, Rotation, const DirectionCd<RT,LA>& dir, 00121 const RT& eps_num, const RT& eps_den, int e1 = 0, int e2 = 1) 00122 : Base( Rep(d) ) 00123 { 00124 CGAL_assertion(dir.dimension()==2); 00125 Matrix& M = ptr()->M_; 00126 for (int i=0; i<d; i++) M(i,i) = FT(1); 00127 RT sin_num, cos_num, denom; 00128 rational_rotation_approximation(dir.dx(), dir.dy(), 00129 sin_num, cos_num, denom, 00130 eps_num, eps_den); 00131 00132 M(e1,e1) = cos_num/denom; M(e1,e2) = -sin_num/denom; 00133 M(e2,e1) = sin_num/denom; M(e2,e2) = cos_num/denom; 00134 M(d,d) = FT(1); 00135 } 00136 00137 int dimension() const 00138 { return ptr()->M_.row_dimension()-1; } 00139 00140 const Matrix& matrix() const { return ptr()->M_; } 00141 00142 bool is_odd() const 00143 { return LA::sign_of_determinant(matrix())<0; } 00144 00145 Vector operator()(const Vector& v) const 00146 { CGAL_assertion(matrix().row_dimension()-1==v.dimension()); 00147 const Matrix& M = ptr()->M_; 00148 int i,j,d(v.dimension()); 00149 Vector res(d); 00150 for (i=0; i<d; ++i) { // all rows 00151 FT cres(0); 00152 for (j=0; j<d; ++j) cres+=M(i,j)*v[j]; // per row 00153 cres += M(i,d); 00154 res[i]=cres; 00155 } 00156 return res; 00157 } 00158 00159 Vector transform_linearly(const Vector& v) const 00160 { CGAL_assertion(matrix().row_dimension()-1==v.dimension()); 00161 const Matrix& M = ptr()->M_; 00162 int i,j,d(v.dimension()); 00163 Vector res(d); 00164 for (i=0; i<d; ++i) { // all rows 00165 FT cres(0); 00166 for (j=0; j<d; ++j) cres+=M(i,j)*v[j]; // per row 00167 res[i]=cres; 00168 } 00169 return res; 00170 } 00171 00172 00173 Aff_transformationCd<RT,LA> inverse() const 00174 { Aff_transformationCd<RT,LA> Inv; RT D; 00175 Vector dummy; 00176 if ( !LA::inverse(matrix(),Inv.ptr()->M_,D,dummy) ) 00177 CGAL_error_msg("Aff_transformationCd::inverse: not invertible."); 00178 if ( D < FT(0) ) Inv.ptr()->M_ = -Inv.ptr()->M_; 00179 return Inv; 00180 } 00181 00182 Aff_transformationCd<RT,LA> 00183 operator*(const Aff_transformationCd<RT,LA>& s) const 00184 { CGAL_assertion_msg((dimension()==s.dimension()), 00185 "Aff_transformationCd::operator*: dimensions disagree."); 00186 return Aff_transformationCd<RT,LA>(matrix()*s.matrix()); 00187 } 00188 00189 bool operator==(const Aff_transformationCd<RT,LA>& a1) const 00190 { if ( this->identical(a1) ) return true; 00191 return ( matrix() == a1.matrix() ); 00192 } 00193 bool operator!=(const Aff_transformationCd<RT,LA>& a1) const 00194 { return !operator==(a1); } 00195 00196 }; // Aff_transformationCd 00197 00198 template <class FT, class LA> 00199 std::ostream& operator<<( 00200 std::ostream& os, const Aff_transformationCd<FT,LA>& t) 00201 { os << t.matrix(); return os; } 00202 00203 template <class FT, class LA> 00204 std::istream& operator>>( 00205 std::istream& is, Aff_transformationCd<FT,LA>& t) 00206 { typename LA::Matrix M(t.dimension()); 00207 is >> M; t = Aff_transformationCd<FT,LA>(M); 00208 return is; 00209 } 00210 00211 00212 CGAL_END_NAMESPACE 00213 #endif // CGAL_AFF_TRANSFORMATIONCD_H 00214
1.7.6.1