00001 #ifndef __UTIL_VECTOR_H
00002 #define __UTIL_VECTOR_H
00003
00009 #include <config.h>
00010 #include <iostream>
00011 #include <cassert>
00012 #include <cstdarg>
00013 #include <QTextStream>
00014 #include <util/static_assert.h>
00015 #include <storage/fwd.h>
00016 #include <cmath>
00017
00021 namespace util
00022 {
00031 template <size_t dim,class T = double>
00032 class Vector
00033 {
00034 protected:
00035 T elems[dim];
00036
00037 public:
00038 typedef T value_type;
00039 typedef T& reference_type;
00040 typedef const T& const_reference_type;
00041 typedef T* pointer_type;
00042 typedef const T* const_pointer_type;
00043 typedef T* iterator;
00044 typedef const T* const_iterator;
00045
00049 Vector(const Vector& vec)
00050 {
00051 for(size_t i = 0 ; i < dim ; i++)
00052 elems[i] = vec[i];
00053 }
00054
00055 #ifdef USE_CXX0X
00056 Vector(Vector&&) = default;
00057 Vector& operator=(Vector&&) = default;
00058 #endif
00059
00063 template <size_t d1, class T1>
00064 explicit Vector(const Vector<d1,T1>& vec)
00065 {
00066 if(d1 < dim)
00067 {
00068 for(size_t i = 0 ; i < d1 ; ++i)
00069 elems[i] = vec[i];
00070 for(size_t i = d1 ; i < dim ; ++i)
00071 elems[i] = 0;
00072 }
00073 else
00074 {
00075 for(size_t i = 0 ; i < dim ; ++i)
00076 elems[i] = vec[i];
00077 }
00078 }
00079
00088 template <class Vec>
00089 explicit Vector(const Vec& el)
00090 {
00091 for(size_t i = 0 ; i < dim ; i++)
00092 elems[i] = el[i];
00093 }
00094
00100 Vector( const T& x = T() )
00101 {
00102 for( size_t i = 0 ; i < dim ; ++i )
00103 elems[ i ] = x;
00104 }
00105
00109 explicit Vector( const T& x, const T& y )
00110 {
00111 STATIC_ASSERT( dim == 2, "Constructor with 2 arguments can be used only for 2D vectors" );
00112 elems[ 0 ] = x;
00113 elems[ 1 ] = y;
00114 }
00115
00119 explicit Vector( const T& x, const T& y, const T& z )
00120 {
00121 STATIC_ASSERT( dim == 3, "Constructor with 3 arguments can be used only for 3D vectors" );
00122 elems[ 0 ] = x;
00123 elems[ 1 ] = y;
00124 elems[ 2 ] = z;
00125 }
00126
00130 explicit Vector( const T& x, const T& y, const T& z, const T& t )
00131 {
00132 STATIC_ASSERT( dim == 4, "Constructor with 3 arguments can be used only for 3D vectors" );
00133 elems[ 0 ] = x;
00134 elems[ 1 ] = y;
00135 elems[ 2 ] = z;
00136 elems[ 3 ] = t;
00137 }
00138
00142 static size_t size() { return dim; }
00143
00147 T* data() { return elems; }
00148
00152 iterator begin() { return elems; }
00156 const_iterator begin() const { return elems; }
00157
00161 iterator end() { return elems+dim; }
00165 const_iterator end() const { return elems+dim; }
00166
00170 const T* c_data() const { return elems; }
00171
00175 Vector operator-(void) const
00176 {
00177 Vector ans;
00178 for(size_t i = 0 ; i < dim ; i++)
00179 ans[i] = -elems[i];
00180
00181 return ans;
00182 }
00183
00187 Vector operator+(const Vector& vec) const
00188 {
00189 Vector ans(*this);
00190 ans += vec;
00191 return ans;
00192 }
00193
00197 Vector operator-(const Vector& vec) const
00198 {
00199 Vector ans(*this);
00200 ans -= vec;
00201 return ans;
00202 }
00203
00207 Vector mult(const Vector& vec) const
00208 {
00209 Vector ans;
00210 for(size_t i = 0 ; i < dim ; i++)
00211 ans[i] = elems[i] * vec.elems[i];
00212 return ans;
00213 }
00214
00218 Vector operator*(const T& scalar) const
00219 {
00220 Vector ans(*this);
00221 ans *= scalar;
00222 return ans;
00223 }
00224
00228 Vector operator/(const T& scalar) const
00229 {
00230 Vector ans(*this);
00231 ans /= scalar;
00232 return ans;
00233 }
00234
00238 Vector operator/(const Vector& vec) const
00239 {
00240 Vector ans = *this;
00241 ans /= vec;
00242 return ans;
00243 }
00244
00248 Vector& operator/=(const Vector& vec)
00249 {
00250 for(size_t i = 0 ; i < dim ; ++i)
00251 elems[i] /= vec.elems[i];
00252 return *this;
00253 }
00254
00258 friend Vector operator*(const T& scalar,const Vector& vec)
00259 {
00260 Vector ans;
00261 for(size_t i = 0 ; i < dim ; i++)
00262 ans[i] = scalar * vec.elems[i];
00263
00264 return ans;
00265 }
00266
00270 T operator*(const Vector& vec) const
00271 {
00272 T ans = 0;
00273 for(size_t i = 0 ; i < dim ; i++)
00274 ans += elems[i] * vec.elems[i];
00275
00276 return ans;
00277 }
00278
00282 Vector& operator=(const Vector& vec)
00283 {
00284 for(size_t i = 0 ; i < dim ; i++)
00285 elems[i] = vec.elems[i];
00286
00287 return (*this);
00288 }
00289
00293 Vector& operator+=(const Vector& vec)
00294 {
00295 for(size_t i = 0 ; i < dim ; i++)
00296 elems[i] += vec.elems[i];
00297 return *this;
00298 }
00299
00303 Vector& operator-=(const Vector& vec)
00304 {
00305 for(size_t i = 0 ; i < dim ; i++)
00306 elems[i] -= vec.elems[i];
00307 return *this;
00308 }
00309
00313 Vector& operator*=(const T& scalar)
00314 {
00315 for(size_t i = 0 ; i < dim ; i++)
00316 elems[i] *= scalar;
00317 return *this;
00318 }
00319
00323 template <typename T1>
00324 Vector& operator*=(const T1& scalar)
00325 {
00326 for(size_t i = 0 ; i < dim ; i++)
00327 elems[i] = (T)(elems[i]*scalar);
00328 return *this;
00329 }
00330
00334 Vector& operator/=(const T& scalar)
00335 {
00336 for(size_t i = 0 ; i < dim ; ++i)
00337 elems[i] /= scalar;
00338 return *this;
00339 }
00340
00344 template <typename T1>
00345 Vector& operator/=(const T1& scalar)
00346 {
00347 for(size_t i = 0 ; i < dim ; ++i)
00348 elems[i] = (T)(elems[i] / scalar);
00349 return *this;
00350 }
00351
00355 bool operator==(const Vector& vec) const
00356 {
00357 for(size_t i = 0 ; i < dim ; i++)
00358 if(elems[i] != vec.elems[i])
00359 return false;
00360
00361 return true;
00362 }
00363
00367 bool operator!=(const Vector& vec) const
00368 {
00369 return (!((*this) == vec));
00370 }
00371
00375 T& operator[](size_t idx)
00376 {
00377 return elems[idx];
00378 }
00379
00383 T operator[](size_t idx) const
00384 {
00385 return elems[idx];
00386 }
00387
00391 T norm() const
00392 {
00393 return std::sqrt(normsq());
00394 }
00395
00399 T normsq() const
00400 {
00401 T ans = 0;
00402 for(size_t i = 0 ; i < dim ; i++)
00403 ans += elems[i] * elems[i];
00404
00405 return ans;
00406 }
00407
00411 Vector& normalize(void)
00412 {
00413 T sz = norm();
00414 return ((*this) /= sz);
00415 }
00416
00420 Vector normalized(void) const
00421 {
00422 Vector ans(*this);
00423 return ans.normalize();
00424 }
00425
00426 bool iszero(void)
00427 {
00428 for(size_t i = 0 ; i < dim ; i++)
00429 if(elems[i] != 0)
00430 return false;
00431 return true;
00432 }
00433
00434 Vector& zero(void)
00435 {
00436 for(size_t i = 0 ; i < dim ; i++)
00437 elems[i] = 0;
00438 return (*this);
00439 }
00440
00444 void set( const T& x )
00445 {
00446 STATIC_ASSERT( dim == 1, "Set method with 1 argument can be used only for 1D vectors." );
00447 elems[ 0 ] = x;
00448 }
00449
00453 void set( const T& x, const T& y )
00454 {
00455 STATIC_ASSERT( dim == 2, "Set method with 2 arguments can be used only for 2D vectors." );
00456 elems[ 0 ] = x;
00457 elems[ 1 ] = y;
00458 }
00459
00463 void set( const T& x, const T& y, const T& z )
00464 {
00465 STATIC_ASSERT( dim == 3, "Set method with 3 arguments can be used only for 3D vectors." );
00466 elems[ 0 ] = x;
00467 elems[ 1 ] = y;
00468 elems[ 2 ] = z;
00469 }
00470
00474 void set( const T& x, const T& y, const T& z, const T& t )
00475 {
00476 STATIC_ASSERT( dim == 4, "Set method with 4 arguments can be used only for 4D vectors." );
00477 elems[ 0 ] = x;
00478 elems[ 1 ] = y;
00479 elems[ 2 ] = z;
00480 elems[ 3 ] = t;
00481 }
00482
00486 Vector& operator=( const T& value )
00487 {
00488 for( size_t i = 0 ; i < dim ; ++i )
00489 {
00490 elems[ i ] = value;
00491 }
00492 return *this;
00493 }
00494
00498 Vector cross( const Vector& other ) const
00499 {
00500 STATIC_ASSERT( dim == 3, "Cross product is only defined for 3D vectors." );
00501 return ( *this ) ^ other;
00502 }
00503
00507 void x(const T& v) { STATIC_ASSERT( dim > 0, "Accessing x requires at least a 1D vector." ); elems[0] = v; }
00511 void y(const T& v) { STATIC_ASSERT( dim > 1, "Accessing y requires at least a 2D vector." ); elems[1] = v; }
00515 void z(const T& v) { STATIC_ASSERT( dim > 2, "Accessing z requires at least a 3D vector." ); elems[2] = v; }
00519 void t(const T& v) { STATIC_ASSERT( dim > 3, "Accessing t requires at least a 4D vector." ); elems[3] = v; }
00523 T& x() { STATIC_ASSERT( dim > 0, "Accessing x requires at least a 1D vector." ); return elems[0]; }
00527 T& y() { STATIC_ASSERT( dim > 1, "Accessing y requires at least a 2D vector." ); return elems[1]; }
00531 T& z() { STATIC_ASSERT( dim > 2, "Accessing z requires at least a 3D vector." ); return elems[2]; }
00535 T& t() { STATIC_ASSERT( dim > 3, "Accessing t requires at least a 4D vector." ); return elems[3]; }
00539 const T& x() const { STATIC_ASSERT( dim > 0, "Accessing x requires at least a 1D vector." ); return elems[0]; }
00543 const T& y() const { STATIC_ASSERT( dim > 1, "Accessing y requires at least a 2D vector." ); return elems[1]; }
00547 const T& z() const { STATIC_ASSERT( dim > 2, "Accessing z requires at least a 3D vector." ); return elems[2]; }
00551 const T& t() const { STATIC_ASSERT( dim > 3, "Accessing t requires at least a 4D vector." ); return elems[3]; }
00552
00556 void i(const T& v) { STATIC_ASSERT( dim > 0, "Accessing i requires at least a 1D vector." ); elems[0] = v; }
00560 void j(const T& v) { STATIC_ASSERT( dim > 1, "Accessing j requires at least a 2D vector." ); elems[1] = v; }
00564 void k(const T& v) { STATIC_ASSERT( dim > 2, "Accessing k requires at least a 3D vector." ); elems[2] = v; }
00568 void l(const T& v) { STATIC_ASSERT( dim > 3, "Accessing l requires at least a 4D vector." ); elems[3] = v; }
00572 T& i() { STATIC_ASSERT( dim > 0, "Accessing i requires at least a 1D vector." ); return elems[0]; }
00576 T& j() { STATIC_ASSERT( dim > 1, "Accessing j requires at least a 2D vector." ); return elems[1]; }
00580 T& k() { STATIC_ASSERT( dim > 2, "Accessing k requires at least a 3D vector." ); return elems[2]; }
00584 T& l() { STATIC_ASSERT( dim > 3, "Accessing l requires at least a 4D vector." ); return elems[3]; }
00588 const T& i() const { STATIC_ASSERT( dim > 0, "Accessing i requires at least a 1D vector." ); return elems[0]; }
00592 const T& j() const { STATIC_ASSERT( dim > 1, "Accessing j requires at least a 2D vector." ); return elems[1]; }
00596 const T& k() const { STATIC_ASSERT( dim > 2, "Accessing k requires at least a 3D vector." ); return elems[2]; }
00600 const T& l() const { STATIC_ASSERT( dim > 3, "Accessing l requires at least a 4D vector." ); return elems[3]; }
00601
00605 Vector<2,T> projectXY(void)
00606 {
00607 STATIC_ASSERT( dim>1, "2D projection requires at least a 2D vector." );
00608 return Vector<2,T>(elems[0],elems[1]);
00609 }
00610
00616 bool operator<(const Vector& other) const
00617 {
00618 for(size_t i = 0 ; i < dim ; ++i)
00619 {
00620 if(elems[i] < other.elems[i]) return true;
00621 if(elems[i] > other.elems[i]) return false;
00622 }
00623 return false;
00624 }
00625
00631 bool operator<=(const Vector& other) const
00632 {
00633 for(size_t i = 0 ; i < dim ; ++i)
00634 {
00635 if(elems[i] < other.elems[i]) return true;
00636 if(elems[i] > other.elems[i]) return false;
00637 }
00638 return true;
00639 }
00640
00646 bool operator>(const Vector& other) const
00647 {
00648 for(size_t i = 0 ; i < dim ; ++i)
00649 {
00650 if(elems[i] > other.elems[i]) return true;
00651 if(elems[i] < other.elems[i]) return false;
00652 }
00653 return false;
00654 }
00655
00661 bool operator>=(const Vector& other) const
00662 {
00663 for(size_t i = 0 ; i < dim ; ++i)
00664 {
00665 if(elems[i] > other.elems[i]) return true;
00666 if(elems[i] < other.elems[i]) return false;
00667 }
00668 return true;
00669 }
00670
00671 friend std::ostream& operator<<(std::ostream& out,const Vector& vec)
00672 {
00673 for(size_t i = 0 ; i < dim ; i++)
00674 {
00675 out << vec.elems[i];
00676 if(i != (dim - 1))
00677 out << " ";
00678 }
00679 return out;
00680 }
00681
00682 friend std::istream& operator>>(std::istream& in,Vector& vec)
00683 {
00684 in >> vec[ 0 ];
00685 for(size_t i = 1 ; i < dim && in ; i++)
00686 in >> std::ws >> vec[i];
00687 return in;
00688 }
00689
00690 friend QTextStream& operator<<(QTextStream& out, const Vector& vec)
00691 {
00692 for(size_t i = 0 ; i < dim ; i++)
00693 {
00694 out << vec.elems[i];
00695 if(i != (dim - 1))
00696 out << " ";
00697 }
00698 return out;
00699 }
00700
00701 friend QTextStream& operator>>(QTextStream& in,Vector& vec)
00702 {
00703 in >> vec[ 0 ];
00704 for(size_t i = 1 ; i < dim && !in.atEnd() ; i++)
00705 in >> ws >> vec[i];
00706 return in;
00707 }
00708
00709 };
00710
00716 template <class T>
00717 T operator%( const Vector<2,T>& v1, const Vector<2,T>& v2 )
00718 {
00719 return v1^v2;
00720 }
00721
00727 template <class T>
00728 T operator^( const Vector<2,T>& v1, const Vector<2,T>& v2 )
00729 {
00730 return ((v1[0] * v2[1]) -
00731 (v1[1] * v2[0]));
00732 }
00733
00739 template <class T>
00740 T operator^( const Vector<1,T>& v1, const Vector<1,T>& v2 )
00741 {
00742 return 0;
00743 }
00744
00750 template <class T>
00751 Vector<3,T> operator%(const Vector<3,T>& v1,const Vector<3,T>& v2)
00752 {
00753 return v1^v2;
00754 }
00755
00761 template <class T>
00762 Vector<3,T> operator^(const Vector<3,T>& v1,const Vector<3,T>& v2)
00763 {
00764 Vector<3,T> ans;
00765 ans[0] = v1[1]*v2[2] - v1[2]*v2[1];
00766 ans[1] = v1[2]*v2[0] - v1[0]*v2[2];
00767 ans[2] = v1[0]*v2[1] - v1[1]*v2[0];
00768 return ans;
00769 }
00770
00776 template <class T>
00777 double angle( const Vector<2,T>& v )
00778 {
00779 return atan2( v.y(), v.x() );
00780 }
00781
00787 template <class T>
00788 double angle( const Vector<3,T>& v1, const Vector<3,T>& v2 )
00789 {
00790 double x = v1*v2;
00791 double y = norm( v1^v2 );
00792 return atan2( y, x );
00793 }
00794
00800 template <class T>
00801 double angle( const Vector<2,T>& v1, const Vector<2,T>& v2 )
00802 {
00803 double x = v1*v2;
00804 double y = v1^v2;
00805 return atan2( y, x );
00806 }
00807
00813 template <class T>
00814 double angle( const Vector<1,T>& v1, const Vector<1,T>& v2 )
00815 {
00816 return ( v1*v2 < 0 )? -1 : 1;
00817 }
00818
00824 template <class T>
00825 double angle( const Vector<3,T>& v1, const Vector<3,T>& v2, const Vector<3,T>& ref )
00826 {
00827 double x = v1*v2;
00828 Vector<3,T> n = v1^v2;
00829 double y = norm( n );
00830 if( n*ref < 0 )
00831 return atan2( -y, x );
00832 else
00833 return atan2( y, x );
00834 }
00835
00843 inline double normalized(double)
00844 {
00845 return 1;
00846 }
00847
00855 inline double normsq(double s)
00856 {
00857 return s*s;
00858 }
00859
00867 inline double norm(double s)
00868 {
00869 return (s<0)?-s:s;
00870 }
00871
00878 template <size_t dim, typename T>
00879 T norm( const Vector<dim,T>& v )
00880 {
00881 return v.norm();
00882 }
00883
00890 template <size_t dim, typename T>
00891 T normsq( const Vector<dim,T>& v )
00892 {
00893 return v.normsq();
00894 }
00895
00902 template <size_t dim, typename T>
00903 Vector<dim,T> normalized( const Vector<dim,T>& v )
00904 {
00905 return v.normalized();
00906 }
00907
00914 template <size_t dim, typename T>
00915 Vector<dim,T> max( const Vector<dim,T>& v1, const Vector<dim,T>& v2)
00916 {
00917 Vector<dim,T> result;
00918 for(size_t i = 0 ; i < dim ; ++i)
00919 {
00920 result[i] = std::max(v1[i], v2[i]);
00921 }
00922 return result;
00923 }
00924
00931 template <size_t dim, typename T>
00932 Vector<dim,T> min( const Vector<dim,T>& v1, const Vector<dim,T>& v2)
00933 {
00934 Vector<dim,T> result;
00935 for(size_t i = 0 ; i < dim ; ++i)
00936 {
00937 result[i] = std::min(v1[i], v2[i]);
00938 }
00939 return result;
00940 }
00941
00948 template <size_t dim, typename T>
00949 Vector<dim,T> multiply( const Vector<dim,T>& v1, const Vector<dim,T>& v2)
00950 {
00951 Vector<dim,T> result;
00952 for(size_t i = 0 ; i < dim ; ++i)
00953 {
00954 result[i] = v1[i] * v2[i];
00955 }
00956 return result;
00957 }
00958
00965 template <size_t dim, typename T>
00966 Vector<dim,T> divide( const Vector<dim,T>& v1, const Vector<dim,T>& v2)
00967 {
00968 Vector<dim,T> result;
00969 for(size_t i = 0 ; i < dim ; ++i)
00970 {
00971 result[i] = v1[i] / v2[i];
00972 }
00973 return result;
00974 }
00975
00981 template <typename T>
00982 util::Vector<3,T> orthogonal(const util::Vector<3,T>& v)
00983 {
00984 const double ratio = 1-1e-8;
00985 if ((std::abs(v.y()) >= ratio*std::abs(v.x())) && (std::abs(v.z()) >= ratio*std::abs(v.x())))
00986 return util::Vector<3,T>(0, -v.z(), v.y());
00987 else
00988 if ((std::abs(v.x()) >= ratio*std::abs(v.y())) && (std::abs(v.z()) >= ratio*std::abs(v.y())))
00989 return util::Vector<3,T>(-v.z(), 0, v.x());
00990 else
00991 return util::Vector<3,T>(-v.y(), v.x(), 0);
00992 }
00993
00994
00995
00996
00997
00998
00999 template <size_t dim, typename T>
01000 Vector<dim,T> map(const T& (*fct)(const T&), const Vector<dim,T>& v)
01001 {
01002 Vector<dim,T> result;
01003 for(size_t i = 0 ; i < dim ; ++i)
01004 {
01005 result[i] = (*fct)(v[i]);
01006 }
01007 return result;
01008 }
01009
01010
01011
01012
01013
01014
01015 template <size_t dim, typename T>
01016 Vector<dim,T> map(T (*fct)(const T&), const Vector<dim,T>& v)
01017 {
01018 Vector<dim,T> result;
01019 for(size_t i = 0 ; i < dim ; ++i)
01020 {
01021 result[i] = (*fct)(v[i]);
01022 }
01023 return result;
01024 }
01025
01026
01027
01028
01029
01030
01031 template <size_t dim, typename T>
01032 Vector<dim,T> map(T (*fct)(T), const Vector<dim,T>& v)
01033 {
01034 Vector<dim,T> result;
01035 for(size_t i = 0 ; i < dim ; ++i)
01036 {
01037 result[i] = (*fct)(v[i]);
01038 }
01039 return result;
01040 }
01041
01042
01043
01044
01045
01046
01047 template <size_t dim, typename T, typename T1>
01048 Vector<dim,T> map(const T& (*fct)(const T1&), const Vector<dim,T1>& v)
01049 {
01050 Vector<dim,T> result;
01051 for(size_t i = 0 ; i < dim ; ++i)
01052 {
01053 result[i] = (*fct)(v[i]);
01054 }
01055 return result;
01056 }
01057
01058
01059
01060
01061
01062
01063 template <size_t dim, typename T, typename T1>
01064 Vector<dim,T> map(T (*fct)(const T1&), const Vector<dim,T1>& v)
01065 {
01066 Vector<dim,T> result;
01067 for(size_t i = 0 ; i < dim ; ++i)
01068 {
01069 result[i] = (*fct)(v[i]);
01070 }
01071 return result;
01072 }
01073
01079 template <size_t dim, typename T, typename T1>
01080 Vector<dim,T> map(T (*fct)(T1), const Vector<dim,T1>& v)
01081 {
01082 Vector<dim,T> result;
01083 for(size_t i = 0 ; i < dim ; ++i)
01084 {
01085 result[i] = (*fct)(v[i]);
01086 }
01087 return result;
01088 }
01089
01095 template <size_t dim, typename T>
01096 Vector<dim,T> map(const T& (*fct)(const T&,const T&), const Vector<dim,T>& v1, const Vector<dim,T>& v2)
01097 {
01098 Vector<dim,T> result;
01099 for(size_t i = 0 ; i < dim ; ++i)
01100 {
01101 result[i] = (*fct)(v1[i], v2[i]);
01102 }
01103 return result;
01104 }
01105
01111 template <size_t dim, typename T>
01112 Vector<dim,T> map(T (*fct)(const T&,const T&), const Vector<dim,T>& v1, const Vector<dim,T>& v2)
01113 {
01114 Vector<dim,T> result;
01115 for(size_t i = 0 ; i < dim ; ++i)
01116 {
01117 result[i] = (*fct)(v1[i], v2[i]);
01118 }
01119 return result;
01120 }
01121
01127 template <size_t dim, typename T>
01128 Vector<dim,T> map(T (*fct)(T,T), const Vector<dim,T>& v1, const Vector<dim,T>& v2)
01129 {
01130 Vector<dim,T> result;
01131 for(size_t i = 0 ; i < dim ; ++i)
01132 {
01133 result[i] = (*fct)(v1[i], v2[i]);
01134 }
01135 return result;
01136 }
01137
01143 template <size_t dim, typename T, typename T1, typename T2>
01144 Vector<dim,T> map(const T& (*fct)(const T1&,const T2&), const Vector<dim,T1>& v1, const Vector<dim,T2>& v2)
01145 {
01146 Vector<dim,T> result;
01147 for(size_t i = 0 ; i < dim ; ++i)
01148 {
01149 result[i] = (*fct)(v1[i], v2[i]);
01150 }
01151 return result;
01152 }
01153
01159 template <size_t dim, typename T, typename T1, typename T2>
01160 Vector<dim,T> map(T (*fct)(const T1&,const T2&), const Vector<dim,T1>& v1, const Vector<dim,T2>& v2)
01161 {
01162 Vector<dim,T> result;
01163 for(size_t i = 0 ; i < dim ; ++i)
01164 {
01165 result[i] = (*fct)(v1[i], v2[i]);
01166 }
01167 return result;
01168 }
01169
01175 template <size_t dim, typename T, typename T1, typename T2>
01176 Vector<dim,T> map(T (*fct)(T1,T2), const Vector<dim,T1>& v1, const Vector<dim,T2>& v2)
01177 {
01178 Vector<dim,T> result;
01179 for(size_t i = 0 ; i < dim ; ++i)
01180 {
01181 result[i] = (*fct)(v1[i], v2[i]);
01182 }
01183 return result;
01184 }
01185
01191 template <size_t dim, typename T>
01192 Vector<dim,T> operator+(const Vector<dim,T>& v, const T& value)
01193 {
01194 Vector<dim,T> res;
01195 for(size_t i = 0 ; i < dim ; ++i)
01196 res[i] = v[i] + value;
01197 return res;
01198 }
01199
01205 template <size_t dim, typename T>
01206 Vector<dim,T> operator+(const T& value, const Vector<dim,T>& v)
01207 {
01208 Vector<dim,T> res;
01209 for(size_t i = 0 ; i < dim ; ++i)
01210 res[i] = v[i] + value;
01211 return res;
01212 }
01213
01219 template <size_t dim, typename T>
01220 Vector<dim,T> operator-(const Vector<dim,T>& v, const T& value)
01221 {
01222 Vector<dim,T> res;
01223 for(size_t i = 0 ; i < dim ; ++i)
01224 res[i] = v[i] - value;
01225 return res;
01226 }
01227
01234 template <size_t dim, typename T>
01235 Vector<dim,T> operator-(const T& value, const Vector<dim,T>& v)
01236 {
01237 Vector<dim,T> res;
01238 for(size_t i = 0 ; i < dim ; ++i)
01239 res[i] = value - v[i];
01240 return res;
01241 }
01242
01248 template <size_t dim, typename T>
01249 struct CrossProductType;
01250
01254 template <typename T>
01255 struct CrossProductType<2,T>
01256 {
01257 typedef T type;
01258 };
01259
01263 template <typename T>
01264 struct CrossProductType<3,T>
01265 {
01266 typedef Vector<3,T> type;
01267 };
01268
01269 }
01270
01271 #endif // __UTIL_VECTOR_H