• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

spl/math/Vector.h

00001 /*
00002  *   This file is part of the Standard Portable Library (SPL).
00003  *
00004  *   SPL is free software: you can redistribute it and/or modify
00005  *   it under the terms of the GNU General Public License as published by
00006  *   the Free Software Foundation, either version 3 of the License, or
00007  *   (at your option) any later version.
00008  *
00009  *   SPL is distributed in the hope that it will be useful,
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *   GNU General Public License for more details.
00013  *
00014  *   You should have received a copy of the GNU General Public License
00015  *   along with SPL.  If not, see <http://www.gnu.org/licenses/>.
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         // Builds the cartesian coordinates out of the given cylindric coordinates
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         // Builds the cartesian coordinates out of the given cylindric coordinates
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