// ============================================================== // This file is part of Glest Shared Library (www.glest.org) // // Copyright (C) 2001-2008 MartiƱo Figueroa // // You can redistribute this code and/or modify it under // the terms of the GNU General Public License as published // by the Free Software Foundation; either version 2 of the // License, or (at your option) any later version // ============================================================== #ifndef _SHARED_GRAPHICS_MATHUTIL_H_ #define _SHARED_GRAPHICS_MATHUTIL_H_ #include "math_wrapper.h" #include "vec.h" #include "data_types.h" #include "leak_dumper.h" using namespace std; using namespace Shared::Platform; namespace Shared{ namespace Graphics{ const float pi= 3.1415926f; const float sqrt2= 1.41421356f; const float zero= 1e-6f; const float infinity= 1e6f; // ===================================================== // class Rect // ===================================================== // 0 +-+ // | | // +-+ 1 template class Rect2{ public: Vec2 p[2]; public: Rect2(){ }; Rect2(const Vec2 &p0, const Vec2 &p1){ this->p[0]= p0; this->p[1]= p1; } Rect2(T p0x, T p0y, T p1x, T p1y){ p[0].x= p0x; p[0].y= p0y; p[1].x= p1x; p[1].y= p1y; } Rect2 operator*(T scalar){ return Rect2( p[0]*scalar, p[1]*scalar); } Rect2 operator/(T scalar){ return Rect2( p[0]/scalar, p[1]/scalar); } bool isInside(const Vec2 &p) const{ return p.x>=this->p[0].x && p.y>=this->p[0].y && p.xp[1].x && p.yp[1].y; } void clamp(T minX, T minY,T maxX, T maxY){ for(int i=0; i<2; ++i){ if(p[i].xmaxX){ p[i].x= maxX; } if(p[i].y>maxY){ p[i].y= maxY; } } } std::string getString() const { std::ostringstream streamOut; streamOut << "#1: " << this->p[0].getString(); streamOut << "#2: " << this->p[1].getString(); std::string result = streamOut.str(); streamOut.str(std::string()); return result; } }; typedef Rect2 Rect2i; typedef Rect2 Rect2c; typedef Rect2 Rect2f; typedef Rect2 Rect2d; // ===================================================== // class Quad // ===================================================== // 0 +-+ 2 // | | // 1 +-+ 3 template class Quad2{ public: Vec2 p[4]; public: Quad2(){ }; Quad2(const Vec2 &p0, const Vec2 &p1, const Vec2 &p2, const Vec2 &p3){ this->p[0]= p0; this->p[1]= p1; this->p[2]= p2; this->p[3]= p3; } explicit Quad2(const Rect2 &rect){ this->p[0]= rect.p[0]; this->p[1]= Vec2(rect.p[0].x, rect.p[1].y); this->p[2]= rect.p[1]; this->p[3]= Vec2(rect.p[1].x, rect.p[0].y); } Quad2 operator*(T scalar){ return Quad2( p[0]*scalar, p[1]*scalar, p[2]*scalar, p[3]*scalar); } Quad2 operator/(T scalar){ return Quad2( p[0]/scalar, p[1]/scalar, p[2]/scalar, p[3]/scalar); } bool operator <(const Quad2 &v) const { if(p[0] < v.p[0]) { return true; } if(p[1] < v.p[1]) { return true; } if(p[2] < v.p[2]) { return true; } if(p[3] < v.p[3]) { return true; } return false; } bool operator !=(const Quad2 &v) const { if(p[0] != v.p[0]) { return true; } if(p[1] != v.p[1]) { return true; } if(p[2] != v.p[2]) { return true; } if(p[3] != v.p[3]) { return true; } return false; } Rect2 computeBoundingRect() const{ return Rect2i( #ifdef WIN32 min(p[0].x, p[1].x), min(p[0].y, p[2].y), max(p[2].x, p[3].x), max(p[1].y, p[3].y)); #else std::min(p[0].x, p[1].x), std::min(p[0].y, p[2].y), std::max(p[2].x, p[3].x), std::max(p[1].y, p[3].y)); #endif } bool isInside(const Vec2 &pt) const{ if(!computeBoundingRect().isInside(pt)) return false; bool left[4]; left[0]= (pt.y - p[0].y)*(p[1].x - p[0].x) - (pt.x - p[0].x)*(p[1].y - p[0].y) < 0; left[1]= (pt.y - p[1].y)*(p[3].x - p[1].x) - (pt.x - p[1].x)*(p[3].y - p[1].y) < 0; left[2]= (pt.y - p[3].y)*(p[2].x - p[3].x) - (pt.x - p[3].x)*(p[2].y - p[3].y) < 0; left[3]= (pt.y - p[2].y)*(p[0].x - p[2].x) - (pt.x - p[2].x)*(p[0].y - p[2].y) < 0; return left[0] && left[1] && left[2] && left[3]; } void clamp(T minX, T minY, T maxX, T maxY){ for(int i=0; i<4; ++i){ if(p[i].xmaxX){ p[i].x= maxX; } if(p[i].y>maxY){ p[i].y= maxY; } } } float area() { Vec2i v0= p[3]-p[0]; Vec2i v1= p[1]-p[2]; return 0.5f * ((v0.x * v1.y) - (v0.y * v1.x)); } std::string getString() const { std::ostringstream streamOut; streamOut << "#1: " << this->p[0].getString(); streamOut << "#2: " << this->p[1].getString(); streamOut << "#3: " << this->p[2].getString(); streamOut << "#4: " << this->p[3].getString(); std::string result = streamOut.str(); streamOut.str(std::string()); return result; } }; typedef Quad2 Quad2i; typedef Quad2 Quad2c; typedef Quad2 Quad2f; typedef Quad2 Quad2d; // ===================================================== // Misc // ===================================================== inline int next2Power(int n){ int i; for (i=1; i inline T degToRad(T deg){ return (deg*2*pi)/360; } template inline T radToDeg(T rad){ return (rad*360)/(2*pi); } // ==================================================================================================================== // ==================================================================================================================== // Inline implementation // ==================================================================================================================== // ==================================================================================================================== //#if _xs_BigEndian_ // #define _xs_iexp_ 0 // #define _xs_iman_ 1 //#else // #define _xs_iexp_ 1 //intel is little endian // #define _xs_iman_ 0 //#endif //BigEndian_ // ////#define finline __forceinline //#define finline inline // //#ifndef _xs_DEFAULT_CONVERSION //#define _xs_DEFAULT_CONVERSION 0 //#endif // ////typedef long int32; //typedef double real64; //const real64 _xs_doublemagic = real64 (6755399441055744.0); //2^52 * 1.5, uses limited precisicion to floor // //finline int32 xs_CRoundToInt(real64 val, real64 dmr = _xs_doublemagic) { //#if _xs_DEFAULT_CONVERSION==0 // val = val + dmr; // return ((int32*)&val)[_xs_iman_]; // //return 0; //#else // return int32(floor(val+.5)); //#endif //} }}//end namespace #endif