00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef LEMON_XY_H
00020 #define LEMON_XY_H
00021
00022 #include <iostream>
00023 #include <lemon/utility.h>
00024
00037
00038
00039 namespace lemon {
00040
00043
00045
00051 template<typename T>
00052 class xy {
00053
00054 public:
00055
00056 typedef T Value;
00057
00058 T x,y;
00059
00061 xy() {}
00062
00064 xy(T a, T b) : x(a), y(b) { }
00065
00066
00068 template<class TT> xy(const xy<TT> &p) : x(p.x), y(p.y) {}
00069
00071 T normSquare() const {
00072 return x*x+y*y;
00073 }
00074
00076 xy<T>& operator +=(const xy<T>& u) {
00077 x += u.x;
00078 y += u.y;
00079 return *this;
00080 }
00081
00083 xy<T>& operator -=(const xy<T>& u) {
00084 x -= u.x;
00085 y -= u.y;
00086 return *this;
00087 }
00088
00090 xy<T>& operator *=(const T &u) {
00091 x *= u;
00092 y *= u;
00093 return *this;
00094 }
00095
00097 xy<T>& operator /=(const T &u) {
00098 x /= u;
00099 y /= u;
00100 return *this;
00101 }
00102
00104 T operator *(const xy<T>& u) const {
00105 return x*u.x+y*u.y;
00106 }
00107
00109 xy<T> operator+(const xy<T> &u) const {
00110 xy<T> b=*this;
00111 return b+=u;
00112 }
00113
00115 xy<T> operator-() const {
00116 xy<T> b=*this;
00117 b.x=-b.x; b.y=-b.y;
00118 return b;
00119 }
00120
00122 xy<T> operator-(const xy<T> &u) const {
00123 xy<T> b=*this;
00124 return b-=u;
00125 }
00126
00128 xy<T> operator*(const T &u) const {
00129 xy<T> b=*this;
00130 return b*=u;
00131 }
00132
00134 xy<T> operator/(const T &u) const {
00135 xy<T> b=*this;
00136 return b/=u;
00137 }
00138
00140 bool operator==(const xy<T> &u) const {
00141 return (x==u.x) && (y==u.y);
00142 }
00143
00145 bool operator!=(xy u) const {
00146 return (x!=u.x) || (y!=u.y);
00147 }
00148
00149 };
00150
00152
00155 template<typename T> xy<T> operator*(const T &u,const xy<T> &x) {
00156 return x*u;
00157 }
00158
00160
00164 template<typename T>
00165 inline std::istream& operator>>(std::istream &is, xy<T> &z) {
00166 char c;
00167 if (is >> c) {
00168 if (c != '(') is.putback(c);
00169 } else {
00170 is.clear();
00171 }
00172 if (!(is >> z.x)) return is;
00173 if (is >> c) {
00174 if (c != ',') is.putback(c);
00175 } else {
00176 is.clear();
00177 }
00178 if (!(is >> z.y)) return is;
00179 if (is >> c) {
00180 if (c != ')') is.putback(c);
00181 } else {
00182 is.clear();
00183 }
00184 return is;
00185 }
00186
00188
00192 template<typename T>
00193 inline std::ostream& operator<<(std::ostream &os, const xy<T>& z)
00194 {
00195 os << "(" << z.x << ", " << z.y << ")";
00196 return os;
00197 }
00198
00200
00204 template<typename T>
00205 inline xy<T> rot90(const xy<T> &z)
00206 {
00207 return xy<T>(-z.y,z.x);
00208 }
00209
00211
00215 template<typename T>
00216 inline xy<T> rot270(const xy<T> &z)
00217 {
00218 return xy<T>(z.y,-z.x);
00219 }
00220
00221
00222
00224
00228 template<typename T>
00229 class BoundingBox {
00230 xy<T> bottom_left, top_right;
00231 bool _empty;
00232 public:
00233
00235 BoundingBox() { _empty = true; }
00236
00238 BoundingBox(xy<T> a) { bottom_left=top_right=a; _empty = false; }
00239
00241 bool empty() const {
00242 return _empty;
00243 }
00244
00246 void clear() {
00247 _empty=1;
00248 }
00249
00252 xy<T> bottomLeft() const {
00253 return bottom_left;
00254 }
00255
00258 void bottomLeft(xy<T> p) {
00259 bottom_left = p;
00260 }
00261
00264 xy<T> topRight() const {
00265 return top_right;
00266 }
00267
00270 void topRight(xy<T> p) {
00271 top_right = p;
00272 }
00273
00276 xy<T> bottomRight() const {
00277 return xy<T>(top_right.x,bottom_left.y);
00278 }
00279
00282 void bottomRight(xy<T> p) {
00283 top_right.x = p.x;
00284 bottom_left.y = p.y;
00285 }
00286
00289 xy<T> topLeft() const {
00290 return xy<T>(bottom_left.x,top_right.y);
00291 }
00292
00295 void topLeft(xy<T> p) {
00296 top_right.y = p.y;
00297 bottom_left.x = p.x;
00298 }
00299
00302 T bottom() const {
00303 return bottom_left.y;
00304 }
00305
00308 void bottom(T t) {
00309 bottom_left.y = t;
00310 }
00311
00314 T top() const {
00315 return top_right.y;
00316 }
00317
00320 void top(T t) {
00321 top_right.y = t;
00322 }
00323
00326 T left() const {
00327 return bottom_left.x;
00328 }
00329
00332 void left(T t) {
00333 bottom_left.x = t;
00334 }
00335
00338 T right() const {
00339 return top_right.x;
00340 }
00341
00344 void right(T t) {
00345 top_right.x = t;
00346 }
00347
00350 T height() const {
00351 return top_right.y-bottom_left.y;
00352 }
00353
00356 T width() const {
00357 return top_right.x-bottom_left.x;
00358 }
00359
00361 bool inside(const xy<T>& u){
00362 if (_empty)
00363 return false;
00364 else{
00365 return ((u.x-bottom_left.x)*(top_right.x-u.x) >= 0 &&
00366 (u.y-bottom_left.y)*(top_right.y-u.y) >= 0 );
00367 }
00368 }
00369
00371 BoundingBox& add(const xy<T>& u){
00372 if (_empty){
00373 bottom_left=top_right=u;
00374 _empty = false;
00375 }
00376 else{
00377 if (bottom_left.x > u.x) bottom_left.x = u.x;
00378 if (bottom_left.y > u.y) bottom_left.y = u.y;
00379 if (top_right.x < u.x) top_right.x = u.x;
00380 if (top_right.y < u.y) top_right.y = u.y;
00381 }
00382 return *this;
00383 }
00384
00385
00386
00387
00388
00389
00390
00392 BoundingBox& add(const BoundingBox &u){
00393 if ( !u.empty() ){
00394 this->add(u.bottomLeft());
00395 this->add(u.topRight());
00396 }
00397 return *this;
00398 }
00399
00401 BoundingBox operator +(const BoundingBox& u){
00402 BoundingBox b = *this;
00403 return b.add(u);
00404 }
00405
00406
00408 BoundingBox operator &(const BoundingBox& u){
00409 BoundingBox b;
00410 b.bottom_left.x=std::max(this->bottom_left.x,u.bottom_left.x);
00411 b.bottom_left.y=std::max(this->bottom_left.y,u.bottom_left.y);
00412 b.top_right.x=std::min(this->top_right.x,u.top_right.x);
00413 b.top_right.y=std::min(this->top_right.y,u.top_right.y);
00414 b._empty = this->_empty || u._empty ||
00415 b.bottom_left.x>top_right.x && b.bottom_left.y>top_right.y;
00416 return b;
00417 }
00418
00419 };
00420
00421
00423
00426 template<class M>
00427 class XMap
00428 {
00429 M& _map;
00430 public:
00431
00432 typedef typename M::Value::Value Value;
00433 typedef typename M::Key Key;
00435 XMap(M& map) : _map(map) {}
00436 Value operator[](Key k) const {return _map[k].x;}
00437 void set(Key k,Value v) {_map.set(k,typename M::Value(v,_map[k].y));}
00438 };
00439
00441
00446 template<class M>
00447 inline XMap<M> xMap(M &m)
00448 {
00449 return XMap<M>(m);
00450 }
00451
00452 template<class M>
00453 inline XMap<M> xMap(const M &m)
00454 {
00455 return XMap<M>(m);
00456 }
00457
00459
00462 template<class M>
00463 class ConstXMap
00464 {
00465 const M& _map;
00466 public:
00467
00468 typedef typename M::Value::Value Value;
00469 typedef typename M::Key Key;
00471 ConstXMap(const M &map) : _map(map) {}
00472 Value operator[](Key k) const {return _map[k].x;}
00473 };
00474
00476
00481 template<class M>
00482 inline ConstXMap<M> xMap(const M &m)
00483 {
00484 return ConstXMap<M>(m);
00485 }
00486
00488
00491 template<class M>
00492 class YMap
00493 {
00494 M& _map;
00495 public:
00496
00497 typedef typename M::Value::Value Value;
00498 typedef typename M::Key Key;
00500 YMap(M& map) : _map(map) {}
00501 Value operator[](Key k) const {return _map[k].y;}
00502 void set(Key k,Value v) {_map.set(k,typename M::Value(_map[k].x,v));}
00503 };
00504
00506
00511 template<class M>
00512 inline YMap<M> yMap(M &m)
00513 {
00514 return YMap<M>(m);
00515 }
00516
00517 template<class M>
00518 inline YMap<M> yMap(const M &m)
00519 {
00520 return YMap<M>(m);
00521 }
00522
00524
00527 template<class M>
00528 class ConstYMap
00529 {
00530 const M& _map;
00531 public:
00532
00533 typedef typename M::Value::Value Value;
00534 typedef typename M::Key Key;
00536 ConstYMap(const M &map) : _map(map) {}
00537 Value operator[](Key k) const {return _map[k].y;}
00538 };
00539
00541
00546 template<class M>
00547 inline ConstYMap<M> yMap(const M &m)
00548 {
00549 return ConstYMap<M>(m);
00550 }
00551
00552
00554
00558 template<class M>
00559 class NormSquareMap
00560 {
00561 const M& _map;
00562 public:
00563
00564 typedef typename M::Value::Value Value;
00565 typedef typename M::Key Key;
00567 NormSquareMap(const M &map) : _map(map) {}
00568 Value operator[](Key k) const {return _map[k].normSquare();}
00569 };
00570
00572
00577 template<class M>
00578 inline NormSquareMap<M> normSquareMap(const M &m)
00579 {
00580 return NormSquareMap<M>(m);
00581 }
00582
00584
00585
00586 }
00587
00588 #endif //LEMON_XY_H