00001 #ifndef Vec3_H
00002 #define Vec3_H
00003
00004 #include <math.h>
00005 #include <iostream>
00006 #include <stdexcept>
00007
00008
00009
00010
00011
00015 namespace animal {
00016 namespace octree {
00017
00018 template<class DataType>
00019 struct Vec3
00020 {
00021
00022 DataType x;
00023
00024 DataType y;
00025
00026 DataType z;
00027
00028
00029 inline Vec3();
00030 inline Vec3(const DataType x,const DataType y,const DataType z);
00031 inline Vec3(const Vec3& v);
00032
00033
00034 inline void set(const DataType x,const DataType y,const DataType z);
00035 inline void set(const Vec3& v);
00036
00037 inline operator const DataType*() const;
00038
00039
00040 inline bool operator==(const Vec3& b) const;
00041 inline bool operator!=(const Vec3& b) const;
00042 inline bool operator<(const Vec3& b) const;
00043 inline const DataType& operator[](const int i) const;
00044 inline DataType& operator[](const int i);
00045
00046 inline Vec3& operator+=(const Vec3& a);
00047 inline Vec3& operator-=(const Vec3& a);
00048 inline Vec3& operator*=(const DataType& k);
00049 inline Vec3& operator/=(const DataType& k);
00050
00051 inline DataType norm2() const;
00052 inline DataType norm() const;
00053 inline void normalize();
00054 inline Vec3 normalized() const;
00055 inline Vec3 normalized(DataType& f) const;
00056 inline Vec3 withX(const DataType theX) const;
00057 inline Vec3 withY(const DataType theY) const;
00058 inline Vec3 withZ(const DataType theZ) const;
00059 inline Vec3 nonColinearVec() const;
00060
00061 inline Vec3 get_Vec3() { return *this; };
00062
00063
00064
00065 inline Vec3 operator+( const Vec3<DataType>& a ) const;
00066
00067
00068 inline Vec3 operator-( const Vec3<DataType>& a ) const;
00069
00070
00071 inline Vec3 operator-() const;
00072
00073
00074 inline Vec3 operator*( const DataType k ) const;
00075 friend Vec3 operator*( const DataType k, const Vec3<DataType>& v )
00076 {
00077 return v * k;
00078 };
00079
00080
00081 inline Vec3 operator/( const DataType k ) const;
00082
00083
00084 inline DataType operator*( const Vec3<DataType>& a ) const;
00085 inline Vec3 operator^( const Vec3<DataType>& a ) const;
00086
00087
00088 friend std::ostream& operator<<(std::ostream& s, const Vec3<DataType>& v )
00089 {
00090 s<<"("<<v.x<<","<<v.y<<","<<v.z<<")";
00091 return s;
00092 };
00093
00094 friend std::istream& operator>>(std::istream& s, Vec3<DataType>& v )
00095 {
00096 char c;
00097 s.get(c);
00098 s>>v.x;
00099 s.get(c);
00100 s>>v.y;
00101 s.get(c);
00102 s>>v.z;
00103 s.get(c);
00104 return s;
00105 };
00106
00107
00108 static inline const Vec3& axis(const int i);
00109
00110
00111 };
00112
00113
00114
00115
00116
00120 template<class DataType>
00121 inline
00122 Vec3<DataType>::Vec3()
00123 : x(0.0f), y(0.0f), z(0.0f)
00124 {
00125 }
00129 template<class DataType>
00130 inline Vec3<DataType>::Vec3(const DataType x,const DataType y,const DataType z)
00131 : x(x), y(y), z(z)
00132 {
00133 }
00140 template<class DataType>
00141 inline Vec3<DataType>::Vec3(const Vec3& v)
00142 : x(v[0]),y(v[1]),z(v[2])
00143 {
00144 }
00145
00146
00147
00148
00149
00150
00151
00152
00156 template<class DataType>
00157 inline void
00158 Vec3<DataType>::set(const DataType ax,const DataType ay,const DataType az)
00159 {
00160 x = ax;
00161 y = ay;
00162 z = az;
00163 }
00164 template<class DataType>
00165 inline void Vec3<DataType>::set(const Vec3& v)
00166 {
00167 this->set( v[0], v[1], v[2] );
00168 }
00169
00173 template<class DataType>
00174 inline Vec3<DataType>::operator const DataType*() const
00175 {
00176 return static_cast<const DataType*>(&x);
00177 }
00178
00179
00180
00184 template<class DataType>
00185 inline bool
00186 Vec3<DataType>::operator==(const Vec3& b) const
00187 {
00188 return (x == b.x &&
00189 y == b.y &&
00190 z == b.z);
00191 }
00195 template<class DataType>
00196 inline bool
00197 Vec3<DataType>::operator!=(const Vec3& b) const
00198 {
00199 return (x != b.x ||
00200 y != b.y ||
00201 z != b.z);
00202 }
00206 template<class DataType>
00207 inline bool
00208 Vec3<DataType>::operator<(const Vec3& b) const
00209 {
00210 return ((x < b.x) ||
00211 ((x == b.x) && y < b.y) ||
00212 ((x == b.x && y == b.y) && z < b.z));
00213 }
00218 template<class DataType>
00219 inline const DataType&
00220 Vec3<DataType>::operator[](const int i) const
00221 {
00222 return static_cast<const DataType*>(&x)[i] ;
00223 }
00228 template<class DataType>
00229 inline DataType&
00230 Vec3<DataType>::operator[](const int i)
00231 {
00232 return static_cast<DataType*>(&x)[i] ;
00233 }
00234
00235
00236
00237
00238
00239 template<class DataType>
00240 inline Vec3<DataType>& Vec3<DataType>::operator*=(const DataType& k)
00241 {
00242 this->x *= k;
00243 this->y *= k;
00244 this->z *= k;
00245 return *this;
00246 }
00247 template<class DataType>
00248 inline Vec3<DataType>& Vec3<DataType>::operator/=(const DataType& k)
00249 {
00250 this->x /= k;
00251 this->y /= k;
00252 this->z /= k;
00253 return *this;
00254 }
00255
00256 template<class DataType>
00257 inline Vec3<DataType>& Vec3<DataType>::operator+=(const Vec3& a)
00258 {
00259 this->x += a.x;
00260 this->y += a.y;
00261 this->z += a.z;
00262 return *this;
00263 }
00264 template<class DataType>
00265 inline Vec3<DataType>& Vec3<DataType>::operator-=(const Vec3& a)
00266 {
00267 this->x -= a.x;
00268 this->y -= a.y;
00269 this->z -= a.z;
00270 return *this;
00271 }
00272
00273
00274 template<class DataType>
00275 Vec3<DataType> Vec3<DataType>::operator+( const Vec3<DataType>& v ) const
00276 {
00277 return Vec3<DataType>( x+v.x, y+v.y, z+v.z );
00278 }
00279
00280 template<class DataType>
00281 Vec3<DataType> Vec3<DataType>::operator-( const Vec3<DataType>& v ) const
00282 {
00283 return Vec3<DataType>( x-v.x, y-v.y, z-v.z );
00284 }
00285
00286 template<class DataType>
00287 Vec3<DataType> Vec3<DataType>::operator-( ) const
00288 {
00289 return Vec3<DataType>( -x, -y, -z );
00290 }
00291
00292
00293
00294
00295 template<class DataType>
00296 DataType Vec3<DataType>::operator*( const Vec3<DataType>& v ) const
00297 {
00298 return x*v.x + y*v.y + z*v.z;
00299 }
00300 template<class DataType>
00301 Vec3<DataType> Vec3<DataType>::operator*( const DataType k ) const
00302 {
00303 return Vec3<DataType>( x*k, y*k, z*k );
00304 }
00305
00306 template<class DataType>
00307 Vec3<DataType> Vec3<DataType>::operator/( const DataType k ) const
00308 {
00309 return Vec3<DataType>( x/k, y/k, z/k );
00310 }
00311
00315 template<class DataType>
00316 Vec3<DataType> Vec3<DataType>::operator^( const Vec3<DataType>& v ) const
00317 {
00318 return Vec3<DataType>(y*v.z - z*v.y,
00319 z*v.x - x*v.z,
00320 x*v.y - y*v.x);
00321 }
00322
00323
00324
00328 template<class DataType>
00329 inline DataType
00330 Vec3<DataType>::norm2() const
00331 {
00332 return x*x+y*y+z*z;
00333 }
00337 template<class DataType>
00338 inline DataType
00339 Vec3<DataType>::norm() const
00340 {
00341 return sqrtf(norm2()) ;
00342 }
00348 template<class DataType>
00349 inline void
00350 Vec3<DataType>::normalize()
00351 {
00352 const DataType f = norm();
00353 x /= f ;
00354 y /= f ;
00355 z /= f ;
00356 }
00357
00363 template<class DataType>
00364 inline Vec3<DataType>
00365 Vec3<DataType>::normalized() const
00366 {
00367 return *this / norm() ;
00368 }
00383 template<class DataType>
00384 inline Vec3<DataType>
00385 Vec3<DataType>::normalized(DataType& l) const
00386 {
00387 return *this / (l=norm()) ;
00388 }
00392 template<class DataType>
00393 inline Vec3<DataType>
00394 Vec3<DataType>::withX(const DataType theX) const
00395 {
00396 return Vec3(theX,y,z);
00397 }
00401 template<class DataType>
00402 inline Vec3<DataType>
00403 Vec3<DataType>::withY(const DataType theY) const
00404 {
00405 return Vec3(x,theY,z);
00406 }
00410 template<class DataType>
00411 inline Vec3<DataType>
00412 Vec3<DataType>::withZ(const DataType theZ) const
00413 {
00414 return Vec3(x,y,theZ);
00415 }
00416
00417 template<class DataType>
00418 inline const Vec3<DataType>&
00419 Vec3<DataType>::axis(const int i)
00420 {
00421 static const Vec3 axis[3] =
00422 {
00423 Vec3(1.0f,0.0f,0.0f),
00424 Vec3(0.0f,1.0f,0.0f),
00425 Vec3(0.0f,0.0f,1.0f)
00426 };
00427 return axis[i];
00428 };
00433 template<class DataType>
00434 inline Vec3<DataType>
00435 Vec3<DataType>::nonColinearVec() const
00436 {
00437 return ((*this)^Vec3<DataType>::axis(0)).norm2() > 0.0001f ?
00438 Vec3<DataType>::axis(0) :
00439 Vec3<DataType>::axis(1);
00440 }
00441
00442
00443 }
00444 }
00445
00446 #endif // Vec3_H