00001 #ifndef H_2D_VECTOR
00002 #define H_2D_VECTOR
00003
00004 #include <cmath>
00005 #include <functional>
00006 #include <vector>
00007 #include <algorithm>
00008 #include <sstream>
00009 #include <xstring.h>
00010
00011 namespace SDLPP {
00012
00013 template<class T>
00014 inline T Min(const T& a, const T& b)
00015 {
00016 return (a<b?a:b);
00017 }
00018
00019 template<class T>
00020 inline T Max(const T& a, const T& b)
00021 {
00022 return (a>b?a:b);
00023 }
00024
00025
00026 template<class T>
00027 struct Vec2
00028 {
00029 typedef Vec2<T> self;
00030
00031 T x,y;
00032
00033 Vec2(const Vec2& v) : x(v.x), y(v.y) {}
00034 Vec2(const T t) : x(t), y(t) {}
00035 Vec2(const T _x=0, const T _y=0) : x(_x), y(_y) {}
00036 Vec2(const T* t) : x(t[0]), y(t[1]) {}
00037
00038 #ifdef _WINDEF_
00039 Vec2(const POINT& p) : x(p.x), y(p.y) {}
00040 operator POINT() const { POINT p = {x, y}; return p; }
00041 #endif
00042
00043 const T& operator[] (const int i) const { return (&x)[i]; }
00044 T& operator[] (const int i) { return (&x)[i]; }
00045
00046 self& operator+=(const self& v) { x += v.x; y += v.y; return *this; }
00047 self& operator-=(const self& v) { x -= v.x; y -= v.y; return *this; }
00048 self& operator*=(const self& v) { x *= v.x; y *= v.y; return *this; }
00049 self& operator*=(const T& s) { x *= s; y *= s; return *this; }
00050 self& operator/=(const self& v) { x /= v.x; y /= v.y; return *this; }
00051 self& operator/=(const T& s) { x /= s; y /= s; return *this; }
00052
00053 const self& operator+() const { return *this; }
00054 self operator-() const { return self(-x, -y); }
00055
00056 T square_magnitude() const { return x*x + y*y; }
00057 double magnitude() const { return sqrt(double(square_magnitude())); }
00058
00059 self normalized() const { return (*this / magnitude()); }
00060 self& normalize() { return *this /= magnitude(); }
00061
00062 static const self Zero() { static self z(0,0); return z; }
00063 };
00064
00065 template<class T>
00066 class Rect2
00067 {
00068 public:
00069 typedef Rect2<T> self;
00070 typedef Vec2<T> point;
00071 Rect2() : tl(-1,-1), br(-2,-2) {}
00072 Rect2(const point& topleft, const point& bottomright) : tl(topleft), br(bottomright) {}
00073 Rect2(const T x0, const T y0, const T x1, const T y1) : tl(x0,y0), br(x1,y1) {}
00074
00075 #ifdef _WINDEF_
00076 Rect2(const RECT& r) : tl(r.left, r.top), br(r.right, r.bottom) {}
00077 RECT toRECT() const { RECT r = {tl.x, tl.y, br.x, br.y}; return r; }
00078 #endif
00079
00080 T get_width() const { return (br.x - tl.x); }
00081 T get_height() const { return (br.y - tl.y); }
00082
00083 point get_size() const { return point(get_width(), get_height()); }
00084
00085 self& operator+=(const point& v) { tl += v; br += v; return *this; }
00086 self& operator-=(const point& v) { tl -= v; br -= v; return *this; }
00087
00088 self& expand(const point& v) { tl-=v; br+=v; return *this; }
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098 self& normalize()
00099 {
00100 if (tl.x>br.x) Swap(tl.x,br.x);
00101 if (tl.y>br.y) Swap(tl.y,br.y);
00102 return *this;
00103 }
00104
00105
00106 self& operator*=(const self&);
00107
00108 bool inside(const point& v) const
00109 {
00110 return (v.x >= tl.x && v.x <= br.x && v.y >= tl.y && v.y <= br.y);
00111 }
00112
00113 bool is_null() const { return tl.x >= br.x || tl.y >= br.y; }
00114 bool is_valid() const { return !is_null(); }
00115
00116 bool contains(int x, int y) const
00117 {
00118 return (tl.x<=x && tl.y<=y && br.x>x && br.y>y);
00119 }
00120
00121 bool contains(const point& pos) const
00122 {
00123 return contains(pos.x,pos.y);
00124 }
00125
00126 self& unite(const Vec2<int>& p)
00127 {
00128 tl.x=Min(tl.x,p.x);
00129 tl.y=Min(tl.y,p.y);
00130 br.x=Max(br.x,p.x+1);
00131 br.y=Max(br.y,p.y+1);
00132 return *this;
00133 }
00134
00135 self& unite(const self& r)
00136 {
00137 tl.x=Min(tl.x,r.tl.x);
00138 tl.y=Min(tl.y,r.tl.y);
00139 br.x=Max(br.x,r.br.x);
00140 br.y=Max(br.y,r.br.y);
00141 return *this;
00142 }
00143
00144 self& intersect(const self& r)
00145 {
00146 tl.x=Max(tl.x,r.tl.x);
00147 tl.y=Max(tl.y,r.tl.y);
00148 br.x=Min(br.x,r.br.x);
00149 br.y=Min(br.y,r.br.y);
00150 return *this;
00151 }
00152
00153 bool overlapping(const self& r) const
00154 {
00155 return (tl.x < r.br.x && tl.y < r.br.y && br.x > r.tl.x && br.y > r.tl.y);
00156 }
00157
00158 self overlap(const self& r) const
00159 {
00160 return self(Maximize(tl,r.tl),Minimize(br,r.br));
00161 }
00162
00163 point tl,br;
00164 };
00165
00166 template<class T>
00167 std::ostream& operator<< (std::ostream& os, const Vec2<T>& v)
00168 {
00169 return os << v.x << ',' << v.y;
00170 }
00171
00172 template<class T>
00173 inline Vec2<T> operator+(const Vec2<T>& u, const Vec2<T>& v)
00174 {
00175 return Vec2<T>(u.x+v.x, u.y+v.y);
00176 }
00177
00178 template<class T>
00179 inline Vec2<T> operator-(const Vec2<T>& u, const Vec2<T>& v)
00180 {
00181 return Vec2<T>(u.x-v.x, u.y-v.y);
00182 }
00183
00184 template<class T>
00185 inline Vec2<T> operator/(const Vec2<T>& u, const Vec2<T>& v)
00186 {
00187 return Vec2<T>(u.x/v.x, u.y/v.y);
00188 }
00189
00190 template<class T>
00191 inline Vec2<T> operator*(const Vec2<T>& v, const T& s)
00192 {
00193 return Vec2<T>(v.x*s, v.y*s);
00194 }
00195
00196 template<class T>
00197 inline Vec2<T> operator*(const int s, const Vec2<T>& v)
00198 {
00199 return Vec2<T>(s*v.x, s*v.y);
00200 }
00201
00202 template<class T>
00203 inline Vec2<T> operator*(const T& s, const Vec2<T>& v)
00204 {
00205 return Vec2<T>((int)(s*v.x), (int)(s*v.y));
00206 }
00207
00208 template<class T>
00209 inline Vec2<T> operator/(const Vec2<T>& v, const T& s)
00210 {
00211 return Vec2<T>(v.x/s, v.y/s);
00212 }
00213
00214 template<class T>
00215 inline bool operator==(const Vec2<T>& u, const Vec2<T>& v)
00216 {
00217 return (u.x == v.x && u.y == v.y);
00218 }
00219
00220 template<class T>
00221 inline bool operator!= (const Vec2<T>& u, const Vec2<T>& v)
00222 {
00223 return (!(u==v));
00224 }
00225
00226 template<class T>
00227 inline bool operator<(const Vec2<T>& u, const Vec2<T>& v)
00228 {
00229 if (u.y==v.y) return u.x<v.x;
00230 return u.y<v.y;
00231 }
00232
00233 template<class T>
00234 inline bool operator<=(const Vec2<T>& u, const Vec2<T>& v)
00235 {
00236 return (u<v || u==v);
00237 }
00238
00239 template<class T>
00240 inline bool operator>(const Vec2<T>& u, const Vec2<T>& v)
00241 {
00242 return (!(u<=v));
00243 }
00244
00245 template<class T>
00246 inline bool operator>=(const Vec2<T>& u, const Vec2<T>& v)
00247 {
00248 return (!(u<v));
00249 }
00250
00251 template<class T>
00252 inline T operator*(const Vec2<T>& u, const Vec2<T>& v)
00253 {
00254 return u.x*v.x + u.y*v.y;
00255 }
00256
00257 template<class T>
00258 inline Vec2<T> Minimize(const Vec2<T>& u, const Vec2<T>& v)
00259 {
00260 return Vec2<T>(Min(u.x,v.x),Min(u.y,v.y));
00261 }
00262
00263 template<class T>
00264 inline Vec2<T> Maximize(const Vec2<T>& u, const Vec2<T>& v)
00265 {
00266 return Vec2<T>(Max(u.x,v.x),Max(u.y,v.y));
00267 }
00268
00269
00270 template<class T>
00271 inline Rect2<T> operator+(const Rect2<T>& r, const Vec2<T>& v)
00272 {
00273 return (Rect2<T>(r.tl + v, r.br + v));
00274 }
00275
00276 template<class T>
00277 inline Rect2<T> operator-(const Rect2<T>& r, const Vec2<T>& v)
00278 {
00279 return (Rect2<T>(r.tl - v, r.br - v));
00280 }
00281
00282 template<class T>
00283 inline bool operator==(const Rect2<T>& q, const Rect2<T>& r)
00284 {
00285 return q.tl == r.tl && q.br == r.br;
00286 }
00287
00288 template<class T>
00289 inline bool operator!=(const Rect2<T>& q, const Rect2<T>& r)
00290 {
00291 return !(q == r);
00292 }
00293
00294 template<class T>
00295 inline Rect2<T> operator*(const Rect2<T>& q, const Rect2<T>& r)
00296 {
00297 Rect2<T> t(Maximize(q.tl, r.tl), Minimize(q.br, r.br));
00298
00299 if (t.tl > t.br)
00300 return Rect2<T>();
00301
00302 return t;
00303 }
00304
00305 template<class T>
00306 inline Rect2<T>& Rect2<T>::operator*=(const Rect2<T>& r)
00307 {
00308 return *this = *this * r;
00309 }
00310
00311 typedef Vec2<int> iVec2;
00312 typedef Vec2<double> dVec2;
00313 typedef Rect2<int> iRect2;
00314
00315 struct convert_char : public std::unary_function<char,char>
00316 {
00317 char m_From;
00318 char m_To;
00319 convert_char(char from, char to) : m_From(from), m_To(to) {}
00320 char operator() (char c) const { return (c==m_From?m_To:c); }
00321 };
00322
00323 inline iRect2 parse_rect(xstring s)
00324 {
00325 std::transform(s.begin(),s.end(),s.begin(),convert_char(',',' '));
00326 std::istringstream is(s);
00327 iRect2 r;
00328 is >> r.tl.x >> r.tl.y >> r.br.x >> r.br.y;
00329 return r;
00330 }
00331
00332 template<class T>
00333 inline std::ostream& operator<< (std::ostream& os, const Rect2<T>& rect)
00334 {
00335 return os << rect.tl.x << ',' << rect.tl.y << ','
00336 << rect.br.x << ',' << rect.br.y;
00337 }
00338
00339 template<class T>
00340 class Array2D
00341 {
00342 typedef std::vector<T> array;
00343 array m_Array;
00344 iVec2 m_Size;
00345 public:
00346 Array2D()
00347 : m_Size(0,0)
00348 {}
00349
00350 Array2D(int width, int height)
00351 : m_Array(width*height),
00352 m_Size(width,height)
00353 {}
00354
00355 Array2D(int width, int height, const T& def)
00356 : m_Array(width*height,def),
00357 m_Size(width,height)
00358 {}
00359
00360 void resize(int width, int height, const T& def=0)
00361 {
00362 m_Array.resize(width*height,def);
00363 m_Size=iVec2(width,height);
00364 }
00365
00366 const iVec2& size() const { return m_Size; }
00367 int get_width() const { return size().x; }
00368 int get_height() const { return size().y; }
00369
00370 T& operator() (int x, int y)
00371 {
00372 if (x<0 || x>=m_Size.x || y<0 || y>=m_Size.y) throw(xstring("Invalid coords"));
00373 return m_Array[y*m_Size.x+x];
00374 }
00375
00376 const T& operator() (int x, int y) const
00377 {
00378 if (x<0 || x>=m_Size.x || y<0 || y>=m_Size.y) throw(xstring("Invalid coords"));
00379 return m_Array[y*m_Size.x+x];
00380 }
00381
00382 typedef typename array::iterator iterator;
00383 typedef typename array::const_iterator const_iterator;
00384 iterator begin() { return m_Array.begin(); }
00385 iterator end() { return m_Array.end(); }
00386 const_iterator begin() const { return m_Array.begin(); }
00387 const_iterator end() const { return m_Array.end(); }
00388 };
00389
00390 }
00391
00392 #endif // H_2D_VECTOR
00393