Array.h

00001 //===========================================================================
00002 // GoTools - SINTEF Geometry Tools version 1.1
00003 //
00004 // GoTools module: CORE
00005 //
00006 // Copyright (C) 2000-2007 SINTEF ICT, Applied Mathematics, Norway.
00007 //
00008 // This program is free software; you can redistribute it and/or          
00009 // modify it under the terms of the GNU General Public License            
00010 // as published by the Free Software Foundation version 2 of the License. 
00011 //
00012 // This program is distributed in the hope that it will be useful,        
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of         
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          
00015 // GNU General Public License for more details.                           
00016 //
00017 // You should have received a copy of the GNU General Public License      
00018 // along with this program; if not, write to the Free Software            
00019 // Foundation, Inc.,                                                      
00020 // 59 Temple Place - Suite 330,                                           
00021 // Boston, MA  02111-1307, USA.                                           
00022 //
00023 // Contact information: E-mail: tor.dokken@sintef.no                      
00024 // SINTEF ICT, Department of Applied Mathematics,                         
00025 // P.O. Box 124 Blindern,                                                 
00026 // 0314 Oslo, Norway.                                                     
00027 //
00028 // Other licenses are also available for this software, notably licenses
00029 // for:
00030 // - Building commercial software.                                        
00031 // - Building software whose source code you wish to keep private.        
00032 //===========================================================================
00033 #ifndef _ARRAY_H
00034 #define _ARRAY_H
00035 
00036 
00037 #include <boost/static_assert.hpp>
00038 #include "errormacros.h"
00039 #include <iostream>
00040 #include <cmath>
00041 
00042 
00043 
00044 namespace Go
00045 {
00048 
00049 
00057     template <typename T, int Dim>
00058     class Array
00059     {
00060     private:
00061         T p_[Dim];
00062 
00063     public:
00065         Array()
00066         {}
00069         Array(T x, T y)
00070         {
00071             BOOST_STATIC_ASSERT(Dim == 2);
00072             p_[0] = x;
00073             p_[1] = y;
00074         }
00077         Array(T x, T y, T z)
00078         {
00079             BOOST_STATIC_ASSERT(Dim == 3);
00080             p_[0] = x;
00081             p_[1] = y;
00082             p_[2] = z;
00083         }
00086         Array(T x, T y, T z, T w)
00087         {
00088             BOOST_STATIC_ASSERT(Dim == 4);
00089             p_[0] = x;
00090             p_[1] = y;
00091             p_[2] = z;
00092             p_[3] = w;
00093         }
00095         Array(const Array& v)
00096         {
00097             setValue(v.p_);
00098         }
00102         template <typename RandomAccessIterator>
00103         explicit Array(RandomAccessIterator start)
00104         {
00105             setValue(start);
00106         }
00110         template <typename RandomAccessIterator>
00111         void setValue(RandomAccessIterator from)
00112         {
00113             for (int i = 0; i < Dim; ++i)
00114                 p_[i] = from[i];
00115         }
00118         template <typename U>
00119         explicit Array(const Array<U, Dim>& v)
00120         {
00121             setValueConvert(v.begin());
00122         }
00127         template <typename RandomAccessIterator>
00128         void setValueConvert(RandomAccessIterator from)
00129         {
00130             for (int i = 0; i < Dim; ++i)
00131                 p_[i] = T(from[i]);
00132         }
00134         Array& operator = (const Array& v)
00135         {
00136             if (&v != this) {
00137                 setValue(v.p_);
00138             }
00139             return *this;
00140         }
00141 
00144         void read(std::istream& is)
00145         {
00146             for (int i = 0; i < Dim; ++i)
00147                 is >> p_[i];
00148         }
00152         void write(std::ostream& os) const
00153         {
00154             os.precision(16);
00155             for (int i = 0; i < Dim-1; ++i)
00156                 os << p_[i] << ' ';
00157             os << p_[Dim-1];
00158         }
00159 
00162         const T& x() const { return p_[0]; }
00165         T& x()       { return p_[0]; }
00168         const T& y() const { return p_[1]; }
00171         T& y()       { return p_[1]; }
00174         const T& z() const { return p_[2]; }
00177         T& z()       { return p_[2]; }
00178 
00180         const T& operator [] (int i) const { return p_[i]; }
00182         T& operator [] (int i)       { return p_[i]; }
00183 
00185         const T* begin() const { return p_; }
00187         T* begin()       { return p_; }
00189         const T* end() const { return p_+Dim; }
00191         T* end()       { return p_+Dim; }
00192 
00194         int size() const { return Dim; }
00195 
00198         T length2() const
00199         {
00200             T l2(0.0);
00201             for (int i = 0; i < Dim; ++i)
00202                 l2 += p_[i]*p_[i];
00203             return l2;
00204         }
00207         T length() const
00208         {
00209             return sqrt(length2());
00210         }
00213         T lengthInf() const
00214         {
00215             T linf(0.0);
00216             for (int i = 0; i < Dim; ++i) {
00217                 linf = std::max(linf, std::abs(p_[i]));
00218             }
00219             return linf;
00220         }
00224         T dist2(const Array &v) const
00225         {
00226             T l2(0.0);
00227             T d;
00228             for (int i = 0; i < Dim; ++i) {
00229                 d = p_[i] - v.p_[i];
00230                 l2 += d*d;
00231             }
00232             return l2;
00233         }
00237         T dist(const Array &v) const
00238         {
00239             return sqrt(dist2(v));
00240         }
00244         T distInf(const Array &v) const
00245         {
00246             T linf(0.0);
00247             T d;
00248             for (int i = 0; i < Dim; ++i) {
00249                 d = p_[i] - v.p_[i];
00250                 linf = std::max(linf, std::abs(d));
00251             }
00252             return linf;
00253         }
00254 
00257         void normalize()
00258         {
00259             (*this) /= length();
00260         }
00261 
00263         Array operator + (const Array &v) const
00264         {
00265             Array res(*this);
00266             res += v;
00267             return res;
00268         }
00269 
00271         bool operator == (const Array &v) const
00272         {
00273           for (int i = 0; i < Dim; ++i)
00274             if (p_[i] != v.p_[i])
00275               return false;
00276           return true;
00277         }
00279         Array& operator += (const Array &v)
00280         {
00281             for (int i = 0; i < Dim; ++i)
00282                 p_[i] += v.p_[i];
00283             return *this;
00284         }
00285 
00287         Array operator - (const Array &v) const
00288         {
00289             Array res(*this);
00290             res -= v;
00291             return res;
00292         }
00293 
00295         Array& operator -=(const Array &v)
00296         {
00297             for (int i = 0; i < Dim; ++i)
00298                 p_[i] -= v.p_[i];
00299             return *this;
00300         }
00301 
00302         
00304         Array operator * (T d) const
00305         {
00306             Array res(*this);
00307             res *= d;
00308             return res;
00309         }
00310 
00312         Array& operator *= (T d)
00313         {
00314             for (int i = 0; i < Dim; ++i)
00315                 p_[i] *= d;
00316             return *this;
00317         }
00318 
00320         Array  operator / (double d) const
00321         {
00322             Array res(*this);
00323             res /= d;
00324             return res;
00325         }
00327         Array& operator /= (double d)
00328         {
00329             for (int i = 0; i < Dim; ++i)
00330                 p_[i] /= d;
00331             return *this;
00332         }
00333 
00335         Array operator - () const
00336         {
00337             Array res(*this);
00338             for (int i = 0; i < Dim; ++i)
00339                 res.p_[i] = - p_[i];
00340             return res;
00341         }
00342 
00345         T operator * (const Array &v) const
00346         {
00347             T res(0.0);
00348             for (int i = 0; i < Dim; ++i)
00349                 res += p_[i]*v.p_[i];
00350             return res;
00351         }
00352 
00355         Array operator % (const Array &v) const
00356         {
00357             BOOST_STATIC_ASSERT(Dim == 3);
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         }
00362 
00365         Array cross(const Array &v) const
00366         {
00367             return operator%(v);
00368         }
00369 
00372         T cosAngle(const Array& v) const
00373         {
00374             return ((*this)*v)/(length()*v.length());
00375         }
00376 
00379         T angle(const Array& v) const
00380         {
00381             return acos(cosAngle(v));
00382         }
00383 
00385         void zero()
00386         {
00387             for (int i = 0; i < Dim; ++i) {
00388                 p_[i] = T(0.0);
00389             }
00390         }
00391 
00392     };
00393 
00395     typedef Array<double, 2> Vector2D;
00397     typedef Array<double, 3> Vector3D;
00399     typedef Array<double, 4> Vector4D;
00400 
00401 
00403     template<typename T, int Dim>
00404     inline Go::Array<T, Dim> operator * (T d, const Go::Array<T, Dim>& v)
00405     { return v*d; }
00406 
00408     template <typename T, int Dim>
00409     inline std::istream& operator >> (std::istream& is, Go::Array<T,Dim>& v)
00410     { v.read(is); return is; }
00411 
00413     template <typename T, int Dim>
00414     inline std::ostream& operator << (std::ostream& os, const Go::Array<T,Dim>& v)
00415     { v.write(os); return os; }
00416 
00417 
00419 } // namespace Go
00420 
00421 
00422 #endif // _ARRAY_H
00423 
00424 
00425 
00426 

Generated on Mon Jun 11 14:48:18 2007 for GoTools Core Library by  doxygen 1.5.1