00001 #ifndef NMWR_GB_GRAL_CARTESIAN2D_INDEXMAP_H
00002 #define NMWR_GB_GRAL_CARTESIAN2D_INDEXMAP_H
00003
00004
00005
00006 #include <iostream>
00007 #include "Utility/pre-post-conditions.h"
00008 #include "Gral/Grids/Cartesian2D/index-type.h"
00009
00033 class xmjr_indexmap2D {
00034 public:
00035 typedef int_index_type index_type;
00036
00039 struct range {
00040 int x,y;
00041 range(int xx, int yy) : x(xx), y(yy) {}
00042 friend std::ostream& operator<<(std::ostream& out, const range& r) {
00043 return (out << '[' << r.x << ',' << r.y << ']');
00044 }
00045 };
00046
00047
00048
00049 xmjr_indexmap2D(const index_type& UR = index_type(0,0))
00050 : ll_(0,0),ur_(UR), n0_(0) { init();}
00051 xmjr_indexmap2D(int urx, int ury)
00052 : ll_(0,0),ur_(urx,ury), n0_(0) { init();}
00053
00054 xmjr_indexmap2D(const index_type& LL,const index_type& UR, int off = 0)
00055 : ll_(LL), ur_(UR), n0_(off) { init();}
00056
00057 void init() {
00058 nx = ur_.x-ll_.x+1;
00059 ny = ur_.y-ll_.y+1;
00060 rect_size = nx*ny;
00061 }
00062
00063 int x0() const { return ll_.x;}
00064 int xmax() const { return ur_.x;}
00065 int y0() const { return ll_.y;}
00066 int ymax() const { return ur_.y;}
00067 int n0() const { return n0_;}
00068 int nmax() const { return n0() + range_size() -1;}
00069
00070 const index_type& ll() const {return ll_;}
00071 int llx() const {return ll_.x;}
00072 int lly() const {return ll_.y;}
00073 const index_type& ur() const {return ur_;}
00074 int urx() const {return ur_.x;}
00075 int ury() const {return ur_.y;}
00076
00077
00078 bool IsInRange(int x, int y) const {
00079 return ((ll_.x <= x) && ( x <= ur_.x) &&(ll_.y <= y) && ( y <= ur_.y));
00080 }
00081 bool IsInRange(const index_type& i) const {
00082 return IsInRange(i.x,i.y);
00083 }
00084 bool IsInRange(int i) const {
00085 return((n0() <= i) && ( i <= n0() -1 + range_size()));
00086 }
00087
00088 int number(int x, int y) const {
00089 REQUIRE(IsInRange(x,y),
00090 "index (x,y) = (" << x << "," << y << ") not in range "
00091 << range(ll_.x,ur_.x) << "x" << range(ll_.y,ur_.y) << "!",1);
00092 return (n0() + (x-x0())*ny + (y-y0()) );
00093 }
00094 int number(const index_type& idx) const { return number(idx.x,idx.y);}
00095 int offset(int x, int y) const { return number(x,y) - n0();}
00096 int offset(const index_type ij) const { return number(ij) - n0();}
00097
00098 index_type index(int i) const {
00099 REQUIRE(IsInRange(i),
00100 "number not in range " << range(n0(),n0() + range_size() -1) << ": i = " << i,1);
00101 int i0 = i - n0();
00102 int x = i0 / ny;
00103 int y = i0 - x*ny;
00104 return index_type(x0()+x,y0()+y);
00105 }
00106
00107 int range_size() const { return rect_size;}
00108
00109 private:
00110
00111
00112 index_type ll_,ur_;
00113 int n0_;
00114
00115
00116 int nx,ny;
00117 int rect_size;
00118 };
00119
00120 #endif
00121