GLProgramming.com

home :: about :: development guides :: irc :: forums :: search :: paste :: links :: contribute :: code dump

-> Click here to learn how to get live help <-


New Paste :: Recent Pastes:: No Line Numbers


vector by baldurk
1
 
#ifndef VECTOR_H
#define VECTOR_H

#include "general.h"
#include "debug.h"

/*!
 * \file   vec.h
 * \author  <baldurk>
 * \date   Fri Dec 30 21:46:59 2005
 *
 * \brief  Details of the Vector class
 */

/*! 
 * \brief a templated Vector class
 *
 * This class is a vector templated to work for chars, floats.
 * It supports 1 to 4 dimensional vectors. However for 1 and 2
 * dimensional vectors the other dimensions are 0. w is always 1.
 * Scaling (multiplying/dividing by a constant) as well as rotation,
 * multiplication/addition of vector signore w. normalisation will
 * also make sure w is 1.
 *
 * \todo add the dimension into the template.
 */

template <class T> class Vector
{
  public:
    //! default constructor. Initialises to (0, 0, 0, 1)
    Vector()                   : x(0), y(0), z(0), w(1) {}
    //! constructor. Initialises to (x, 0, 0, 1)
    Vector(T X)                : x(X), y(0), z(0), w(1) {}
    //! constructor. Initialises to (x, y, 0, 1)
    Vector(T X, T Y)           : x(X), y(Y), z(0), w(1) {}
    //! constructor. Initialises to (x, y, z, 1)
    Vector(T X, T Y, T Z)      : x(X), y(Y), z(Z), w(1) {}
    //! constructor. Initialises to (x, y, z, w)
    Vector(T X, T Y, T Z, T W) : x(X), y(Y), z(Z), w(W) {}

    //! normalises the vector, and scales it so that w is 1
    inline Vector normalise()
    {FUNC("vec::normalise"); *this /= w; w = 1; *this /= length();ENDRETURN(*this);}
    //! returns the length of the vector
    inline float length()
    {FUNC("vec::length");ENDRETURN(sqrtf(sqrlength())); }
    /*! 
      \brief Returns the square of the length.

      This is a lot faster to calculate than the real length,
      and if all you're doing is comparing one length with another,
      if the square of X is greater than the square of Y then X > Y.
    */
    inline float sqrlength()
    {FUNC("vec::sqrlength"); ENDRETURN(x*x + y*y + z*z); }
    /*! 
     * returns the dot product of this vector and another
     *
     * \param other the other vector
     */
    inline float dotProduct(const Vector other) const
    {FUNC("vec:dot"); ENDRETURN(x * other.x + y * other.y + z * other.z); }
    /*! 
     * returns the cross product of this vector and another
     *
     * \param other the other vector
     */
    inline Vector crossProduct(const Vector other) const
    {
    FUNC("vec::cross");
    ENDRETURN(Vector(y * other.z - z * other.y,
             z * other.x - x * other.z,
             x * other.y - y * other.x));
    }
    //! equality operator
    bool operator == (const Vector vec) const
    {
    FUNC("vec::==");
    if(vec.x == x && vec.y == y && vec.z == z && vec.w == w)
        ENDRETURN(true);
    ENDRETURN(false);
    }
    //! inequality operator
    bool operator != (const Vector vec) const
    {
    FUNC("vec::!=");
    if(vec.x == x && vec.y == y && vec.z == z && vec.w == w)
        ENDRETURN(false);
    ENDRETURN(true);
    }
    //! assignment operator
    Vector operator = (const Vector vec)
    {
    FUNC("vec::=");
    x = vec.x;y = vec.y;z = vec.z;w = vec.w;
    ENDRETURN(*this);
    }

    //! casting to an array
    operator T*() const
    {
    FUNC("vec::T*");
    static T array[4];
    array[0] = x;
    array[1] = y;
    array[2] = z;
    array[3] = w;
    ENDRETURN(array);
    }
    Vector operator * (const Vector vec) const
    {FUNC("vec::*v");ENDRETURN(Vector(x * vec.x, y * vec.y, z * vec.z, w));}
    Vector operator * (const T f) const
    { FUNC("vec::*f"); ENDRETURN(*this * Vector(f, f, f, 1)); }

    Vector operator / (const Vector vec) const
    {FUNC("vec::/v");ENDRETURN(Vector(x / vec.x, y / vec.y, z / vec.z, w));}

    Vector operator / (const T f) const
    { FUNC("vec::/f"); ENDRETURN(*this / Vector(f, f, f, 1)); }

    Vector operator + (const Vector vec) const
    { FUNC("vec::+v");ENDRETURN(Vector(x + vec.x, y + vec.y, z + vec.z, w));}

    Vector operator + (const T f) const
    { FUNC("vec::+f");ENDRETURN(*this + Vector(f, f, f, 0)); }

    Vector operator - (const Vector vec) const
    { FUNC("vec::-v");ENDRETURN(Vector(x - vec.x, y - vec.y, z - vec.z, w));}

    Vector operator - (const T f) const
    { FUNC("vec::-f");ENDRETURN(*this - Vector(f, f, f, 0)); }

    Vector operator -() const
    { FUNC("vec::-");ENDRETURN(Vector(-x, -y, -z, w)); }

    Vector operator -=(const Vector vec)
    { FUNC("vec::-=v"); ENDRETURN(*this = *this - vec); }
    Vector operator -=(const T f)
    { FUNC("vec::-=f"); ENDRETURN(*this = *this - f); }

    Vector operator +=(const Vector vec)
    { FUNC("vec::+=v"); ENDRETURN(*this = *this + vec); }
    Vector operator +=(const T f)
    { FUNC("vec::+=f"); ENDRETURN(*this = *this + f); }

    Vector operator *=(const Vector vec)
    { FUNC("vec::*=v"); ENDRETURN(*this = *this * vec); }
    Vector operator *=(const T f)
    { FUNC("vec::*=f"); ENDRETURN(*this = *this * f); }

    Vector operator /=(const Vector vec)
    { FUNC("vec::/=v"); ENDRETURN(*this = *this / vec); }
    Vector operator /=(const T f)
    { FUNC("vec::/=f"); ENDRETURN(*this = *this / f); }

    //! operator to perform the dot product
    float operator ^(const Vector other) const
    { FUNC("vec::^");ENDRETURN(dotProduct(other)); }

    //! operator to perform the cross product
    Vector operator |(const Vector other) const
    { FUNC("vec::|");ENDRETURN(crossProduct(other)); }

    T x, y, z, w;
};

template <class T> ostream &operator <<(ostream &o, Vector <T> v)
{
    FUNC("vec::<<");
    ENDRETURN(o << "(" << v.x << ", " << v.y << ", " << v.z << ", " << v.w << ")");
}

typedef Vector<float> Vectorf;
typedef Vector<int> Vectori;

#endif