00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef _vector4_h
00018 #define _vector4_h
00019
00020 #include <spl/types.h>
00021 #include <spl/Debug.h>
00022 #include <spl/math/Point.h>
00023
00029 template<typename T, typename FLOATTYPE> class Matrix3;
00030 template<typename T, typename FLOATTYPE> class Matrix4;
00031
00033 template <typename T, typename FLOATTYPE>
00034 class Vector3 : public Point3<T, FLOATTYPE>, public IMemoryValidate
00035 {
00036 protected:
00037
00038 public:
00039 Vector3()
00040 : Point3<T,FLOATTYPE>()
00041 {
00042 }
00043
00044 Vector3(T x)
00045 : Point3<T,FLOATTYPE>(x)
00046 {
00047 }
00048
00049 Vector3(T x, T y)
00050 : Point3<T,FLOATTYPE>(x, y)
00051 {
00052 }
00053
00054 Vector3(T x, T y, T z)
00055 : Point3<T,FLOATTYPE>(x, y, z)
00056 {
00057 }
00058
00059 Vector3(const Vector3<T, FLOATTYPE>& v)
00060 : Point3<T, FLOATTYPE>(v)
00061 {
00062 }
00063
00065 inline FLOATTYPE Length()
00066 {
00067 return (FLOATTYPE)FastMath::Sqrt((FLOATTYPE)(m_x*m_x+m_y*m_y+m_z*m_z));
00068 }
00069
00071 void Normalize()
00072 {
00073 FLOATTYPE dist = Length();
00074 if (dist == 0)
00075 {
00076 return;
00077 }
00078 FLOATTYPE invdist = 1 / dist;
00079 m_x = (T)(m_x * invdist);
00080 m_y = (T)(m_y * invdist);
00081 m_z = (T)(m_z * invdist);
00082 }
00083
00085 void Reverse()
00086 {
00087 m_x = -m_x;
00088 m_y = -m_y;
00089 m_z = -m_z;
00090 }
00091
00093 Vector3<T,FLOATTYPE> Transform(Matrix3<T,FLOATTYPE> *m)
00094 {
00095 return Vector3<T,FLOATTYPE>(
00096 m_x*m->m00 + m_y*m->m01 + m_z*m->m02+ m_w*m->m03,
00097 m_x*m->m10 + m_y*m->m11 + m_z*m->m12+ m_w*m->m13,
00098 m_x*m->m20 + m_y*m->m21 + m_z*m->m22+ m_w*m->m23
00099 );
00100 }
00101
00103 Vector3<T,FLOATTYPE> Transform(Matrix4<T,FLOATTYPE> *m)
00104 {
00105 return Vector3<T,FLOATTYPE>(
00106 m_x*m->m00 + m_y*m->m01 + m_z*m->m02+ m->m03,
00107 m_x*m->m10 + m_y*m->m11 + m_z*m->m12+ m->m13,
00108 m_x*m->m20 + m_y*m->m21 + m_z*m->m22+ m->m23);
00109 }
00110
00111 void MultEqual( Matrix3<T,FLOATTYPE> *m )
00112 {
00113 FLOATTYPE a, b, c;
00114
00115 a = m_x * m->m00 + m_y * m->m01 + m_z * m->m02;
00116 b = m_x * m->m10 + m_y * m->m11 + m_z * m->m12;
00117 c = m_x * m->m20 + m_y * m->m21 + m_z * m->m22;
00118 m_x = a;
00119 m_y = b;
00120 m_z = c;
00121 }
00122
00123 void MultEqual( Vector3<T,FLOATTYPE> *v )
00124 {
00125 m_x *= v->m_x;
00126 m_y *= v->m_y;
00127 m_z *= v->m_z;
00128 }
00129
00131 static void GetCylindric(T x, T y, FLOATTYPE *r, FLOATTYPE *theta)
00132 {
00133 *r = (FLOATTYPE)FastMath::Sqrt(x*x + y*y);
00134 *theta = (FLOATTYPE)Math::Atan2(x, y);
00135 }
00136
00137 static void GetCartesian(T *x, T *y, FLOATTYPE r, FLOATTYPE theta)
00138
00139 {
00140 *x = r * FastMath::Cos(theta);
00141 *y = r * FastMath::Sin(theta);
00142 }
00143
00145 static Vector3<T,FLOATTYPE> GetNormal(Vector4<T,FLOATTYPE> *a, Vector4<T,FLOATTYPE> *b)
00146 {
00147 Vector3<T,FLOATTYPE> v = VectorProduct(a, b);
00148 v.Normalize();
00149 return v;
00150 }
00151
00153 static Vector3<T,FLOATTYPE> GetNormal(Vector3<T,FLOATTYPE> *a, Vector3<T,FLOATTYPE> *b, Vector3<T,FLOATTYPE> *c)
00154 {
00155 Vector3<T,FLOATTYPE> v = VectorProduct(a,b,c);
00156 v.Normalize();
00157 return v;
00158 }
00159
00161 static Vector3<T,FLOATTYPE> VectorProduct(Vector3<T,FLOATTYPE> *a, Vector3<T,FLOATTYPE> *b)
00162 {
00163 return Vector3<T,FLOATTYPE>(a->m_y*b->m_z-b->m_y*a->m_z,a->m_z*b->m_x-b->m_z*a->m_x,a->m_x*b->m_y-b->m_x*a->m_y);
00164 }
00165
00167 static Vector3<T,FLOATTYPE> VectorProduct(Vector4<T,FLOATTYPE> *a, Vector3<T,FLOATTYPE> *b, Vector3<T,FLOATTYPE> *c)
00168 {
00169 Vector4<T,FLOATTYPE> v1 = Sub(b, a);
00170 Vector4<T,FLOATTYPE> v2 = Sub(c, a);
00171 return VectorProduct(&v1, &v2);
00172 }
00173
00174 inline FLOATTYPE DotProduct(Vector3<T,FLOATTYPE> *b)
00175 {
00176 return m_x*b->m_x + m_y*b->m_y + m_z*b->m_z;
00177 }
00178
00180 Vector3<T,FLOATTYPE> CrossProduct( Vector3<T,FLOATTYPE> *w )
00181 {
00182 Vector3<T,FLOATTYPE> v(
00183 m_y * w.m_z - m_z * w.m_y,
00184 m_z * w.m_x - m_x * w.m_z,
00185 m_x * w.m_y - m_y * w.m_x);
00186 return v;
00187 }
00188
00189 void Translate(FLOATTYPE x, FLOATTYPE y, FLOATTYPE z)
00190 {
00191 m_x += x;
00192 m_y += y;
00193 m_z += z;
00194 }
00195
00196 Vector3<T, FLOATTYPE> ToNormalized()
00197 {
00198 Vector3<T, FLOATTYPE> v = *this;
00199 v.Normalize();
00200 return v;
00201 }
00202
00204 static FLOATTYPE Angle(Vector3<T,FLOATTYPE> *a, Vector3<T,FLOATTYPE> *b)
00205 {
00206 a->Normalize();
00207 b->Normalize();
00208 return a->m_x*b->m_x + a->m_y*b->m_y + a->m_z*b->m_z;
00209 }
00210
00212 static Vector3<T,FLOATTYPE> Add(Vector3<T,FLOATTYPE> *a, Vector3<T,FLOATTYPE> *b)
00213 {
00214 return Vector3<T,FLOATTYPE>(a->m_x+b->m_x, a->m_y+b->m_y, a->m_z+b->m_z);
00215 }
00216
00218 static Vector3<T,FLOATTYPE> Sub(Vector3<T,FLOATTYPE> *a, Vector3<T,FLOATTYPE> *b)
00219 {
00220 return Vector3<T,FLOATTYPE>(a->m_x-b->m_x, a->m_y-b->m_y, a->m_z-b->m_z);
00221 }
00222
00223 static Vector3<T,FLOATTYPE> Scale(FLOATTYPE f, Vector3<T,FLOATTYPE> *a)
00224 {
00225 return Vector3<T,FLOATTYPE>(f*a->m_x, f*a->m_y, f*a->m_z);
00226 }
00227
00228 virtual void ValidateMem () const
00229 {
00230 }
00231 virtual void CheckMem () const
00232 {
00233 }
00234 };
00235
00237 template <typename T, typename FLOATTYPE>
00238 class Vector4 : public Point4<T, FLOATTYPE>, public IMemoryValidate
00239 {
00240 protected:
00241
00242 public:
00243 Vector4()
00244 : Point4<T,FLOATTYPE>()
00245 {
00246 }
00247
00248 Vector4(T x)
00249 : Point4<T,FLOATTYPE>(x)
00250 {
00251 }
00252
00253 Vector4(T x, T y)
00254 : Point4<T,FLOATTYPE>(x, y)
00255 {
00256 }
00257
00258 Vector4(T x, T y, T z)
00259 : Point4<T,FLOATTYPE>(x, y, z)
00260 {
00261 }
00262
00263 Vector4(T x, T y, T z, T w)
00264 : Point4<T,FLOATTYPE>(x, y, z, w)
00265 {
00266 }
00267
00268 Vector4(const Vector4<T, FLOATTYPE>& v)
00269 : Point4<T, FLOATTYPE>(v)
00270 {
00271 }
00272
00273 inline T X() { return m_x; }
00274 inline T Y() { return m_y; }
00275 inline T Z() { return m_z; }
00276 inline T W() { return m_w; }
00277
00279 inline FLOATTYPE Length()
00280 {
00281 return (FLOATTYPE)FastMath::Sqrt((FLOATTYPE)(m_x*m_x+m_y*m_y+m_z*m_z+m_w*m_w));
00282 }
00283
00285 void Normalize()
00286 {
00287 FLOATTYPE dist = Length();
00288 if (dist == 0)
00289 {
00290 return;
00291 }
00292 FLOATTYPE invdist = 1 / dist;
00293 m_x = (T)(m_x * invdist);
00294 m_y = (T)(m_y * invdist);
00295 m_z = (T)(m_z * invdist);
00296 m_w = (T)(m_w * invdist);
00297 }
00298
00300 void Reverse()
00301 {
00302 m_x = -m_x;
00303 m_y = -m_y;
00304 m_z = -m_z;
00305 m_w = -m_w;
00306 }
00307
00308
00310 Vector4<T,FLOATTYPE> Transform(Matrix4<T,FLOATTYPE> *m)
00311 {
00312 return Vector4<T,FLOATTYPE>(
00313 m_x*m->m00 + m_y*m->m01 + m_z*m->m02+ m_w*m->m03,
00314 m_x*m->m10 + m_y*m->m11 + m_z*m->m12+ m_w*m->m13,
00315 m_x*m->m20 + m_y*m->m21 + m_z*m->m22+ m_w*m->m23
00316 );
00317 }
00318
00320 static void GetCylindric(T x, T y, FLOATTYPE *r, FLOATTYPE *theta)
00321 {
00322 *r = (FLOATTYPE)FastMath::Sqrt(x*x + y*y);
00323 *theta = (FLOATTYPE)Math::Atan2(x, y);
00324 }
00325
00326 static void GetCartesian(T *x, T *y, FLOATTYPE r, FLOATTYPE theta)
00327
00328 {
00329 *x = r * FastMath::Cos(theta);
00330 *y = r * FastMath::Sin(theta);
00331 }
00332
00334 static Vector4<T,FLOATTYPE> GetNormal(Vector4<T,FLOATTYPE> *a, Vector4<T,FLOATTYPE> *b)
00335 {
00336 Vector4<T,FLOATTYPE> v = VectorProduct(a, b);
00337 v.Normalize();
00338 return v;
00339 }
00340
00342 static Vector4<T,FLOATTYPE> GetNormal(Vector4<T,FLOATTYPE> *a, Vector4<T,FLOATTYPE> *b, Vector4<T,FLOATTYPE> *c)
00343 {
00344 Vector4<T,FLOATTYPE> v = VectorProduct(a,b,c);
00345 v.Normalize();
00346 return v;
00347 }
00348
00350 static Vector4<T,FLOATTYPE> VectorProduct(Vector4<T,FLOATTYPE> *a, Vector4<T,FLOATTYPE> *b)
00351 {
00352 return Vector4<T,FLOATTYPE>(a->m_y*b->m_z-b->m_y*a->m_z,a->m_z*b->m_x-b->m_z*a->m_x,a->m_x*b->m_y-b->m_x*a->m_y);
00353 }
00354
00356 static Vector4<T,FLOATTYPE> VectorProduct(Vector4<T,FLOATTYPE> *a, Vector4<T,FLOATTYPE> *b, Vector4<T,FLOATTYPE> *c)
00357 {
00358 Vector4<T,FLOATTYPE> v1 = Sub(b, a);
00359 Vector4<T,FLOATTYPE> v2 = Sub(c, a);
00360 return VectorProduct(&v1, &v2);
00361 }
00362
00363 inline FLOATTYPE DotProduct(Vector4<T,FLOATTYPE> *b)
00364 {
00365 return m_x*b->m_x + m_y*b->m_y + m_z*b->m_z + m_w*b->m_w;
00366 }
00367
00369 Vector4<T,FLOATTYPE> CrossProduct( Vector4<T,FLOATTYPE> *w )
00370 {
00371 Vector4<T,FLOATTYPE> v(
00372 m_y * w.m_z - z * w.m_y,
00373 m_z * w.m_x - m_x * w.m_z,
00374 m_x * w.m_y - m_y * w.m_x);
00375 return v;
00376 }
00377
00379 static FLOATTYPE Angle(Vector4<T,FLOATTYPE> *a, Vector4<T,FLOATTYPE> *b)
00380 {
00381 a->Normalize();
00382 b->Normalize();
00383 return a->m_x*b->m_x + a->m_y*b->m_y + a->m_z*b->m_z + a->m_w*b->m_w;
00384 }
00385
00387 static Vector4<T,FLOATTYPE> Add(Vector4<T,FLOATTYPE> *a, Vector4<T,FLOATTYPE> *b)
00388 {
00389 return Vector4<T,FLOATTYPE>(a->m_x+b->m_x, a->m_y+b->m_y, a->m_z+b->m_z, a->m_w+b->m_w);
00390 }
00391
00393 static Vector4<T,FLOATTYPE> Sub(Vector4<T,FLOATTYPE> *a, Vector4<T,FLOATTYPE> *b)
00394 {
00395 return Vector4<T,FLOATTYPE>(a->m_x-b->m_x, a->m_y-b->m_y, a->m_z-b->m_z, a->m_w-b->m_w);
00396 }
00397
00398 static Vector4<T,FLOATTYPE> Scale(FLOATTYPE f, Vector4<T,FLOATTYPE> *a)
00399 {
00400 return Vector4<T,FLOATTYPE>(f*a->m_x, f*a->m_y, f*a->m_z, f*a->m_w);
00401 }
00402
00403 Vector4<T, FLOATTYPE> ToNormalized()
00404 {
00405 Vector4<T, FLOATTYPE> v = *this;
00406 v.Normalize();
00407 return v;
00408 }
00409
00410 virtual void ValidateMem () const
00411 {
00412 }
00413 virtual void CheckMem () const
00414 {
00415 }
00416 };
00417
00418 #include <spl/math/Matrix.h>
00419
00422 #endif