00001
00002
00003
00004 #ifndef __Vector3T_HPP
00005 #define __Vector3T_HPP
00006
00007 #include <iostream>
00008 #include "Math.hpp"
00009
00010 template <class T>
00011 class Matrix3T;
00012
00013 template <class T>
00014 class Vector3T
00015 {
00016 public:
00017 T x;
00018 T y;
00019 T z;
00020 Vector3T () {}
00021 Vector3T (float cx, float cy, float cz) { x = (T)cx; y = (T)cy; z = (T)cz; }
00022 Vector3T (int cx, int cy, int cz) { x = (T)cx; y = (T)cy; z = (T)cz; }
00023 Vector3T (double cx, double cy, float cz) { x = (T)(cx); y = (T)(cy); z = (T)cz; }
00024 template <class S> Vector3T (const Vector3T<S>& v) { x = (T)v.x; y = (T)v.y; z = (T)v.z; }
00025 template <class S> Vector3T& operator= (const Vector3T<S>& v) { x = (T)v.x; y = (T)v.y; z = (T)v.z; return *this; }
00026
00027 Vector3T& clear (void) { x = (T)(0); y = (T)(0); z = (T)(0); return *this; }
00028 Vector3T& make (double cx, double cy, double cz) { x = (T)(cx); y = (T)(cy); z = (T)(cz); return *this; }
00029 Vector3T& make (double xyz) { x = (T)(xyz); y = (T)(xyz); z = (T)(xyz); return *this; }
00030
00031 Vector3T& set (double cx, double cy, double cz) { x = (T)(cx); y = (T)(cy); z = (T)(cz); return *this; }
00032 Vector3T& set (double xyz) { x = (T)(xyz); y = (T)(xyz); z = (T)(xyz); return *this; }
00033
00034 bool operator== (const Vector3T& src) const { return (x == src.x && y == src.y && z == src.z); }
00035 bool operator!= (const Vector3T& src) const { return !(x == src.x && y == src.y && z == src.z); }
00036
00037 Vector3T& operator+= (const Vector3T& v) { x += v.x; y += v.y; z += v.z; return *this; }
00038 Vector3T& operator-= (const Vector3T& v) { x -= v.x; y -= v.y; z -= v.z; return *this; }
00039 Vector3T& operator*= (const Matrix3T<T>& m);
00040
00041 void rotateAbout( const Vector3T<T> &v, const T &d );
00042 Vector3T& operator*= (double s) { x = (T)(x*s), y = (T)(y*s); z = (T)(z*s); return *this; }
00043 Vector3T& operator/= (double s) { s = 1.0/s; x = (T)(x*s), y = (T)(y*s); z = (T)(z*s); return *this; }
00044 bool isOne (void) const { return (x == 1.0f && y == 1.0f && z == 1.0f); }
00045 bool isZero (void) const { return (x == 0.0f && y == 0.0f && z == 0.0f); }
00046 bool isValid (void) const { return _finite(x) && _finite(y) && _finite(z); }
00047 double length (void) const { return sqrt(x*x+y*y+z*z); }
00048 double lengthSqr (void) const { return x*x+y*y+z*z; }
00049 Vector3T& negate (void) { x=-x; y=-y; z=-z; return *this; }
00050 Vector3T& normalize (double len = 1.0) { double l = length(); if (l!=0.0) *this *= (len/l); else {x = 1; y = 0; z = 0;} return *this; }
00051 Vector3T& scale (const Vector3T& v) { x *= v.x; y *= v.y; z *= v.z; return *this; }
00052 Vector3T& descale (const Vector3T& v) { x /= v.x, y /= v.y; z /= v.z; return *this; }
00053 Vector3T& clampUnit (void) { if(x <= (T)0.0) x = (T)0.0; else if(x >= (T)1.0) x = (T)1.0; if(y <= (T)0.0) y = (T)0.0; else if(y >= (T)1.0) y = (T)1.0; if(z <= (T)0.0) z = (T)0.0; else if(z >= (T)1.0) z = (T)1.0; return *this; }
00054 const T& operator[] (int i) const { return ((T*)this)[i]; }
00055 T& operator[] (int i) { return ((T*)this)[i]; }
00056 };
00057
00058
00059 template<class T>
00060 inline void Vector3T<T>::rotateAbout( const Vector3T<T> &v, const T &d )
00061 {
00062
00063
00064
00065
00066
00067 T s, c, t;
00068 Vector3T<T> tmp( *this );
00069 Vector3T<T> vn( v );
00070 c = (T)cos( d );
00071 s = (T)sin( d );
00072 t = (T)1 - c;
00073 vn.normalize( );
00074 x = (t*vn.x*vn.x+c) * tmp.x + (t*vn.x*vn.y-s*vn.z) * tmp.y
00075 + (t*vn.x*vn.z+s*vn.y) * tmp.z;
00076 y = (t*vn.x*vn.y+s*vn.z) * tmp.x + (t*vn.y*vn.y+c) * tmp.y
00077 + (t*vn.y*vn.z-s*vn.x) * tmp.z;
00078 z = (t*vn.x*vn.z-s*vn.y) * tmp.x + (t*vn.y*vn.z+s*vn.x) * tmp.y
00079 + (t*vn.z*vn.z+c) * tmp.z;
00080 }
00081
00082
00083 template <class T> inline Vector3T<T> operator+ (const Vector3T<T>& v1, const Vector3T<T>& v2) { return Vector3T<T>(v1.x+v2.x, v1.y+v2.y, v1.z+v2.z); }
00084 template <class T> inline Vector3T<T> operator- (const Vector3T<T>& v1, const Vector3T<T>& v2) { return Vector3T<T>(v1.x-v2.x, v1.y-v2.y, v1.z-v2.z); }
00085 template <class T> inline Vector3T<T> operator* (const Vector3T<T>& v, const double s) { return Vector3T<T>(v.x*s, v.y*s, v.z*s); }
00086 template <class T> inline Vector3T<T> operator* (const double s, const Vector3T<T>& v) { return v*s; }
00087 template <class T> inline Vector3T<T> operator/ (const Vector3T<T>& v, const double s) { double r = 1.0/s; return v*r; }
00088 template <class T> inline Vector3T<T> operator- (const Vector3T<T>& v) { return Vector3T<T>(-v.x, -v.y, -v.z); }
00089
00090 template <class T>
00091 float abs(Vector3T<T> t)
00092 {
00093 return t.length();
00094 }
00095
00096 template <class T>
00097 std::ostream &operator<<(std::ostream &os, const Vector3T<T> &t)
00098 {
00099 os << t.x << ' ' << t.y << ' ' << t.z;
00100 return os;
00101 }
00102
00103 template <class T>
00104 std::istream &operator>>(std::istream &is, Vector3T<T> &t)
00105 {
00106 is >> t.x;
00107 is >> t.y;
00108 is >> t.z;
00109 return is;
00110 }
00111
00112 template <class T>
00113 inline float dot(const Vector3T<T>& a, const Vector3T<T>& b)
00114 {
00115 return a[0]*b[0] + a[1]*b[1] + a[2]*b[2];
00116 }
00117
00118 template <class T>
00119 inline Vector3T<T> cross(const Vector3T<T>& a, const Vector3T<T>& b)
00120 {
00121 Vector3T<T> v((a[1]*b[2])-(a[2]*b[1]),
00122 -(a[0]*b[2])+(a[2]*b[0]),
00123 (a[0]*b[1])-(a[1]*b[0]));
00124 return v;
00125 }
00126
00127 typedef Vector3T<float> Vector3;
00128
00129 inline Vector3 randOnSphere()
00130 {
00131 float d,x,y,z;
00132 do
00133 {
00134 x = 2.0*urand( )-1.0; y = 2.0*urand( )-1.0; z = 2.0*urand( )-1.0;
00135 d = x*x+y*y+z*z;
00136 }
00137 while( d > 1.0f || d == 0.0);
00138 return Vector3(x,y,z)/sqrt(d);
00139 }
00140
00141 inline Vector3 randInSphere()
00142 {
00143 float d,x,y,z;
00144 do
00145 {
00146 x = 2.0*urand( )-1.0; y = 2.0*urand( )-1.0; z = 2.0*urand( )-1.0;
00147 d = x*x+y*y+z*z;
00148 }
00149 while( d > 1.0f );
00150 return Vector3(x,y,z);
00151 }
00152
00153 #endif