Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   Related Pages  

sglVec3.hpp

00001 /*****************************************************************************
00002  * SGL: A Scene Graph Library
00003  *
00004  * Copyright (C) 1997-2001  Scott McMillan   All Rights Reserved.
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Library General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Library General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Library General Public
00017  * License along with this library; if not, write to the Free
00018  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019  *****************************************************************************
00020  *     File: sglVec3.hpp
00021  *  Created: 8 March 1999
00022  *  Summary: 3D templated vector class
00023  *****************************************************************************/
00024 
00025 #ifndef __SGL_VEC3_HPP
00026 #define __SGL_VEC3_HPP
00027 
00028 #include <sgl.h>
00029 
00030 template <class T> class sglMat3;
00031 template <class T> class sglVec2;
00032 
00033 // ---------------------------------------------------------------------------
00034 template <class T>
00035 class sglVec3
00036 {
00037 public:
00038    // constructors
00039    sglVec3() {};
00040 
00041    sglVec3(T x, T y, T z)
00042       { m_vector[0] = x; m_vector[1] = y; m_vector[2] = z; }
00043 
00044    template <class S>
00045    sglVec3(const sglVec3<S>& vec)
00046       {
00047          m_vector[0] = (T)vec[0];
00048          m_vector[1] = (T)vec[1];
00049          m_vector[2] = (T)vec[2];
00050       }
00051 
00052    // destructor
00053    ~sglVec3() {};  // not virtual, do not subclass
00054 
00055    inline T *getPtr() const { return (T *)m_vector; }
00056 
00057    // indexing operators
00058    inline       T& operator[](unsigned int i)       { return m_vector[i]; }
00059    inline const T& operator[](unsigned int i) const { return m_vector[i]; }
00060 
00061    // set from any other type
00062    template <class S>
00063    inline void set(S x, S y, S z)
00064       {
00065          m_vector[0] = (T)x; m_vector[1] = (T)y; m_vector[2] = (T)z;
00066       }  
00067     
00068    // assignment operators
00069    template <class S>
00070    inline sglVec3 &operator=(const sglVec3<S>& vec)
00071       {
00072          m_vector[0] = (T)vec[0];
00073          m_vector[1] = (T)vec[1];
00074          m_vector[2] = (T)vec[2];
00075          return *this;
00076       }
00077 
00078    // boolean operators
00079    template <class S>
00080    inline bool operator==(const sglVec3<S>& vec) const
00081       {
00082          return (m_vector[0] == (T)vec[0] &&
00083                  m_vector[1] == (T)vec[1] &&
00084                  m_vector[2] == (T)vec[2]);
00085       }
00086    template <class S>
00087    inline bool operator!=(const sglVec3<S>& vec) const
00088       {
00089          return (m_vector[0] != (T)vec[0] ||
00090                  m_vector[1] != (T)vec[1] ||
00091                  m_vector[2] != (T)vec[2]);
00092       }
00093 
00094    template <class S>
00095    inline bool operator<(const sglVec3<S>& vec) const
00096       {
00097          return (dot(*this) < vec.dot(vec));
00098       }
00099    template <class S>
00100    inline bool operator>(const sglVec3<S>& vec) const
00101       {
00102          return (dot(*this) > vec.dot(vec));
00103       }
00104 
00105    // math operators
00106    template <class S>
00107    inline sglVec3& operator+=(const sglVec3<S>& vec)
00108       {
00109          m_vector[0]+=(T)vec[0];
00110          m_vector[1]+=(T)vec[1];
00111          m_vector[2]+=(T)vec[2];
00112          return *this;
00113       }
00114    template <class S>
00115    inline sglVec3& operator-=(const sglVec3<S>& vec)
00116       {
00117          m_vector[0]-=(T)vec[0];
00118          m_vector[1]-=(T)vec[1];
00119          m_vector[2]-=(T)vec[2];
00120          return *this;
00121       }
00122    inline sglVec3& operator*=(const T s)
00123       {
00124          m_vector[0] *= s;
00125          m_vector[1] *= s;
00126          m_vector[2] *= s;
00127          return *this;
00128       }
00129 
00130    template <class S>
00131    inline const sglVec3<T> operator+(const sglVec3<S> &rhs) const
00132       {
00133          return sglVec3(m_vector[0]+(T)rhs[0],
00134                         m_vector[1]+(T)rhs[1],
00135                         m_vector[2]+(T)rhs[2]);
00136       }
00137    template <class S>
00138    inline const sglVec3<T> operator-(const sglVec3<S> &rhs) const
00139       {
00140          return sglVec3(m_vector[0]-(T)rhs[0],
00141                         m_vector[1]-(T)rhs[1],
00142                         m_vector[2]-(T)rhs[2]);
00143       }
00144    inline const sglVec3<T> operator*(T scalar) const
00145       {
00146          return sglVec3(m_vector[0]*scalar,
00147                         m_vector[1]*scalar,
00148                         m_vector[2]*scalar);
00149       }
00150 
00151    // explicit math operations (for backward compatibility)
00152    template <class S1, class S2>
00153    inline void add(const sglVec3<S1>& vec1, const sglVec3<S2>& vec2)
00154       {
00155          m_vector[0] = (T)vec1[0] + (T)vec2[0];
00156          m_vector[1] = (T)vec1[1] + (T)vec2[1];
00157          m_vector[2] = (T)vec1[2] + (T)vec2[2];
00158       }
00159    template <class S1, class S2>
00160    inline void sub(const sglVec3<S1>& vec1, const sglVec3<S2>& vec2)
00161       {
00162          m_vector[0] = (T)vec1[0] - (T)vec2[0];
00163          m_vector[1] = (T)vec1[1] - (T)vec2[1];
00164          m_vector[2] = (T)vec1[2] - (T)vec2[2]; 
00165       }
00166    template <class S>
00167    inline void scale(const sglVec3<S>& vec, T s)
00168       {
00169          m_vector[0] = (T)vec[0]*s;
00170          m_vector[1] = (T)vec[1]*s;
00171          m_vector[2] = (T)vec[2]*s;
00172       }
00173 
00174 
00175    // other ops
00176    template <class S>
00177    inline bool almostEqual(const sglVec3<S>& vec, double eps) const
00178       {
00179          return (SGL_ALMOST_EQUAL(m_vector[0], vec[0], eps) &&
00180                  SGL_ALMOST_EQUAL(m_vector[1], vec[1], eps) &&
00181                  SGL_ALMOST_EQUAL(m_vector[2], vec[2], eps));
00182       }
00183 
00184    template <class S>
00185    inline void cross(const sglVec3<S>& vec)
00186       {
00187          // temporaries required in case vec == this
00188          T x         = m_vector[1]*(T)vec[2] - m_vector[2]*(T)vec[1];
00189          T y         = m_vector[2]*(T)vec[0] - m_vector[0]*(T)vec[2];
00190          m_vector[2] = m_vector[0]*(T)vec[1] - m_vector[1]*(T)vec[0];
00191          m_vector[0] = x; m_vector[1] = y;
00192       }
00193 
00194    template <class S1, class S2>
00195    inline void cross(const sglVec3<S1>& vec1, const sglVec3<S2>& vec2)
00196       {
00197          // temporaries required in case vec1 or vec2 == this
00198          T x         = (T)vec1[1]*(T)vec2[2] - (T)vec1[2]*(T)vec2[1];
00199          T y         = (T)vec1[2]*(T)vec2[0] - (T)vec1[0]*(T)vec2[2];
00200          m_vector[2] = (T)vec1[0]*(T)vec2[1] - (T)vec1[1]*(T)vec2[0];
00201          m_vector[0] = x; m_vector[1] = y;
00202       }
00203 
00204    // reducing methods which result is a T
00205    template <class S>
00206    inline T dot(const sglVec3<S>& vec) const
00207       {
00208          return (m_vector[0]*(T)vec[0] +
00209                  m_vector[1]*(T)vec[1] +
00210                  m_vector[2]*(T)vec[2]);
00211       }
00212 
00213    template <class S, class R>
00214    inline static R dot(const sglVec3<R>& vec1, const sglVec3<S>& vec2)
00215       {
00216          return (vec1[0]*(R)vec2[0] +
00217                  vec1[1]*(R)vec2[1] +
00218                  vec1[2]*(R)vec2[2]);
00219       }
00220 
00221    inline T length() const
00222       {
00223          return (T) sqrt(dot(*this));
00224       }
00225 
00226    template <class S>
00227    inline T distance(const sglVec3<S>& vec) const
00228       {
00229          return (T) sqrt(((T)vec[0] - m_vector[0])*((T)vec[0] - m_vector[0])+
00230                          ((T)vec[1] - m_vector[1])*((T)vec[1] - m_vector[1])+
00231                          ((T)vec[2] - m_vector[2])*((T)vec[2] - m_vector[2]));
00232       }
00233 
00234    inline T normalize()
00235       {
00236          T len = length();
00237          if (len) *this *= (1.0/len);
00238          return len;
00239       }
00240 
00241    template <class S>
00242    inline T normalize(const sglVec3<S>& vec)
00243       {
00244          T len = vec.length();
00245          if (len) scale(vec, 1.0/len);
00246          return len;
00247       }
00248 
00249    // stream operators
00250 #if defined(TEMPLATE_OSTREAM_HACK)
00251    template <class S> 
00252    friend ostream& operator<< (ostream& ostrm, const sglVec3<S>& vec);
00253 
00254    template <class S> 
00255    friend istream& operator>> (istream& istrm, sglVec3<S>& vec);
00256 #else
00257    friend ostream& operator<< (ostream& ostrm, const sglVec3<T>& vec)
00258         {
00259             return (ostrm << "(" << vec[0] << ", " << vec[1]
00260                     << ", " << vec[2] << ")");
00261         }
00262 
00263    friend istream& operator>> (istream& istrm, sglVec3<T>& vec)
00264         {
00265             return (istrm >> vec[0] >> vec[1] >> vec[2]);
00266         }
00267 #endif
00268 
00269 private:
00270    T m_vector[3];
00271 };
00272 
00273 //----------------------------------------------------------------------------
00274 #if defined(TEMPLATE_OSTREAM_HACK)
00275 template <class T>
00276 inline ostream& operator<< (ostream& ostrm, const sglVec3<T>& vec)
00277 {
00278     return (ostrm << "(" << vec[0] << ", " << vec[1] << ", " << vec[2] << ")");
00279 }
00280 
00281 template <class T>
00282 inline istream& operator>> (istream& istrm, sglVec3<T>& vec)
00283 {
00284     return (istrm >> vec[0] >> vec[1] >> vec[2]);
00285 }
00286 #endif
00287 //----------------------------------------------------------------------------
00288 
00289 #endif

Generated at Mon Jul 1 18:00:06 2002 for SGL by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001