Vector.h

Go to the documentation of this file.
00001 /**<!-------------------------------------------------------------------->
00002    @class  Vector
00003    @author Travis Fischer (fisch0920@gmail.com)
00004    @date   Fall 2008
00005    
00006    @brief
00007       Provides basic functionality for a constant-sized Vector
00008    <!-------------------------------------------------------------------->**/
00009 
00010 #ifndef VECTOR_H_
00011 #define VECTOR_H_
00012 
00013 #include <common/common.h>
00014 #include <iostream>
00015 #include <limits>
00016 
00017 #define VECTOR_NO_ELEMENTS    (N)
00018 #define VECTOR_SIZE           (sizeof(T) * VECTOR_NO_ELEMENTS)
00019 
00020 /**
00021  * @brief
00022  *    A Vector is templated to store N elements of data of type T.  If 
00023  * left off, T will default to a "real_t" data type, where a real_t is 
00024  * assumed to be either a float or a double.
00025  * 
00026  * Included in this definition are typedefs for the most commonly used 
00027  * vectors (Vector4, Vector3, etc), and these can be thought of as shortcuts 
00028  * to reference their associated Vector templates.  For example, 
00029  * Vector4 can be used to refer to Vector<4, real_t>.
00030  * 
00031  * A Vector stores its data internally as an N-length array of type T.
00032  */
00033 template <unsigned N = 3, typename T = real_t>
00034 struct Vector {
00035    
00036    /// Underlying data stored as an N-length array of type T
00037    T data[VECTOR_NO_ELEMENTS];
00038    
00039    
00040    ///@name Constructors
00041    //@{-----------------------------------------------------------------
00042    
00043    /// Expects N arguments of type T
00044    inline Vector(const T *srcData);
00045    
00046    /// Constructs a zero Vector
00047    inline Vector();
00048    
00049    /// Copy Constructor
00050    inline Vector(const Vector<N, T> &v);
00051    
00052    
00053    //@}-----------------------------------------------------------------
00054    ///@name Static convenience constructors to generate common vectors
00055    //@{-----------------------------------------------------------------
00056    
00057    /// Generates a vector full of zeroes
00058    static inline Vector<N, T> zero() {
00059       return Vector<N, T>();
00060    }
00061    
00062    /// Generates a vector full of ones
00063    static inline Vector<N, T> ones() {
00064       return Vector<N, T>::fill(1);
00065    }
00066    
00067    /// Generates a vector filled with the specified value
00068    static inline Vector<N, T> fill(const T &val) {
00069       Vector<N, T> ret = Vector<N, T>::zero();
00070       
00071       for(unsigned i = N; i--;)
00072          ret[i] = val;
00073       
00074       return ret;
00075    }
00076    
00077    /// @returns the element-wise minimum vector from the two given vectors
00078    static inline Vector<N, T> min(const Vector<N, T> &v1, const Vector<N, T> &v2) {
00079       Vector<N, T> ret;
00080       
00081       for(unsigned i = N; i--;)
00082          ret[i] = MIN(v1[i], v2[i]);
00083 
00084       return ret;
00085    }
00086    
00087    /// @returns the element-wise maximum vector from the two given vectors
00088    static inline Vector<N, T> max(const Vector<N, T> &v1, const Vector<N, T> &v2) {
00089       Vector<N, T> ret;
00090       
00091       for(unsigned i = N; i--;)
00092          ret[i] = MAX(v1[i], v2[i]);
00093 
00094       return ret;
00095    }
00096 
00097    /// Generates a vector filled with the maximum T (infinity)
00098    static inline Vector<N, T> infinity() {
00099       return Vector<N, T>::fill(std::numeric_limits<T>::max());
00100    }
00101    
00102    /// Generates a vector filled with the minimum T (negative infinity)
00103    static inline Vector<N, T> negativeInfinity() {
00104       // note std::numeric_limits<T>::min() for float and double returns 
00105       // the smallest positive number representable, not the smallest 
00106       // valid floating point number that type can hold...
00107       return Vector<N, T>::fill(-std::numeric_limits<T>::max());
00108    }
00109    
00110    /// theta is latitude angle; phi is longitude angle
00111    static inline Vector<3, T> fromSpherical(T theta, T phi) {
00112       return Vector<3, T>(sin(theta) * cos(phi), 
00113                           cos(theta), 
00114                           sin(theta) * sin(phi)).getNormalized();
00115    }
00116    
00117    /// Samples a random vector distributed according to a cosine-falloff about 
00118    /// the given normal vector (within the upward hemisphere defined by the 
00119    /// normal)
00120    static Vector<3, real_t> cosRandom(const Vector<3, real_t> &normal);
00121    
00122    
00123    //@}-----------------------------------------------------------------
00124    ///@name Accessor Operators
00125    //@{-----------------------------------------------------------------
00126 
00127    /// @returns a const reference to the element at the given index
00128    inline const T &operator[](const unsigned index) const;
00129    /// @returns a       reference to the element at the given index
00130    /// @note changes to the returned element will affect this vector
00131    inline       T &operator[](const unsigned index);
00132    
00133    /// @returns a pointer to the underlying data (N-length array of type T)
00134    inline const T *operator*() const;
00135    /// @returns a pointer to the underlying data (N-length array of type T)
00136    inline       T *operator*();
00137    
00138    
00139    //@}-----------------------------------------------------------------
00140    ///@name Equality Operators
00141    //@{-----------------------------------------------------------------
00142    
00143    inline       bool       operator==(const Vector<N, T> &v) const;
00144    inline       bool       operator!=(const Vector<N, T> &v) const;
00145    
00146    
00147    //@}-----------------------------------------------------------------
00148    ///@name Mutator Operators
00149    //@{-----------------------------------------------------------------
00150    
00151    inline       Vector<N, T> &operator =(const Vector<N, T> &v);
00152    inline       Vector<N, T> &operator+=(const Vector<N, T> &rhs);
00153    inline       Vector<N, T> &operator-=(const Vector<N, T> &rhs);
00154    
00155    
00156    //@}-----------------------------------------------------------------
00157    ///@name Scalar Mutator Operators
00158    //@{-----------------------------------------------------------------
00159    
00160    inline       Vector<N, T> &operator*=(const T &scale);
00161    inline       Vector<N, T> &operator/=(const T &scale);
00162    
00163    
00164    //@}-----------------------------------------------------------------
00165    ///@name Arithmetic Operators
00166    //@{-----------------------------------------------------------------
00167    
00168    inline       Vector<N, T>  operator+ (const Vector<N, T> &rhs) const;
00169    inline       Vector<N, T>  operator- (const Vector<N, T> &rhs) const;
00170    
00171    /// @returns element-wise multiplication of two vectors
00172    inline       Vector<N, T>  operator* (const Vector<N, T> &rhs) const;
00173    
00174    
00175    //@}-----------------------------------------------------------------
00176    ///@name Scalar Arithmetic Operators
00177    //@{-----------------------------------------------------------------
00178    
00179    inline       Vector<N, T>  operator* (const T &scale) const;
00180    inline       Vector<N, T>  operator/ (const T &scale) const;
00181    
00182    
00183    //@}-----------------------------------------------------------------
00184    ///@name More Complex Functionality
00185    //@{-----------------------------------------------------------------
00186    
00187    /// @returns whether or not this Vector is unitized
00188    inline bool isUnit() const;
00189    
00190    /// @returns whether or not this Vector is the zero vector
00191    inline bool isZero() const;
00192    
00193    /// @returns a normalized version of this vector
00194    inline Vector<N, T> getNormalized() const;   
00195     
00196    /// @returns the reciprocal version of this vector (1.0 / this)
00197    inline Vector<N, T> getReciprocal() const;
00198    
00199    /// Normalizes this Vector and returns the old magnitude
00200    inline T normalize();
00201    
00202    /// @returns the magnitude of this vector
00203    inline T getMagnitude() const;
00204    
00205    /// @returns the squared magnitude of this vector
00206    inline T getMagnitude2() const;
00207    
00208    /// @returns the magnitude of the vector connecting this vector to the one 
00209    ///    passed in
00210    inline T getDistance(const Vector<N, T> &v) const; 
00211    
00212    /// @returns the squared magnitude of the vector connecting this vector to 
00213    ///    the one passed in
00214    inline T getDistance2(const Vector<N, T> &v) const;
00215    
00216    /// @returns the sum of the components in this Vector
00217    inline T getSum() const;
00218    
00219    /// @returns the average of the components in this Vector
00220    inline T getAverage() const;
00221    
00222    /// @returns the dot (inner) product of two vectors
00223    inline T dot(const Vector<N, T> &rhs) const;
00224    
00225    /// @returns dimension (0,1,...,N) of maximum length
00226    inline unsigned getMaxDimension() const;
00227    
00228    /// @returns dimension (0,1,...,N) of minimum length
00229    inline unsigned getMinDimension() const;
00230    
00231    /// Cleans up vector (0's out entries that are less than epsilon)
00232    void cleanup();
00233    
00234    
00235    //@}-----------------------------------------------------------------
00236    ///@name Specialized Vector Functionality
00237    //@{-----------------------------------------------------------------
00238    
00239    /// Convenience Constructor
00240    inline explicit Vector(const T &v0, const T &v1 = 0, const T &v2 = 0);
00241    
00242    /// @returns the cross product of two vectors
00243    /// @note only have to implement for 3 or 4 dimensions
00244    ///    (in either case, just use hardcoded cross product for 3 dimensions and 
00245    ///     if N is 4, set 'w' to 0)
00246    inline Vector<N, T> cross(const Vector<N, T> &rhs) const;
00247    
00248    /**
00249     * Assumes normal is normalized, incident vector is incoming and
00250     * resultant vector is exiting
00251     * 
00252     * @note only defined for Vector3
00253     */
00254    Vector<N, T> reflectVector(const Vector<N, T> &normal) const;
00255    Vector<N, T> refractVector(const Vector<N, T> &normal, real_t in, 
00256                               real_t out = 1.0f) const;
00257    
00258    /**
00259     * @returns an orthonormal basis constructed from this vector in out 
00260     *    parameters U and V
00261     * 
00262     * @note only defined for Vector3
00263     */
00264    void getOrthonormalBasis(Vector<N, T> &U, Vector<N, T> &V);
00265    
00266    
00267    //@}-----------------------------------------------------------------
00268 };
00269 
00270 
00271 /// @brief Standard 4-element vector of real_ts
00272 typedef Vector<4> Vector4;
00273 
00274 /// @brief Standard 3-element vector of real_ts
00275 typedef Vector<3> Vector3;
00276 
00277 /// @brief Standard 2-element vector of real_ts
00278 typedef Vector<2> Vector2;
00279 
00280 ///@name Extra operators where Vector is on right-hand side
00281 //@{---------------------------------------------------------------------
00282 
00283 /// @returns the N-length vector resulting from multiplying a scalar by an 
00284 ///    N-length vector
00285 template <unsigned N, typename T>
00286    inline Vector<N, T> operator* (const real_t &scale, const Vector<N, T> &v);
00287 
00288 /// @returns (-1) * rhs, which is a negated version of the original right 
00289 ///    hand side vector
00290 template <unsigned N, typename T>
00291    inline Vector<N, T> operator- (const Vector<N, T> &rhs);
00292 
00293 /// Prints a Vector to an output stream
00294 template <unsigned N, typename T>
00295    inline std::ostream     &operator<<(std::ostream &os, const Vector<N, T> &v);
00296 
00297 //@}---------------------------------------------------------------------
00298 
00299 /// converts the vector defined by the given spherical coordinates around 
00300 /// the canonical up vector (0, 1, 0) to be centered around the given up 
00301 /// vector N
00302 inline Vector3 convertHemisphere(const real_t theta, const real_t phi, 
00303                                  const Vector3 &N);
00304 
00305 /// converts the vector w centered around the canonical up vector (0, 1, 0) 
00306 /// to be centered around the given up vector N
00307 inline Vector3 convertHemisphere(const Vector3 &w, const Vector3 &normal);
00308 
00309 #if MILTON_ENABLE_SSE
00310 #  include <common/math/simd/Vector3SSE.h>
00311 #else
00312 #  include <common/math/sisd/Vector3.h>
00313 #endif
00314 
00315 /* Include inline implementations */
00316 #include "common/math/Vector.inl"
00317 
00318 #endif // VECTOR_H_
00319 

Generated on 28 Feb 2009 for Milton by doxygen 1.5.6