00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef LEMON_XY_H
00018 #define LEMON_XY_H
00019
00020 #include <iostream>
00021 #include <lemon/utility.h>
00022
00035
00036
00037 namespace lemon {
00038
00041
00043
00049 template<typename T>
00050 class xy {
00051
00052 public:
00053
00054 typedef T Value;
00055
00056 T x,y;
00057
00059 xy() {}
00060
00062 xy(T a, T b) : x(a), y(b) { }
00063
00064
00066 template<class TT> xy(const xy<TT> &p) : x(p.x), y(p.y) {}
00067
00069 T normSquare() const {
00070 return x*x+y*y;
00071 }
00072
00074 xy<T>& operator +=(const xy<T>& u) {
00075 x += u.x;
00076 y += u.y;
00077 return *this;
00078 }
00079
00081 xy<T>& operator -=(const xy<T>& u) {
00082 x -= u.x;
00083 y -= u.y;
00084 return *this;
00085 }
00086
00088 xy<T>& operator *=(const T &u) {
00089 x *= u;
00090 y *= u;
00091 return *this;
00092 }
00093
00095 xy<T>& operator /=(const T &u) {
00096 x /= u;
00097 y /= u;
00098 return *this;
00099 }
00100
00102 T operator *(const xy<T>& u) const {
00103 return x*u.x+y*u.y;
00104 }
00105
00107 xy<T> operator+(const xy<T> &u) const {
00108 xy<T> b=*this;
00109 return b+=u;
00110 }
00111
00113 xy<T> operator-() const {
00114 xy<T> b=*this;
00115 b.x=-b.x; b.y=-b.y;
00116 return b;
00117 }
00118
00120 xy<T> operator-(const xy<T> &u) const {
00121 xy<T> b=*this;
00122 return b-=u;
00123 }
00124
00126 xy<T> operator*(const T &u) const {
00127 xy<T> b=*this;
00128 return b*=u;
00129 }
00130
00132 xy<T> operator/(const T &u) const {
00133 xy<T> b=*this;
00134 return b/=u;
00135 }
00136
00138 bool operator==(const xy<T> &u) const {
00139 return (x==u.x) && (y==u.y);
00140 }
00141
00143 bool operator!=(xy u) const {
00144 return (x!=u.x) || (y!=u.y);
00145 }
00146
00147 };
00148
00150
00153 template<typename T> xy<T> operator*(const T &u,const xy<T> &x) {
00154 return x*u;
00155 }
00156
00158
00162 template<typename T>
00163 inline std::istream& operator>>(std::istream &is, xy<T> &z) {
00164 char c;
00165 if (is >> c) {
00166 if (c != '(') is.putback(c);
00167 } else {
00168 is.clear();
00169 }
00170 if (!(is >> z.x)) return is;
00171 if (is >> c) {
00172 if (c != ',') is.putback(c);
00173 } else {
00174 is.clear();
00175 }
00176 if (!(is >> z.y)) return is;
00177 if (is >> c) {
00178 if (c != ')') is.putback(c);
00179 } else {
00180 is.clear();
00181 }
00182 return is;
00183 }
00184
00186
00190 template<typename T>
00191 inline std::ostream& operator<<(std::ostream &os, const xy<T>& z)
00192 {
00193 os << "(" << z.x << ", " << z.y << ")";
00194 return os;
00195 }
00196
00198
00202 template<typename T>
00203 inline xy<T> rot90(const xy<T> &z)
00204 {
00205 return xy<T>(-z.y,z.x);
00206 }
00207
00209
00213 template<typename T>
00214 inline xy<T> rot270(const xy<T> &z)
00215 {
00216 return xy<T>(z.y,-z.x);
00217 }
00218
00219
00220
00222
00226 template<typename T>
00227 class BoundingBox {
00228 xy<T> bottom_left, top_right;
00229 bool _empty;
00230 public:
00231
00233 BoundingBox() { _empty = true; }
00234
00236 BoundingBox(xy<T> a) { bottom_left=top_right=a; _empty = false; }
00237
00239 bool empty() const {
00240 return _empty;
00241 }
00242
00244 void clear() {
00245 _empty=1;
00246 }
00247
00249 xy<T> bottomLeft() const {
00250 return bottom_left;
00251 }
00252
00254 xy<T> topRight() const {
00255 return top_right;
00256 }
00257
00259 xy<T> bottomRight() const {
00260 return xy<T>(top_right.x,bottom_left.y);
00261 }
00262
00264 xy<T> topLeft() const {
00265 return xy<T>(bottom_left.x,top_right.y);
00266 }
00267
00269 T bottom() const {
00270 return bottom_left.y;
00271 }
00272
00274 T top() const {
00275 return top_right.y;
00276 }
00277
00279 T left() const {
00280 return bottom_left.x;
00281 }
00282
00284 T right() const {
00285 return top_right.x;
00286 }
00287
00289 T height() const {
00290 return top_right.y-bottom_left.y;
00291 }
00292
00294 T width() const {
00295 return top_right.x-bottom_left.x;
00296 }
00297
00299 bool inside(const xy<T>& u){
00300 if (_empty)
00301 return false;
00302 else{
00303 return ((u.x-bottom_left.x)*(top_right.x-u.x) >= 0 &&
00304 (u.y-bottom_left.y)*(top_right.y-u.y) >= 0 );
00305 }
00306 }
00307
00309 BoundingBox& add(const xy<T>& u){
00310 if (_empty){
00311 bottom_left=top_right=u;
00312 _empty = false;
00313 }
00314 else{
00315 if (bottom_left.x > u.x) bottom_left.x = u.x;
00316 if (bottom_left.y > u.y) bottom_left.y = u.y;
00317 if (top_right.x < u.x) top_right.x = u.x;
00318 if (top_right.y < u.y) top_right.y = u.y;
00319 }
00320 return *this;
00321 }
00322
00323
00324
00325
00326
00327
00328
00330 BoundingBox& add(const BoundingBox &u){
00331 if ( !u.empty() ){
00332 this->add(u.bottomLeft());
00333 this->add(u.topRight());
00334 }
00335 return *this;
00336 }
00337
00339 BoundingBox operator +(const BoundingBox& u){
00340 BoundingBox b = *this;
00341 return b.add(u);
00342 }
00343
00344
00346 BoundingBox operator &(const BoundingBox& u){
00347 BoundingBox b;
00348 b.bottom_left.x=std::max(this->bottom_left.x,u.bottom_left.x);
00349 b.bottom_left.y=std::max(this->bottom_left.y,u.bottom_left.y);
00350 b.top_right.x=std::min(this->top_right.x,u.top_right.x);
00351 b.top_right.y=std::min(this->top_right.y,u.top_right.y);
00352 b._empty = this->_empty || u._empty ||
00353 b.bottom_left.x>top_right.x && b.bottom_left.y>top_right.y;
00354 return b;
00355 }
00356
00357 };
00358
00359
00361
00364 template<class M>
00365 class XMap
00366 {
00367 typename SmartReference<M>::Type _map;
00368 public:
00369 typedef True NeedCopy;
00370
00371 typedef typename M::Value::Value Value;
00372 typedef typename M::Key Key;
00374 XMap(typename SmartParameter<M>::Type map) : _map(map) {}
00375 Value operator[](Key k) const {return _map[k].x;}
00376 void set(Key k,Value v) {_map.set(k,typename M::Value(v,_map[k].y));}
00377 };
00378
00380
00385 template<class M>
00386 inline XMap<M> xMap(M &m)
00387 {
00388 return XMap<M>(m);
00389 }
00390
00391 template<class M>
00392 inline XMap<M> xMap(const M &m)
00393 {
00394 return XMap<M>(m);
00395 }
00396
00398
00401 template<class M>
00402 class ConstXMap
00403 {
00404 typename SmartConstReference<M>::Type _map;
00405 public:
00406 typedef True NeedCopy;
00407
00408 typedef typename M::Value::Value Value;
00409 typedef typename M::Key Key;
00411 ConstXMap(const M &map) : _map(map) {}
00412 Value operator[](Key k) const {return _map[k].x;}
00413 };
00414
00416
00421 template<class M>
00422 inline ConstXMap<M> xMap(const M &m)
00423 {
00424 return ConstXMap<M>(m);
00425 }
00426
00428
00431 template<class M>
00432 class YMap
00433 {
00434 typename SmartReference<M>::Type _map;
00435 public:
00436 typedef True NeedCopy;
00437
00438 typedef typename M::Value::Value Value;
00439 typedef typename M::Key Key;
00441 YMap(typename SmartParameter<M>::Type map) : _map(map) {}
00442 Value operator[](Key k) const {return _map[k].y;}
00443 void set(Key k,Value v) {_map.set(k,typename M::Value(_map[k].x,v));}
00444 };
00445
00447
00452 template<class M>
00453 inline YMap<M> yMap(M &m)
00454 {
00455 return YMap<M>(m);
00456 }
00457
00458 template<class M>
00459 inline YMap<M> yMap(const M &m)
00460 {
00461 return YMap<M>(m);
00462 }
00463
00465
00468 template<class M>
00469 class ConstYMap
00470 {
00471 typename SmartConstReference<M>::Type _map;
00472 public:
00473 typedef True NeedCopy;
00474
00475 typedef typename M::Value::Value Value;
00476 typedef typename M::Key Key;
00478 ConstYMap(const M &map) : _map(map) {}
00479 Value operator[](Key k) const {return _map[k].y;}
00480 };
00481
00483
00488 template<class M>
00489 inline ConstYMap<M> yMap(const M &m)
00490 {
00491 return ConstYMap<M>(m);
00492 }
00493
00494
00496
00500 template<class M>
00501 class NormSquareMap
00502 {
00503 typename SmartConstReference<M>::Type _map;
00504 public:
00505 typedef True NeedCopy;
00506
00507 typedef typename M::Value::Value Value;
00508 typedef typename M::Key Key;
00510 NormSquareMap(const M &map) : _map(map) {}
00511 Value operator[](Key k) const {return _map[k].normSquare();}
00512 };
00513
00515
00520 template<class M>
00521 inline NormSquareMap<M> normSquareMap(const M &m)
00522 {
00523 return NormSquareMap<M>(m);
00524 }
00525
00527
00528
00529 }
00530
00531 #endif //LEMON_XY_H