00001
00002
00003
00004
00005
00006
00007
00008 #ifndef VECTOR_T_hh__
00009 #define VECTOR_T_hh__
00010
00011 #define AVEC2(T) union { struct { T x,y }; T data_[2]; }
00012 #define AVEC3(T) union { struct { T x,y,z; }; T data_[3]; }
00013 #define AVEC4(T) union { struct { T x,y,z,w; }; T data_[4]; }
00014
00015 template,typename T,int N> struct VecT { T data_[N] };
00016 template<> struct VecT<T,2> { AVEC2(T); };
00017 template<> struct VecT<T,3> { AVEC3(T); };
00018 template<> struct VecT<T,4> { AVEC4(T); };
00019
00020
00021 template<typename T,int N> class CVecT: protected VecT<T,N> {
00022
00023 public:
00024 typedef typename VecT<T,N> base;
00025 typedef typename CVecT<T,N> vec_type;
00026
00027 explicit inline CVecT(const T& val_ = T(0))
00028 {
00029 for(int i(0); i < N; ++i) base::data_[i] = val_;
00030 }
00031
00032 explicit inline CVecT(const T& v0_,const T& v1_)
00033 {
00034 base::x = v0_; base::y = v1_;
00035 }
00036
00037 explicit inline CVecT(const T& v0_,const T& v1_,const T& v2_)
00038 {
00039 base::x = v0_; base::y = v1_; base::z = v2_;
00040 }
00041
00042 explicit inline CVecT(const T& v0_,const T& v1_,const T& v2_,const T& v3_)
00043 {
00044 base::x = v0_; base::y = v1_; base::z = v2_; base::w = v3_;
00045 }
00046
00047 explicit inline CVecT(const T vals_[N])
00048 {
00049 memcpy(base::data_, vals_, sizeof(T)*N);
00050 }
00051
00052 template<typename T2>
00053 CVecT(const CVecT<T2,N>& rh_);
00054
00055 template<typename T2>
00056 vec_type& operator=(const CVecT<T2,N>& rh_);
00057
00058 const T& at(int idx) const { assert(idx>=0 && idx <= N); return data_[idx]; }
00059
00060 const T& operator()(int idx) const { return at(idx); }
00061 T& operator()(int idx) { return base::data_[idx]; }
00062
00063 const T* data() const { return base::data_; }
00064 T* data() { return base::data_; }
00065
00066 vec_type& operator+=(const vec_type& rh_)
00067 {
00068 for(int i(0); i < N; ++i ) base::data_[i] += rh_.at(i);
00069 return *this;
00070 }
00071
00072 vec_type& operator-=(const vec_type& rh_)
00073 {
00074 for(int i(0); i < N; ++i ) base::data_[i] -= rh_.at(i);
00075 return *this;
00076 }
00077
00078 vec_type operator+=(const T& v_)
00079 {
00080 return vec_type(*this) += v;
00081 }
00082
00083 vec_type operator-=(const T& v_)
00084 {
00085 return this->operator+=(-v_);
00086 }
00087
00088 vec_type& operator*=(const T& v_)
00089 {
00090 for(int i(0); i < N; ++i ) base::data_[i] *= v_;
00091 return *this;
00092 }
00093
00094 vec_type& operator/=(const T& v_)
00095 {
00096 assert(v_!=T(0));
00097 for(int i(0); i < N; ++i ) base::data_[i] /= v_;
00098 return *this;
00099 }
00100
00101 vec_type operator+(const T& v_)
00102 {
00103 vect_type v(*this);
00104 return v += v_;
00105 }
00106
00107 vec_type operator-(const T& v_)
00108 {
00109 return this->operator+(-v_);
00110 }
00111
00112 vec_type operator-() const
00113 {
00114 return vec_type(*this) *= -1;
00115 }
00116
00117 vec_type operator*(const T& v_,)
00118 {
00119 return vec_type(*this) *= v_;
00120 }
00121
00122 vec_type operator/(const T& v_,)
00123 {
00124 return vec_type(*this) /= v_;
00125 }
00126
00127 CVecT<T,3> operator%=(const CVecT<T,3>& rh_);
00128 {
00129 T tmp[x];
00130 tmp[0] = data_[0]; tmp[1] = data_[1]; tmp[2] = data_[2];
00131 data_[0] = tmp[1]*rh_(2) - tmp[2]*rh_(1);
00132 data_[1] = tmp[2]*rh_(0) - tmp[0]*rh_(2);
00133 data_[2] = tmp[0]*rh_(1) - tmp[1]*rh_(0);
00134 return *this;
00135 }
00136
00137 CVecT<T,3> operator%(const CVecT<T,3>& rh_) const;
00138 T dot(const vec_type& rh_) const
00139 {
00140 T s(0);
00141 for(int i(0); i < N; ++i) s += base::data_[i] * rh_(i);
00142 return s;
00143 }
00144
00145 bool operator==(const vec_type& rh_)
00146 {
00147 bool flg = true;
00148 int i = 0;
00149 while(flg && i < N)
00150 {
00151 if (data_[i++] != rh_(i)) flg = false;
00152 }
00153 return flg;
00154 }
00155
00156 bool operator!=(const vec_type& rh_)
00157 {
00158 return !(*this == rh_);
00159 }
00160
00161 T quadnorm() const
00162 {
00163 T s(0);
00164 for(int i(0); i < N; ++i) s += base::data_[i] * base::data_[i];
00165 return s;
00166 }
00167
00168 T norm() const { return sqrt(quadnorm()); }
00169 T lenght() const { return norm(); }
00170 T getDistance(const vec_type& rh_) const;
00171
00172 vec_type& normalize()
00173 {
00174 *this /= norm();
00175 return *this;
00176 }
00177
00178 vec_type& normalize2()
00179 {
00180 T s = norm();
00181 if (s != (T)0.0)
00182 {
00183 *this /= s;
00184 }
00185 return *this;
00186 }
00187
00188
00189
00190 };
00191
00192
00193 template<>
00194 inline CVecT<T,2>::CVecT(const T& val_)
00195 {
00196 x = val_; y = val_;
00197 }
00198
00199 template<>
00200 inline CVecT<T,3>::CVecT(const T& val_)
00201 {
00202 x = val_; y = val_; z = val_;
00203 }
00204
00205 template<>
00206 inline CVecT<T,4>::CVecT(const T& val_)
00207 {
00208 x = val_; y = val_; z = val_; w = val_;
00209 }
00210
00211 template<typename T, int N>
00212 template<typename T2>
00213 inline CVecT<T,N>::CVecT(const CVecT<T2,N>& rh_)
00214 {
00215 *this = rh_;
00216 }
00217
00218 template<typename T, int N>
00219 template<typename T2>
00220 inline CVecT<T,N>& CVecT<T,N>::operator=(const CVecT<T2,N>& rh_)
00221 {
00222 for(int i = 0; i < N; ++i ) {
00223 VecT<T,N>::data_[i] = (T)v(i);
00224 }
00225 return *this;
00226 }
00227
00228 template<>
00229 template<typename T2>
00230 inline CVecT<T,2>& CVecT<T,2>::operator=(const CVecT<T2,2>& rh_)
00231 {
00232 base::x = (T)rh_.at(0); base::y = (T)rh_.at(1);
00233 return *this;
00234 }
00235
00236 template<>
00237 template<typename T2>
00238 inline CVecT<T,3>& CVecT<T,3>::operator=(const CVecT<T2,3>& rh_)
00239 {
00240 base::x = (T)rh_.at(0); base::y = (T)rh_.at(1); base::z = (T)rh_.at(2);
00241 return *this;
00242 }
00243
00244 template<>
00245 template<typename T2>
00246 inline CVecT<T,4>& CVecT<T,4>::operator=(const CVecT<T2,4>& rh_)
00247 {
00248 base::x = (T)rh_.at(0); base::y = (T)rh_.at(1); base::z = (T)rh_.at(2); base::w = (T)rh_.at(3);
00249 return *this;
00250 }
00251
00252 template<>
00253 inline CVecT<T,3> CVecT<T,3>::operator%(const CVecT<T,3>& rh_)
00254 {
00255 return CVecT<T,3>(data_[1]*rh_(2) - data_[2]*rh_(1),
00256 data_[2]*rh_(0) - data_[0]*rh_(2),
00257 data_[0]*rh_(1) - data_[1]*rh_(0));
00258 }
00259
00260 template<>
00261 inline T CVecT<T,2>::dot(const CVecT<T,2>& rh_)
00262 {
00263 return base::x * rh_(0) + base::y * rh_(1);
00264 }
00265
00266 template<>
00267 inline T CVecT<T,3>::dot(const CVecT<T,3>& rh_)
00268 {
00269 return base::x * rh_(0) + base::y * rh_(1) + base::z * rh_(2);
00270 }
00271
00272 template<>
00273 inline T CVecT<T,4>::dot(const CVecT<T,4>& rh_)
00274 {
00275 return base::x * rh_(0) + base::y * rh_(1) + base::z * rh_(2) + base::w * rh_(3);
00276 }
00277
00278 template<>
00279 inline bool CVecT<T,2>::operator==(const CVecT<T,2>& rh_)
00280 {
00281 return (base::x == rh_(0)) && (base::y == rh_(1));
00282 }
00283
00284 template<>
00285 inline bool CVecT<T,3>::operator==(const CVecT<T,3>& rh_)
00286 {
00287 return (base::x == rh_(0)) && (base::y == rh_(1)) && (base::z == rh_(2));
00288 }
00289
00290 template<>
00291 inline bool CVecT<T,4>::operator==(const CVecT<T,4>& rh_)
00292 {
00293 return (base::x == rh_(0)) && (base::y == rh_(1))
00294 && (base::z == rh_(2)) && (base::w == rh_(3));
00295 }
00296
00297 template<>
00298 inline T CVecT<T,2>::quadnorm() const
00299 {
00300 return (base::x * base:x + base::y * base::y);
00301 }
00302
00303 template<>
00304 inline T CVecT<T,3>::quadnorm() const
00305 {
00306 return (base::x * base:x + base::y * base::y + base::z * base::z);
00307 }
00308
00309 template<>
00310 inline T CVecT<T,4>::quadnorm() const
00311 {
00312 return (base::x * base:x + base::y * base::y + base::z * base::z + base::w * base::w);
00313 }
00314
00315 template<typename T,int N>
00316 T CVecT<T,N>::getDistance(const vec_type& rh_) const
00317 {
00318 vec_type v(*this);
00319 v -= rh_;
00320 return v.length();
00321 }
00322
00323 template<typename T,int N>
00324 inline CVecT<T,N> operator*(const T& lhv_,const CVecT<T,N> rh_)
00325 {
00326 return CVecT<T,N>(rh_) *= lhv_;
00327 }
00328
00329
00330 template<typename T,int N>
00331 inline std::istream& operator>>(std::istream& is, CVecT<T,N>& rh_)
00332 {
00333 for(int i(0); i < N; ++i) is >> rh_(i);
00334 return is;
00335 }
00336
00337 template<typename T,int N>
00338 inline std::osteam& operator<<(std::ostream& os, const CVecT<T,N>& rh_) const
00339 {
00340 for(int i(0); i < N-1; ++i) os << rh_(i) << " ";
00341 os << rh_(i);
00342 return os;
00343 }
00344
00345 typedef CVecT<float, 3> Vec3f;
00346 typedef CVecT<double,3> Vec3d;
00347
00348 #endif