Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics
[Home] [Tutorials] [All Classes] [Grouped Classes]

X:/dropbox/visualizationlibrary/src/vlCore/Vector2.hpp

Go to the documentation of this file.
00001 /**************************************************************************************/
00002 /*                                                                                    */
00003 /*  Visualization Library                                                             */
00004 /*  http://www.visualizationlibrary.org                                               */
00005 /*                                                                                    */
00006 /*  Copyright (c) 2005-2010, Michele Bosi                                             */
00007 /*  All rights reserved.                                                              */
00008 /*                                                                                    */
00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
00010 /*  are permitted provided that the following conditions are met:                     */
00011 /*                                                                                    */
00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
00013 /*  list of conditions and the following disclaimer.                                  */
00014 /*                                                                                    */
00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
00017 /*  other materials provided with the distribution.                                   */
00018 /*                                                                                    */
00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
00020 /*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
00021 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
00022 /*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
00023 /*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
00024 /*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
00025 /*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
00026 /*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
00027 /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
00028 /*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
00029 /*                                                                                    */
00030 /**************************************************************************************/
00031 
00032 #ifndef Vector2_INCLUDE_ONCE
00033 #define Vector2_INCLUDE_ONCE
00034 
00035 #include <vlCore/OpenGLDefs.hpp>
00036 #include <vlCore/std_types.hpp>
00037 #include <cmath>
00038 
00039 #ifdef min
00040 #undef min
00041 #endif
00042 
00043 #ifdef max
00044 #undef max
00045 #endif
00046 
00047 #ifdef dot
00048 #undef dot
00049 #endif
00050 
00051 #ifdef cross
00052 #undef cross
00053 #endif
00054 
00055 namespace vl
00056 {
00057   // fast square root
00058 
00059   #if VL_FAST_SQUARE_ROOTS == 1
00060     #define VL_FLOAT_SQRT(x)    fast_sqrt(x)
00061     #define VL_FLOAT_INVSQRT(x) fast2_inversesqrt(x)
00062   #else
00063     #define VL_FLOAT_SQRT(x)    ((float)::sqrt(x))
00064     #define VL_FLOAT_INVSQRT(x) (1.0f/(float)::sqrt(x))
00065   #endif
00066 
00067   // fast square root functions, see Dave Eberly's paper and http://www.beyond3d.com/content/articles/8/
00068 
00069   inline float fast1_inversesqrt(float x)
00070   {
00071     float xhalf = 0.5f*x;
00072     union { float f; unsigned int i; } num;
00073     num.f = x;
00074     num.i = 0x5f3759df - (num.i>>1);
00075     x = num.f;
00076     x = x*(1.5f - xhalf*x*x); // single iteration, very quick, but very poor precision
00077     return x;
00078   }
00079   inline float fast2_inversesqrt(float x)
00080   {
00081     float xhalf = 0.5f*x;
00082     union { float f; unsigned int i; } num;
00083     num.f = x;
00084     num.i = 0x5f3759df - (num.i>>1);
00085     x = num.f;
00086     x = x*(1.5f - xhalf*x*x);
00087     x = x*(1.5f - xhalf*x*x); // two iterations, sligthtly better precision
00088     return x;
00089   }
00090   inline float fast_sqrt(float x) { if (x == 0.0f) return 0.0f; else return x * fast2_inversesqrt(x); }
00091 
00096   template<typename T_Scalar>
00097   class Vector2
00098   {
00099   public:
00100     typedef T_Scalar scalar_type;
00101     static const int scalar_count = 2;
00102     Vector2(const Vector2& other) { *this = other; }
00103     Vector2() { x() = y() = 0; }
00104 
00105     template<class T>
00106     explicit Vector2(const T& other)
00107     {
00108       x() = (T_Scalar)other.x();
00109       y() = (T_Scalar)other.y();
00110     }
00111 
00112     explicit Vector2(T_Scalar x, T_Scalar y)
00113     {
00114       mScalar[0] = x;
00115       mScalar[1] = y;
00116     }
00117 
00118     T_Scalar* ptr() { return mScalar; }
00119     const T_Scalar* ptr() const { return mScalar; }
00120 
00121     const T_Scalar& x() const { return mScalar[0]; }
00122     const T_Scalar& y() const { return mScalar[1]; }
00123 
00124     T_Scalar& x() { return mScalar[0]; }
00125     T_Scalar& y() { return mScalar[1]; }
00126 
00127     const T_Scalar& r() const { return mScalar[0]; }
00128     const T_Scalar& g() const { return mScalar[1]; }
00129 
00130     T_Scalar& r() { return mScalar[0]; }
00131     T_Scalar& g() { return mScalar[1]; }
00132 
00133     const T_Scalar& s() const { return mScalar[0]; }
00134     const T_Scalar& t() const { return mScalar[1]; }
00135 
00136     T_Scalar& s() { return mScalar[0]; }
00137     T_Scalar& t() { return mScalar[1]; }
00138 
00139     Vector2 operator+(const Vector2& other) const
00140     {
00141       return Vector2(x()+other.x(), y()+other.y());
00142     }
00143     Vector2 operator-(const Vector2& other) const
00144     {
00145       return Vector2(x()-other.x(), y()-other.y());
00146     }
00147     Vector2 operator*(const Vector2& other) const
00148     {
00149       return Vector2(x()*other.x(), y()*other.y());
00150     }
00151     Vector2 operator/(const Vector2& other) const
00152     {
00153       return Vector2(x()/other.x(), y()/other.y());
00154     }
00155     Vector2 operator+(T_Scalar val) const
00156     {
00157       return Vector2(x()+val, y()+val);
00158     }
00159     Vector2 operator-(T_Scalar val) const
00160     {
00161       return Vector2(x()-val, y()-val);
00162     }
00163     Vector2 operator*(T_Scalar val) const
00164     {
00165       return Vector2(x()*val, y()*val);
00166     }
00167     Vector2 operator/(T_Scalar val) const
00168     {
00169       return Vector2(x()/val, y()/val);
00170     }
00171     Vector2 operator-() const
00172     {
00173       return Vector2(-x(), -y());
00174     }
00175     Vector2& operator+=(const Vector2& other)
00176     {
00177       *this = *this + other;
00178       return *this;
00179     }
00180     Vector2& operator-=(const Vector2& other)
00181     {
00182       *this = *this - other;
00183       return *this;
00184     }
00185     Vector2& operator*=(const Vector2& other)
00186     {
00187       *this = *this * other;
00188       return *this;
00189     }
00190     Vector2& operator/=(const Vector2& other)
00191     {
00192       *this = *this / other;
00193       return *this;
00194     }
00195     Vector2& operator+=(T_Scalar val)
00196     {
00197       *this = *this + val;
00198       return *this;
00199     }
00200     Vector2& operator-=(T_Scalar val)
00201     {
00202       *this = *this - val;
00203       return *this;
00204     }
00205     Vector2& operator*=(T_Scalar val)
00206     {
00207       *this = *this * val;
00208       return *this;
00209     }
00210     Vector2& operator/=(T_Scalar val)
00211     {
00212       *this = *this / val;
00213       return *this;
00214     }
00215     Vector2& operator=(const Vector2& other)
00216     {
00217       x() = other.x();
00218       y() = other.y();
00219       return *this;
00220     }
00221     Vector2& operator=(T_Scalar val)
00222     {
00223       x() = y() = val;
00224       return *this;
00225     }
00226     bool operator==(const Vector2& other) const
00227     {
00228       return x() == other.x() && y() == other.y();
00229     }
00230     bool operator!=(const Vector2& other) const
00231     {
00232       return !operator==(other);
00233     }
00234     bool operator<(const Vector2& other) const
00235     {
00236       if (x() != other.x())
00237         return x() < other.x();
00238       else
00239         return y() < other.y();
00240     }
00241     T_Scalar& operator[](unsigned i) { return mScalar[i]; }
00242     const T_Scalar& operator[](unsigned i) const { return mScalar[i]; }
00243     T_Scalar length() const { return ::sqrt(x()*x()+y()*y()); }
00244     T_Scalar lengthSquared() const { return x()*x()+y()*y(); }
00245     bool isNull() const { return !x() && !y(); }
00246     const Vector2& normalize(T_Scalar *len=NULL)
00247     {
00248       T_Scalar l = length();
00249       if (len)
00250         *len = l;
00251       if (l)
00252         *this *= (T_Scalar)(1.0/l); 
00253       return *this; 
00254     }
00255 
00256   protected:
00257     T_Scalar mScalar[scalar_count];
00258   };
00259 
00260   template<typename T>
00261   inline const Vector2<T> operator*(T val, const Vector2<T>& v)
00262   {
00263     return v * val;
00264   }
00265 
00267   typedef Vector2<int> ivec2;
00269   typedef Vector2<unsigned int> uvec2;
00271   typedef Vector2<float> fvec2;
00273   typedef Vector2<double> dvec2;
00275   typedef Vector2<char> bvec2;
00277   typedef Vector2<unsigned char> ubvec2;
00279   typedef Vector2<short> svec2;
00281   typedef Vector2<unsigned short> usvec2;
00282 
00283   #if VL_PIPELINE_PRECISION == 2
00284 
00285     typedef dvec2 vec2;
00286   #else
00287 
00288     typedef fvec2 vec2;
00289   #endif
00290 
00291   inline float dot(const fvec2& v1, const fvec2& v2) { return v1.x()*v2.x() + v1.y()*v2.y(); }
00292   inline double dot(const dvec2& v1, const dvec2& v2) { return v1.x()*v2.x() + v1.y()*v2.y(); }
00293   inline float dot(const ivec2& v1, const ivec2& v2) { return (float)(v1.x()*v2.x() + v1.y()*v2.y()); }
00294   inline float dot(const uvec2& v1, const uvec2& v2) { return (float)(v1.x()*v2.x() + v1.y()*v2.y()); }
00295 
00296   inline float min(float a, float b) { return a < b ? a : b; }
00297   inline double min(double a, double b) { return a < b ? a : b; }
00298   inline int min(int a, int b) { return a < b ? a : b; }
00299   inline unsigned int min(unsigned int a, unsigned int b) { return a < b ? a : b; }
00300   inline float max(float a, float b) { return a > b ? a : b; }
00301   inline double max(double a, double b) { return a > b ? a : b; }
00302   inline int max(int a, int b) { return a > b ? a : b; }
00303   inline unsigned int max(unsigned int a, unsigned int b) { return a > b ? a : b; }
00304   inline float clamp(float x, float minval, float maxval) { return min(max(x,minval),maxval); }
00305   inline double clamp(double x, double minval, double maxval) { return min(max(x,minval),maxval); }
00306   inline int clamp(int x, int minval, int maxval) { return min(max(x,minval),maxval); }
00307   inline unsigned int clamp(unsigned int x, unsigned int minval, unsigned int maxval) { return min(max(x,minval),maxval); }
00308 
00309   inline fvec2 min(const fvec2& a, const fvec2& b)
00310   {
00311     return fvec2( a.x() < b.x() ? a.x() : b.x(),
00312       a.y() < b.y() ? a.y() : b.y());
00313   }
00314   inline fvec2 min(const fvec2& a, float b)
00315   {
00316     return fvec2( a.x() < b ? a.x() : b,
00317       a.y() < b ? a.y() : b);
00318   }
00319   inline dvec2 min(const dvec2& a, const dvec2& b)
00320   {
00321     return dvec2( a.x() < b.x() ? a.x() : b.x(),
00322       a.y() < b.y() ? a.y() : b.y());
00323   }
00324   inline dvec2 min(const dvec2& a, double b)
00325   {
00326     return dvec2( a.x() < b ? a.x() : b,
00327       a.y() < b ? a.y() : b);
00328   }
00329   inline ivec2 min(const ivec2& a, const ivec2& b)
00330   {
00331     return ivec2( a.x() < b.x() ? a.x() : b.x(),
00332       a.y() < b.y() ? a.y() : b.y());
00333   }
00334   inline ivec2 min(const ivec2& a, int b)
00335   {
00336     return ivec2( a.x() < b ? a.x() : b,
00337       a.y() < b ? a.y() : b);
00338   }
00339   inline uvec2 min(const uvec2& a, const uvec2& b)
00340   {
00341     return uvec2( a.x() < b.x() ? a.x() : b.x(),
00342       a.y() < b.y() ? a.y() : b.y());
00343   }
00344   inline uvec2 min(const uvec2& a, unsigned int b)
00345   {
00346     return uvec2( a.x() < b ? a.x() : b,
00347       a.y() < b ? a.y() : b);
00348   }
00349   inline fvec2 max(const fvec2& a, const fvec2& b)
00350   {
00351     return fvec2( a.x() > b.x() ? a.x() : b.x(),
00352       a.y() > b.y() ? a.y() : b.y());
00353   }
00354   inline fvec2 max(const fvec2& a, float b)
00355   {
00356     return fvec2( a.x() > b ? a.x() : b,
00357       a.y() > b ? a.y() : b);
00358   }
00359   inline dvec2 max(const dvec2& a, const dvec2& b)
00360   {
00361     return dvec2( a.x() > b.x() ? a.x() : b.x(),
00362       a.y() > b.y() ? a.y() : b.y());
00363   }
00364   inline dvec2 max(const dvec2& a, double b)
00365   {
00366     return dvec2( a.x() > b ? a.x() : b,
00367       a.y() > b ? a.y() : b);
00368   }
00369   inline ivec2 max(const ivec2& a, const ivec2& b)
00370   {
00371     return ivec2( a.x() > b.x() ? a.x() : b.x(),
00372       a.y() > b.y() ? a.y() : b.y());
00373   }
00374   inline ivec2 max(const ivec2& a, int b)
00375   {
00376     return ivec2( a.x() > b ? a.x() : b,
00377       a.y() > b ? a.y() : b);
00378   }
00379   inline uvec2 max(const uvec2& a, const uvec2& b)
00380   {
00381     return uvec2( a.x() > b.x() ? a.x() : b.x(),
00382       a.y() > b.y() ? a.y() : b.y());
00383   }
00384   inline uvec2 max(const uvec2& a, unsigned int b)
00385   {
00386     return uvec2( a.x() > b ? a.x() : b,
00387       a.y() > b ? a.y() : b);
00388   }
00389   inline fvec2 clamp(const fvec2& x, float minval, float maxval) { return min(max(x,minval),maxval); }
00390   inline fvec2 clamp(const fvec2& x, const fvec2& minval, const fvec2& maxval) { return min(max(x,minval),maxval); }
00391   inline dvec2 clamp(const dvec2& x, double minval, double maxval) { return min(max(x,minval),maxval); }
00392   inline dvec2 clamp(const dvec2& x, const dvec2& minval, const dvec2& maxval) { return min(max(x,minval),maxval); }
00393   inline ivec2 clamp(const ivec2& x, int minval, int maxval) { return min(max(x,minval),maxval); }
00394   inline ivec2 clamp(const ivec2& x, const ivec2& minval, const ivec2& maxval) { return min(max(x,minval),maxval); }
00395   inline uvec2 clamp(const uvec2& x, unsigned int minval, unsigned int maxval) { return min(max(x,minval),maxval); }
00396   inline uvec2 clamp(const uvec2& x, const uvec2& minval, const uvec2& maxval) { return min(max(x,minval),maxval); }
00397 }
00398 
00399 #endif

Visualization Library 2011.09.1160 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 2 2013 13:40:32.
Permission is granted to use this page to write and publish articles regarding Visualization Library.