Vector2.h

Go to the documentation of this file.
00001 #ifndef VECTOR2_H_
00002 #define VECTOR2_H_
00003 
00004 /* greebo: This file contains the templated class definition of the three-component vector
00005  *
00006  * BasicVector2: A vector with three components of type <Element>
00007  *
00008  * The BasicVector2 is equipped with the most important operators like *, *= and so on.
00009  *
00010  * Note: The most commonly used Vector2 is a BasicVector2<float>, this is also defined in this file
00011  *
00012  * Note: that the multiplication of a Vector2 with another one (Vector2*Vector2) does NOT
00013  * result in an inner product but in a component-wise scaling. Use the .dot() method to
00014  * execute an inner product of two vectors.
00015  */
00016 
00017 #include "lrint.h"
00018 #include <cmath>
00019 #include <float.h>
00020 #include <sstream>
00021 
00022 template<typename Element>
00023 class BasicVector2
00024 {
00025         // This is where the components of the vector are stored.
00026         Element m_elements[2];
00027 
00028     public:
00029         // Constructor with no arguments
00030         BasicVector2 ()
00031         {
00032         }
00033 
00036         BasicVector2 (const Element& x_, const Element& y_)
00037         {
00038             x() = x_;
00039             y() = y_;
00040         }
00041 
00042         // Return NON-CONSTANT references to the vector components
00043         Element& x ()
00044         {
00045             return m_elements[0];
00046         }
00047         Element& y ()
00048         {
00049             return m_elements[1];
00050         }
00051 
00052         // Return CONSTANT references to the vector components
00053         const Element& x () const
00054         {
00055             return m_elements[0];
00056         }
00057         const Element& y () const
00058         {
00059             return m_elements[1];
00060         }
00061 
00062         Element& operator[] (std::size_t i)
00063         {
00064             return m_elements[i];
00065         }
00066         const Element& operator[] (std::size_t i) const
00067         {
00068             return m_elements[i];
00069         }
00070 
00071         Element* data ()
00072         {
00073             return m_elements;
00074         }
00075         const Element* data () const
00076         {
00077             return m_elements;
00078         }
00079 
00082         bool operator== (const BasicVector2& other) const
00083         {
00084             return (other.x() == x() && other.y() == y());
00085         }
00086 
00089         bool operator!= (const BasicVector2& other) const
00090         {
00091             return !(*this == other);
00092         }
00093 
00094         /*  Define the negation operator -
00095          *  All the vector's components are negated
00096          */
00097         BasicVector2<Element> operator- () const
00098         {
00099             return BasicVector2<Element> (-m_elements[0], -m_elements[1]);
00100         }
00101 
00102         /*  Define the addition operators + and += with any other BasicVector2 of type OtherElement
00103          *  The vectors are added to each other element-wise
00104          */
00105         template<typename OtherElement>
00106         BasicVector2<Element> operator+ (const BasicVector2<OtherElement>& other) const
00107         {
00108             return BasicVector2<Element> (m_elements[0] + static_cast<Element> (other.x()), m_elements[1]
00109                     + static_cast<Element> (other.y()));
00110         }
00111 
00112         template<typename OtherElement>
00113         void operator+= (const BasicVector2<OtherElement>& other)
00114         {
00115             m_elements[0] += static_cast<Element> (other.x());
00116             m_elements[1] += static_cast<Element> (other.y());
00117         }
00118 
00119         /*  Define the substraction operators - and -= with any other BasicVector2 of type OtherElement
00120          *  The vectors are substracted from each other element-wise
00121          */
00122         template<typename OtherElement>
00123         BasicVector2<Element> operator- (const BasicVector2<OtherElement>& other) const
00124         {
00125             return BasicVector2<Element> (m_elements[0] - static_cast<Element> (other.x()), m_elements[1]
00126                     - static_cast<Element> (other.y()));
00127         }
00128 
00129         template<typename OtherElement>
00130         void operator-= (const BasicVector2<OtherElement>& other)
00131         {
00132             m_elements[0] -= static_cast<Element> (other.x());
00133             m_elements[1] -= static_cast<Element> (other.y());
00134         }
00135 
00136         /*  Define the multiplication operators * and *= with another Vector2 of type OtherElement
00137          *
00138          *  The vectors are multiplied element-wise
00139          *
00140          *  greebo: This is mathematically kind of senseless, as this is a mixture of
00141          *  a dot product and scalar multiplication. It can be used to scale each
00142          *  vector component by a different factor, so maybe this comes in handy.
00143          */
00144         template<typename OtherElement>
00145         BasicVector2<Element> operator* (const BasicVector2<OtherElement>& other) const
00146         {
00147             return BasicVector2<Element> (m_elements[0] * static_cast<Element> (other.x()), m_elements[1]
00148                     * static_cast<Element> (other.y()));
00149         }
00150 
00151         template<typename OtherElement>
00152         void operator*= (const BasicVector2<OtherElement>& other)
00153         {
00154             m_elements[0] *= static_cast<Element> (other.x());
00155             m_elements[1] *= static_cast<Element> (other.y());
00156         }
00157 
00158         /*  Define the multiplications * and *= with a scalar
00159          */
00160         template<typename OtherElement>
00161         BasicVector2<Element> operator* (const OtherElement& other) const
00162         {
00163             Element factor = static_cast<Element> (other);
00164             return BasicVector2<Element> (m_elements[0] * factor, m_elements[1] * factor);
00165         }
00166 
00167         template<typename OtherElement>
00168         void operator*= (const OtherElement& other)
00169         {
00170             Element factor = static_cast<Element> (other);
00171             m_elements[0] *= factor;
00172             m_elements[1] *= factor;
00173         }
00174 
00175         /*  Define the division operators / and /= with another Vector2 of type OtherElement
00176          *  The vectors are divided element-wise
00177          */
00178         template<typename OtherElement>
00179         BasicVector2<Element> operator/ (const BasicVector2<OtherElement>& other) const
00180         {
00181             return BasicVector2<Element> (m_elements[0] / static_cast<Element> (other.x()), m_elements[1]
00182                     / static_cast<Element> (other.y()));
00183         }
00184 
00185         template<typename OtherElement>
00186         void operator/= (const BasicVector2<OtherElement>& other)
00187         {
00188             m_elements[0] /= static_cast<Element> (other.x());
00189             m_elements[1] /= static_cast<Element> (other.y());
00190         }
00191 
00192         /*  Define the scalar divisions / and /=
00193          */
00194         template<typename OtherElement>
00195         BasicVector2<Element> operator/ (const OtherElement& other) const
00196         {
00197             Element divisor = static_cast<Element> (other);
00198             return BasicVector2<Element> (m_elements[0] / divisor, m_elements[1] / divisor);
00199         }
00200 
00201         template<typename OtherElement>
00202         void operator/= (const OtherElement& other)
00203         {
00204             Element divisor = static_cast<Element> (other);
00205             m_elements[0] /= divisor;
00206             m_elements[1] /= divisor;
00207         }
00208 
00214         double getLength () const
00215         {
00216             double lenSquared = m_elements[0] * m_elements[0] + m_elements[1] * m_elements[1];
00217             return sqrt(lenSquared);
00218         }
00219 
00222         double getLengthSquared () const
00223         {
00224             double lenSquared = m_elements[0] * m_elements[0] + m_elements[1] * m_elements[1];
00225             return lenSquared;
00226         }
00227 
00228         /* Scalar product this vector with another Vector2,
00229          * returning the projection of <self> onto <other>
00230          *
00231          * @param other
00232          * The Vector2 to dot-product with this Vector2.
00233          *
00234          * @returns
00235          * The inner product (a scalar): a[0]*b[0] + a[1]*b[1]
00236          */
00237         template<typename OtherT>
00238         Element dot (const BasicVector2<OtherT>& other) const
00239         {
00240             return Element(m_elements[0] * other.x() + m_elements[1] * other.y());
00241         }
00242 
00243         /* Cross-product this vector with another Vector2, returning the scalar result
00244          *
00245          * @param other
00246          * The Vector2 to cross-product with this Vector2.
00247          *
00248          * @returns
00249          * The cross-product of the two vectors, a scalar: a[0]*b[1] - b[0]*a[1]
00250          */
00251         template<typename OtherT>
00252         Element crossProduct (const BasicVector2<OtherT>& other) const
00253         {
00254             return Element(m_elements[0] * other.y() - m_elements[1] * other.x());
00255         }
00256 
00260         std::string toString () const
00261         {
00262             std::stringstream ss;
00263             ss << m_elements[0] << " " << m_elements[1];
00264             return ss.str();
00265         }
00266 };
00267 
00268 // ==========================================================================================
00269 
00270 // A 2-element vector stored in single-precision floating-point.
00271 typedef BasicVector2<float> Vector2;
00272 
00273 #endif /*VECTOR2_H_*/

Generated by  doxygen 1.6.2