00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
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 }
00420
00421
00422 #endif // _ARRAY_H
00423
00424
00425
00426