Vector3.h

Go to the documentation of this file.
00001 #ifndef VECTOR3_H_
00002 #define VECTOR3_H_
00003 
00004 /* greebo: This file contains the templated class definition of the three-component vector
00005  *
00006  * BasicVector3: A vector with three components of type <Element>
00007  *
00008  * The BasicVector3 is equipped with the most important operators like *, *= and so on.
00009  *
00010  * Note: The most commonly used Vector3 is a BasicVector3<float>, this is also defined in this file
00011  *
00012  * Note: that the multiplication of a Vector3 with another one (Vector3*Vector3) 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 <sstream>
00019 #include <string>
00020 #include <cmath>
00021 #include <float.h>
00022 
00023 // BasicVector3: A 3-element vector of type Element
00024 template<typename Element>
00025 class BasicVector3
00026 {
00027 
00028         // The actual values of the vector, an array containing 3 values of type Element
00029         Element m_elements[3];
00030 
00031     public:
00032 
00033         // Constructor with no argument
00034         BasicVector3 ()
00035         {
00036         }
00037 
00038         // Templated copy constructor
00039         template<typename OtherElement>
00040         BasicVector3 (const BasicVector3<OtherElement>& other)
00041         {
00042             x() = static_cast<Element> (other.x());
00043             y() = static_cast<Element> (other.y());
00044             z() = static_cast<Element> (other.z());
00045         }
00046 
00049         BasicVector3 (const Element& x_, const Element& y_, const Element& z_)
00050         {
00051             x() = x_;
00052             y() = y_;
00053             z() = z_;
00054         }
00055 
00059         BasicVector3 (const Element* array)
00060         {
00061             for (int i = 0; i < 3; ++i)
00062                 m_elements[i] = array[i];
00063         }
00064 
00072         BasicVector3 (const std::string& str)
00073         {
00074             // Initialise the vector with 0, in case the string parse fails
00075             m_elements[0] = m_elements[1] = m_elements[2] = 0;
00076             // Use a stringstream to parse the string
00077             std::stringstream strm(str);
00078             strm << std::skipws;
00079             strm >> x();
00080             strm >> y();
00081             strm >> z();
00082         }
00083 
00086         void set (const Element& x, const Element& y, const Element& z)
00087         {
00088             m_elements[0] = x;
00089             m_elements[1] = y;
00090             m_elements[2] = z;
00091         }
00092 
00093         // Return NON-CONSTANT references to the vector components
00094         Element& x ()
00095         {
00096             return m_elements[0];
00097         }
00098         Element& y ()
00099         {
00100             return m_elements[1];
00101         }
00102         Element& z ()
00103         {
00104             return m_elements[2];
00105         }
00106 
00107         // Return CONSTANT references to the vector components
00108         const Element& x () const
00109         {
00110             return m_elements[0];
00111         }
00112         const Element& y () const
00113         {
00114             return m_elements[1];
00115         }
00116         const Element& z () const
00117         {
00118             return m_elements[2];
00119         }
00120 
00123         bool operator== (const BasicVector3& other) const
00124         {
00125             return (other.x() == x() && other.y() == y() && other.z() == z());
00126         }
00127 
00130         bool operator!= (const BasicVector3& other) const
00131         {
00132             return !(*this == other);
00133         }
00134 
00135         /*  Define the negation operator -
00136          *  All the vector's components are negated
00137          */
00138         BasicVector3<Element> operator- () const
00139         {
00140             return BasicVector3<Element> (-m_elements[0], -m_elements[1], -m_elements[2]);
00141         }
00142 
00143         /*  Define the addition operators + and += with any other BasicVector3 of type OtherElement
00144          *  The vectors are added to each other element-wise
00145          */
00146         template<typename OtherElement>
00147         BasicVector3<Element> operator+ (const BasicVector3<OtherElement>& other) const
00148         {
00149             return BasicVector3<Element> (m_elements[0] + static_cast<Element> (other.x()), m_elements[1]
00150                     + static_cast<Element> (other.y()), m_elements[2] + static_cast<Element> (other.z()));
00151         }
00152 
00153         template<typename OtherElement>
00154         void operator+= (const BasicVector3<OtherElement>& other)
00155         {
00156             m_elements[0] += static_cast<Element> (other.x());
00157             m_elements[1] += static_cast<Element> (other.y());
00158             m_elements[2] += static_cast<Element> (other.z());
00159         }
00160 
00161         /*  Define the substraction operators - and -= with any other BasicVector3 of type OtherElement
00162          *  The vectors are substracted from each other element-wise
00163          */
00164         template<typename OtherElement>
00165         BasicVector3<Element> operator- (const BasicVector3<OtherElement>& other) const
00166         {
00167             return BasicVector3<Element> (m_elements[0] - static_cast<Element> (other.x()), m_elements[1]
00168                     - static_cast<Element> (other.y()), m_elements[2] - static_cast<Element> (other.z()));
00169         }
00170 
00171         template<typename OtherElement>
00172         void operator-= (const BasicVector3<OtherElement>& other)
00173         {
00174             m_elements[0] -= static_cast<Element> (other.x());
00175             m_elements[1] -= static_cast<Element> (other.y());
00176             m_elements[2] -= static_cast<Element> (other.z());
00177         }
00178 
00179         /*  Define the multiplication operators * and *= with another Vector3 of type OtherElement
00180          *
00181          *  The vectors are multiplied element-wise
00182          *
00183          *  greebo: This is mathematically kind of senseless, as this is a mixture of
00184          *  a dot product and scalar multiplication. It can be used to scale each
00185          *  vector component by a different factor, so maybe this comes in handy.
00186          */
00187         template<typename OtherElement>
00188         BasicVector3<Element> operator* (const BasicVector3<OtherElement>& other) const
00189         {
00190             return BasicVector3<Element> (m_elements[0] * static_cast<Element> (other.x()), m_elements[1]
00191                     * static_cast<Element> (other.y()), m_elements[2] * static_cast<Element> (other.z()));
00192         }
00193 
00194         template<typename OtherElement>
00195         void operator*= (const BasicVector3<OtherElement>& other)
00196         {
00197             m_elements[0] *= static_cast<Element> (other.x());
00198             m_elements[1] *= static_cast<Element> (other.y());
00199             m_elements[2] *= static_cast<Element> (other.z());
00200         }
00201 
00202         /*  Define the multiplications * and *= with a scalar
00203          */
00204         template<typename OtherElement>
00205         BasicVector3<Element> operator* (const OtherElement& other) const
00206         {
00207             Element factor = static_cast<Element> (other);
00208             return BasicVector3<Element> (m_elements[0] * factor, m_elements[1] * factor, m_elements[2] * factor);
00209         }
00210 
00211         template<typename OtherElement>
00212         void operator*= (const OtherElement& other)
00213         {
00214             Element factor = static_cast<Element> (other);
00215             m_elements[0] *= factor;
00216             m_elements[1] *= factor;
00217             m_elements[2] *= factor;
00218         }
00219 
00220         /*  Define the division operators / and /= with another Vector3 of type OtherElement
00221          *  The vectors are divided element-wise
00222          */
00223         template<typename OtherElement>
00224         BasicVector3<Element> operator/ (const BasicVector3<OtherElement>& other) const
00225         {
00226             return BasicVector3<Element> (m_elements[0] / static_cast<Element> (other.x()), m_elements[1]
00227                     / static_cast<Element> (other.y()), m_elements[2] / static_cast<Element> (other.z()));
00228         }
00229 
00230         template<typename OtherElement>
00231         void operator/= (const BasicVector3<OtherElement>& other)
00232         {
00233             m_elements[0] /= static_cast<Element> (other.x());
00234             m_elements[1] /= static_cast<Element> (other.y());
00235             m_elements[2] /= static_cast<Element> (other.z());
00236         }
00237 
00238         /*  Define the scalar divisions / and /=
00239          */
00240         template<typename OtherElement>
00241         BasicVector3<Element> operator/ (const OtherElement& other) const
00242         {
00243             Element divisor = static_cast<Element> (other);
00244             return BasicVector3<Element> (m_elements[0] / divisor, m_elements[1] / divisor, m_elements[2] / divisor);
00245         }
00246 
00247         template<typename OtherElement>
00248         void operator/= (const OtherElement& other)
00249         {
00250             Element divisor = static_cast<Element> (other);
00251             m_elements[0] /= divisor;
00252             m_elements[1] /= divisor;
00253             m_elements[2] /= divisor;
00254         }
00255 
00256         /*
00257          * Mathematical operations on the BasicVector3
00258          */
00259 
00265         double getLength () const
00266         {
00267             double lenSquared = m_elements[0] * m_elements[0] + m_elements[1] * m_elements[1] + m_elements[2]
00268                     * m_elements[2];
00269             return sqrt(lenSquared);
00270         }
00271 
00274         double getLengthSquared () const
00275         {
00276             double lenSquared = m_elements[0] * m_elements[0] + m_elements[1] * m_elements[1] + m_elements[2]
00277                     * m_elements[2];
00278             return lenSquared;
00279         }
00280 
00281         // Return a new BasicVector3 equivalent to the normalised
00282         // version of this BasicVector3 (scaled by the inverse of its size)
00283         BasicVector3<Element> getNormalised () const
00284         {
00285             return (*this) / getLength();
00286         }
00287 
00288         /* Scalar product this vector with another Vector3,
00289          * returning the projection of <self> onto <other>
00290          *
00291          * @param other
00292          * The Vector3 to dot-product with this Vector3.
00293          *
00294          * @returns
00295          * The inner product (a scalar): a[0]*b[0] + a[1]*b[1] + a[2]*b[2]
00296          */
00297 
00298         template<typename OtherT>
00299         Element dot (const BasicVector3<OtherT>& other) const
00300         {
00301             return Element(m_elements[0] * other.x() + m_elements[1] * other.y() + m_elements[2] * other.z());
00302         }
00303 
00304         /* Cross-product this vector with another Vector3, returning the result
00305          * in a new Vector3.
00306          *
00307          * @param other
00308          * The Vector3 to cross-product with this Vector3.
00309          *
00310          * @returns
00311          * The cross-product of the two vectors.
00312          */
00313 
00314         template<typename OtherT>
00315         BasicVector3<Element> crossProduct (const BasicVector3<OtherT>& other) const
00316         {
00317             return BasicVector3<Element> (m_elements[1] * other.z() - m_elements[2] * other.y(), m_elements[2]
00318                     * other.x() - m_elements[0] * other.z(), m_elements[0] * other.y() - m_elements[1] * other.x());
00319         }
00320 
00324         std::string toString () const
00325         {
00326             std::stringstream ss;
00327             ss << m_elements[0] << " " << m_elements[1] << " " << m_elements[2];
00328             return ss.str();
00329         }
00330 
00337         operator const Element* () const
00338         {
00339             return m_elements;
00340         }
00341 
00342         operator Element* ()
00343         {
00344             return m_elements;
00345         }
00346 
00347 };
00348 
00352 template<typename T>
00353 std::ostream& operator<< (std::ostream& st, BasicVector3<T> vec)
00354 {
00355     st << "<" << vec.x() << ", " << vec.y() << ", " << vec.z() << ">";
00356     return st;
00357 }
00358 
00359 // ==========================================================================================
00360 
00361 // A 3-element vector stored in single-precision floating-point.
00362 typedef BasicVector3<float> Vector3;
00363 
00364 // =============== Common Vector3 Methods ==================================================
00365 
00366 const Vector3 g_vector3_identity(0, 0, 0);
00367 const Vector3 g_vector3_max = Vector3(FLT_MAX, FLT_MAX, FLT_MAX);
00368 const Vector3 g_vector3_axis_x(1, 0, 0);
00369 const Vector3 g_vector3_axis_y(0, 1, 0);
00370 const Vector3 g_vector3_axis_z(0, 0, 1);
00371 
00372 const Vector3 g_vector3_axes[3] = { g_vector3_axis_x, g_vector3_axis_y, g_vector3_axis_z };
00373 
00374 template<typename Element, typename OtherElement>
00375 inline void vector3_swap (BasicVector3<Element>& self, BasicVector3<OtherElement>& other)
00376 {
00377     std::swap(self.x(), other.x());
00378     std::swap(self.y(), other.y());
00379     std::swap(self.z(), other.z());
00380 }
00381 
00382 template<typename Element, typename OtherElement, typename Epsilon>
00383 inline bool vector3_equal_epsilon (const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other,
00384         Epsilon epsilon)
00385 {
00386     return float_equal_epsilon(self.x(), other.x(), epsilon) && float_equal_epsilon(self.y(), other.y(), epsilon)
00387             && float_equal_epsilon(self.z(), other.z(), epsilon);
00388 }
00389 
00390 template<typename Element>
00391 inline BasicVector3<Element> vector3_mid (const BasicVector3<Element>& begin, const BasicVector3<Element>& end)
00392 {
00393     return (begin + end) * 0.5;
00394 }
00395 
00396 template<typename Element>
00397 inline Element float_divided (Element f, Element other)
00398 {
00399     return f / other;
00400 }
00401 
00402 template<typename Element>
00403 inline void vector3_normalise (BasicVector3<Element>& self)
00404 {
00405     self = self.getNormalised();
00406 }
00407 
00408 template<typename Element>
00409 inline BasicVector3<Element> vector3_snapped (const BasicVector3<Element>& self)
00410 {
00411     return BasicVector3<Element> (Element(float_to_integer(self.x())), Element(float_to_integer(self.y())), Element(
00412             float_to_integer(self.z())));
00413 }
00414 
00415 template<typename Element>
00416 inline void vector3_snap (BasicVector3<Element>& self)
00417 {
00418     self = vector3_snapped(self);
00419 }
00420 
00421 template<typename Element, typename OtherElement>
00422 inline BasicVector3<Element> vector3_snapped (const BasicVector3<Element>& self, const OtherElement& snap)
00423 {
00424     return BasicVector3<Element> (Element(float_snapped(self.x(), snap)), Element(float_snapped(self.y(), snap)),
00425             Element(float_snapped(self.z(), snap)));
00426 }
00427 template<typename Element, typename OtherElement>
00428 inline void vector3_snap (BasicVector3<Element>& self, const OtherElement& snap)
00429 {
00430     self = vector3_snapped(self, snap);
00431 }
00432 
00433 inline Vector3 vector3_for_spherical (double theta, double phi)
00434 {
00435     return Vector3(static_cast<float> (cos(theta) * cos(phi)), static_cast<float> (sin(theta) * cos(phi)),
00436             static_cast<float> (sin(phi)));
00437 }
00438 
00439 #endif /*VECTOR3_H_*/

Generated by  doxygen 1.6.2