//=========================================================================== // GoTools Core - SINTEF Geometry Tools Core library, version 2.0.1 // // Copyright (C) 2000-2007, 2010 SINTEF ICT, Applied Mathematics, Norway. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., // 59 Temple Place - Suite 330, // Boston, MA 02111-1307, USA. // // Contact information: E-mail: tor.dokken@sintef.no // SINTEF ICT, Department of Applied Mathematics, // P.O. Box 124 Blindern, // 0314 Oslo, Norway. // // Other licenses are also available for this software, notably licenses // for: // - Building commercial software. // - Building software whose source code you wish to keep private. //=========================================================================== 00013 #ifndef _ARRAY_H 00014 #define _ARRAY_H 00015 00016 00017 #include <boost/static_assert.hpp> 00018 #include "GoTools/utils/errormacros.h" 00019 #include <iostream> 00020 #include <cmath> 00021 00022 00023 00024 namespace Go 00025 { 00026 00034 template <typename T, int Dim> 00035 class Array 00036 { 00037 private: 00038 T p_[Dim]; 00039 00040 public: 00042 Array() 00043 {} 00044 00048 explicit Array(T x) 00049 { 00050 for (int i=0; i<Dim; i++) 00051 p_[i] = x; 00052 } 00053 00056 Array(T x, T y) 00057 { 00058 BOOST_STATIC_ASSERT(Dim == 2); 00059 p_[0] = x; 00060 p_[1] = y; 00061 } 00064 Array(T x, T y, T z) 00065 { 00066 BOOST_STATIC_ASSERT(Dim == 3); 00067 p_[0] = x; 00068 p_[1] = y; 00069 p_[2] = z; 00070 } 00073 Array(T x, T y, T z, T w) 00074 { 00075 BOOST_STATIC_ASSERT(Dim == 4); 00076 p_[0] = x; 00077 p_[1] = y; 00078 p_[2] = z; 00079 p_[3] = w; 00080 } 00082 Array(const Array& v) 00083 { 00084 setValue(v.p_); 00085 } 00089 template <typename RandomAccessIterator> 00090 explicit Array(RandomAccessIterator start) 00091 { 00092 setValue(start); 00093 } 00097 template <typename RandomAccessIterator> 00098 void setValue(RandomAccessIterator from) 00099 { 00100 for (int i = 0; i < Dim; ++i) 00101 p_[i] = from[i]; 00102 } 00105 template <typename U> 00106 explicit Array(const Array<U, Dim>& v) 00107 { 00108 setValueConvert(v.begin()); 00109 } 00114 template <typename RandomAccessIterator> 00115 void setValueConvert(RandomAccessIterator from) 00116 { 00117 for (int i = 0; i < Dim; ++i) 00118 p_[i] = T(from[i]); 00119 } 00121 Array& operator = (const Array& v) 00122 { 00123 if (&v != this) { 00124 setValue(v.p_); 00125 } 00126 return *this; 00127 } 00128 00131 void read(std::istream& is) 00132 { 00133 for (int i = 0; i < Dim; ++i) 00134 is >> p_[i]; 00135 } 00139 void write(std::ostream& os) const 00140 { 00141 os.precision(16); 00142 for (int i = 0; i < Dim-1; ++i) 00143 os << p_[i] << ' '; 00144 os << p_[Dim-1]; 00145 } 00146 00149 const T& x() const { return p_[0]; } 00152 T& x() { return p_[0]; } 00155 const T& y() const { return p_[1]; } 00158 T& y() { return p_[1]; } 00161 const T& z() const { return p_[2]; } 00164 T& z() { return p_[2]; } 00165 00167 const T& operator [] (int i) const { return p_[i]; } 00169 T& operator [] (int i) { return p_[i]; } 00170 00172 const T* begin() const { return p_; } 00174 T* begin() { return p_; } 00176 const T* end() const { return p_+Dim; } 00178 T* end() { return p_+Dim; } 00179 00181 int size() const { return Dim; } 00182 00185 T length2() const 00186 { 00187 T l2(0.0); 00188 for (int i = 0; i < Dim; ++i) 00189 l2 += p_[i]*p_[i]; 00190 return l2; 00191 } 00194 T length() const 00195 { 00196 #ifdef __BORLANDC__ 00197 return std::sqrt(length2()); 00198 #else 00199 return sqrt(length2()); 00200 #endif 00201 } 00204 T lengthInf() const 00205 { 00206 T linf(0.0); 00207 for (int i = 0; i < Dim; ++i) { 00208 linf = std::max(linf, std::abs(p_[i])); 00209 } 00210 return linf; 00211 } 00215 T dist2(const Array &v) const 00216 { 00217 T l2(0.0); 00218 T d; 00219 for (int i = 0; i < Dim; ++i) { 00220 d = p_[i] - v.p_[i]; 00221 l2 += d*d; 00222 } 00223 return l2; 00224 } 00228 T dist(const Array &v) const 00229 { 00230 #ifdef __BORLANDC__ 00231 return std::sqrt(dist2(v)); 00232 #else 00233 return sqrt(dist2(v)); 00234 #endif 00235 } 00239 T distInf(const Array &v) const 00240 { 00241 T linf(0.0); 00242 T d; 00243 for (int i = 0; i < Dim; ++i) { 00244 d = p_[i] - v.p_[i]; 00245 linf = std::max(linf, std::abs(d)); 00246 } 00247 return linf; 00248 } 00249 00252 void normalize() 00253 { 00254 (*this) /= length(); 00255 } 00256 00258 Array operator + (const Array &v) const 00259 { 00260 Array res(*this); 00261 res += v; 00262 return res; 00263 } 00264 00266 bool operator == (const Array &v) const 00267 { 00268 for (int i = 0; i < Dim; ++i) 00269 if (p_[i] != v.p_[i]) 00270 return false; 00271 return true; 00272 } 00274 Array& operator += (const Array &v) 00275 { 00276 for (int i = 0; i < Dim; ++i) 00277 p_[i] += v.p_[i]; 00278 return *this; 00279 } 00280 00282 Array operator - (const Array &v) const 00283 { 00284 Array res(*this); 00285 res -= v; 00286 return res; 00287 } 00288 00290 Array& operator -=(const Array &v) 00291 { 00292 for (int i = 0; i < Dim; ++i) 00293 p_[i] -= v.p_[i]; 00294 return *this; 00295 } 00296 00297 00299 Array operator * (T d) const 00300 { 00301 Array res(*this); 00302 res *= d; 00303 return res; 00304 } 00305 00307 Array& operator *= (T d) 00308 { 00309 for (int i = 0; i < Dim; ++i) 00310 p_[i] *= d; 00311 return *this; 00312 } 00313 00315 Array operator / (double d) const 00316 { 00317 Array res(*this); 00318 res /= d; 00319 return res; 00320 } 00322 Array& operator /= (double d) 00323 { 00324 for (int i = 0; i < Dim; ++i) 00325 p_[i] /= d; 00326 return *this; 00327 } 00328 00330 Array operator - () const 00331 { 00332 Array res(*this); 00333 for (int i = 0; i < Dim; ++i) 00334 res.p_[i] = - p_[i]; 00335 return res; 00336 } 00337 00340 T operator * (const Array &v) const 00341 { 00342 T res(0.0); 00343 for (int i = 0; i < Dim; ++i) 00344 res += p_[i]*v.p_[i]; 00345 return res; 00346 } 00347 00350 Array operator % (const Array &v) const 00351 { 00352 BOOST_STATIC_ASSERT(Dim == 3); 00353 #ifdef __BORLANDC__ 00354 return Array<T, Dim>(p_[1]*v.p_[2] - p_[2]*v.p_[1], 00355 p_[2]*v.p_[0] - p_[0]*v.p_[2], 00356 p_[0]*v.p_[1] - p_[1]*v.p_[0]); 00357 #else 00358 return Array(p_[1]*v.p_[2] - p_[2]*v.p_[1], 00359 p_[2]*v.p_[0] - p_[0]*v.p_[2], 00360 p_[0]*v.p_[1] - p_[1]*v.p_[0]); 00361 #endif 00362 } 00363 00366 Array cross(const Array &v) const 00367 { 00368 return operator%(v); 00369 } 00370 00373 T cosAngle(const Array& v) const 00374 { 00375 T cosang = ((*this)*v)/(length()*v.length()); 00376 // Roundoff may push us outside the [-1, 1] interval, 00377 // which may lead to no end of trouble. 00378 cosang = std::max(T(-1.0), cosang); 00379 cosang = std::min(T(1.0), cosang); 00380 return cosang; 00381 } 00382 00385 T angle(const Array& v) const 00386 { 00387 #ifdef __BORLANDC__ 00388 return std::acos(cosAngle(v)); 00389 #else 00390 return acos(cosAngle(v)); 00391 #endif 00392 } 00393 00395 void zero() 00396 { 00397 for (int i = 0; i < Dim; ++i) { 00398 p_[i] = T(0.0); 00399 } 00400 } 00401 00402 }; 00403 00405 typedef Array<double, 2> Vector2D; 00407 typedef Array<double, 3> Vector3D; 00409 typedef Array<double, 4> Vector4D; 00410 00411 00413 template<typename T, int Dim> 00414 inline Go::Array<T, Dim> operator * (T d, const Go::Array<T, Dim>& v) 00415 { return v*d; } 00416 00418 template <typename T, int Dim> 00419 inline std::istream& operator >> (std::istream& is, Go::Array<T,Dim>& v) 00420 { v.read(is); return is; } 00421 00423 template <typename T, int Dim> 00424 inline std::ostream& operator << (std::ostream& os, const Go::Array<T,Dim>& v) 00425 { v.write(os); return os; } 00426 00427 00428 } // namespace Go 00429 00430 00431 #endif // _ARRAY_H 00432 00433 00434
Generated on Tue Sep 21 15:44:17 2010 for GoTools Core by  doxygen 1.6.3