Visualization Library v1.0.3A lightweight C++ OpenGL middleware for 2D/3D graphics |
[Download] [Tutorials] [All Classes] [Grouped Classes] |
00001 /**************************************************************************************/ 00002 /* */ 00003 /* Visualization Library */ 00004 /* http://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