AMROC Main     Blockstructured Adaptive Mesh Refinement in object-oriented C++


Main Page   Class Hierarchy   Compound List   File List  

BBox.h

Go to the documentation of this file.
00001 #ifndef _included_BBox_h
00002 #define _included_BBox_h
00003 
00011 #include "lparx_copyright.h"
00012 #include "Coords.h"
00013 
00014 #include <iostream.h>
00015 #include <fstream.h>
00016 #include <strstream.h>
00017 #include "streams_CompConf.h"
00018 #include <stdlib.h>
00019 
00020 #ifndef LOWERBOUND
00021 #define LOWERBOUND (-1000000000)
00022 #endif
00023 #ifndef UPPERBOUND
00024 #define UPPERBOUND ( 1000000000)
00025 #endif
00026 
00027 #define BBoxNULL        ((BBox *) NULL)
00028 
00035 class BBox
00036   {
00037    friend istream& operator >> (istream&, BBox &);
00038    friend ostream& operator << (ostream&, BBox const &);
00039    friend ifstream& operator >> (ifstream&, BBox&);
00040    friend ofstream& operator << (ofstream&, const BBox&);
00041    friend strstream& operator >> (strstream&, BBox&);
00042    friend strstream& operator << (strstream&, const BBox&);
00043 
00044    Coords lb, ub;
00045    Coords step;
00046 
00047 public:
00048    int rank;
00049    static class BBox _empty_bbox;
00050 
00051 public:
00052    inline BBox(void)
00053         : lb(0,UPPERBOUND), ub(0,LOWERBOUND), rank(-1)  {}
00054    inline BBox(const int r, const int s)
00055         : lb(r,UPPERBOUND), ub(r,LOWERBOUND), step(r,s), rank(r) {}
00056    inline BBox(const int r, Coords const &s)
00057         : lb(r,UPPERBOUND), ub(r,LOWERBOUND), step(s), rank(r) {}
00058    inline BBox(Coords const &l, Coords const &u, const int s)
00059         : lb(l), ub(u), step(l.rank,s), rank(l.rank) {}
00060    inline BBox(const int r, const int *l, const int *u, const int s)
00061         : lb(r,l), ub(r,u), step(r,s), rank(r) {}
00062    inline BBox(Coords const &l, Coords const &u, Coords const &s)
00063         : lb(l), ub(u), step(s), rank(l.rank) {}
00064    inline BBox(const int r, const int *l, const int *u, const int *s)
00065         : lb(r,l), ub(r,u), step(r,s), rank(r) {}
00066    inline BBox(BBox const &other)
00067         : lb(other.lb), ub(other.ub), step(other.step), rank(other.rank) {}
00068 
00069    /* Special constructors for 1, 2 & 3 D */
00070    inline BBox(const int r, const int i, 
00071                      const int ii, const int s)
00072         : lb(r,i), ub(r,ii), step(r,s), rank(r) {}
00073    inline BBox(const int r, const int i, const int j, 
00074                      const int ii, const int jj, const int s)
00075         : lb(r,i,j), ub(r,ii,jj), step(r,s), rank(r) {}
00076    inline BBox(const int r, const int i, const int j, const int k,
00077                      const int ii, const int jj, const int kk, const int s)
00078         : lb(r,i,j,k), ub(r,ii,jj,kk), step(r,s), rank(r) {}
00079    inline BBox(const int r, const int i, const int j, 
00080                      const int ii, const int jj, 
00081                      const int s, const int ss)
00082         : lb(r,i,j), ub(r,ii,jj), step(r,s,ss), rank(r) {}
00083    inline BBox(const int r, const int i, const int j, const int k,
00084                      const int ii, const int jj, const int kk, 
00085                      const int s, const int ss, const int sss)
00086         : lb(r,i,j,k), ub(r,ii,jj,kk), step(r,s,ss,sss), rank(r) {}
00087 
00088    inline BBox& operator = (const BBox& other)
00089         { 
00090          step = other.step; rank = other.rank; 
00091          lb = other.lb; ub = other.ub; 
00092          return(*this); 
00093         }
00094 
00095    inline ~BBox() {}
00096    
00097    /* Functions which modify the bounding box -- lower and upper bounds */
00098    inline void setempty()
00099      { lb.setval(UPPERBOUND); ub.setval(LOWERBOUND); }
00100 
00101    inline void setlower(Coords const &l) { lb = l; }
00102    inline void setlower(const int *l)
00103      { register int i; for (i=0;i<rank; i++) lb(i) = l[i]; }
00104 
00105    inline void setupper(Coords const &u) { ub = u; }
00106    inline void setupper(const int *u)
00107      { register int i; for (i=0;i<rank; i++) ub(i) = u[i]; }
00108 
00109    inline void setbbox(const int *l, const int *u)
00110      { setlower(l); setupper(u); }
00111    inline void setbbox(Coords const &l, Coords const &u) 
00112      { lb = l; ub = u; }
00113    inline void setbbox(BBox const &other) 
00114      { step = other.step; rank = other.rank; lb = other.lb; ub = other.ub; }
00115 
00116    /* Some simple inline access functions for class BBox */
00117    inline Coords const &lower() const { return(lb); }
00118    inline Coords const &upper() const { return(ub); }
00119    inline int lower(const int i) const { return(lb(i)); }
00120    inline int upper(const int i) const { return(ub(i)); }
00121 
00122    inline Coords &lower() { return(lb); }
00123    inline Coords &upper() { return(ub); }
00124    inline int &lower(const int i) { return(lb(i)); }
00125    inline int &upper(const int i) { return(ub(i)); }
00126 
00127    inline Coords const &stepsize(void) const { return (step); }
00128    inline Coords &stepsize(void) { return (step); }
00129    inline int stepsize(const int i) const { return (step(i)); }
00130    inline int &stepsize(const int i) { return (step(i)); }
00131 
00132    inline void setstepsize(const int i, const int s) { step(i) = s; }
00133    inline void setstepsize(Coords const &s) { step = s; }
00134    inline void setstepsize(const int s) { step.setval(s); }
00135 
00136    inline int extents(const int i) const 
00137      { return((ub(i)-lb(i)+step(i))/step(i)); }
00138    inline Coords extents() const 
00139      { return((ub-lb+step)/step); }
00140 
00141    inline int empty() const
00142      { return ( (rank < 0) ||
00143                ((rank > 0) && (ub(0) < lb(0))) ||
00144                ((rank > 1) && (ub(1) < lb(1))) ||
00145                ((rank > 2) && (ub(2) < lb(2)))
00146              ) ; }
00147 
00148    inline int bottom(void) const
00149      {
00150        register int b = (rank > 0) ? lb(0)/step(0) : 0;
00151        register int e = (rank > 1) ? (ub(0)-lb(0)+step(0))/step(0) : 1;
00152        b += (rank > 1) ? e*lb(1)/step(1) : 0; 
00153        e *= (rank > 2) ? (ub(1)-lb(1)+step(1))/step(1) : 1;
00154        b += (rank > 2) ? e*lb(2)/step(2) : 0; 
00155        return (-b);
00156      }
00157 
00158    inline int size() const
00159      {
00160        if (empty()) return 0;
00161        register int s = (rank > 0) ? (ub(0)-lb(0)+step(0))/step(0) : 0;
00162        s *= (rank > 1) ? ((ub(1)-lb(1)+step(1))/step(1)) : 1;
00163        s *= (rank > 2) ? ((ub(2)-lb(2)+step(2))/step(2)) : 1;
00164        return s;
00165      }
00166 
00167    /* by compatible in dimension d I mean lb1(d) == lb2(d) && ub1(d) == ub2(d) */
00168    inline int compatible(BBox const &rhs, const int d) const
00169      { return( lb(d) == rhs.lb(d) && ub(d) == rhs.ub(d) ); }
00170 
00171    /* can the boxes be merged !! */
00172    //int mergable(BBox const &rhs, const int d, const int olap) const;
00173    inline int mergable(BBox const &rhs, const int d, const int olap) const
00174      {
00175        return (
00176        (rank == 1) ? (abs(lb(d) - rhs.ub(d)) == (1-olap)*step(d)) || 
00177                      (abs(ub(d) - rhs.lb(d)) == (1-olap)*step(d)) :
00178        (rank == 2) ? compatible(rhs,(d+1)%2) &&
00179                      ((abs(lb(d) - rhs.ub(d)) == (1-olap)*step(d)) || 
00180                       (abs(ub(d) - rhs.lb(d)) == (1-olap)*step(d))) :
00181        (rank == 3) ? compatible(rhs,(d+1)%3) &&
00182                      compatible(rhs,(d+2)%3) &&
00183                      ((abs(lb(d) - rhs.ub(d)) == (1-olap)*step(d)) || 
00184                       (abs(ub(d) - rhs.lb(d)) == (1-olap)*step(d))): 0
00185        );
00186      }
00187 
00188    //int BBox::mergable(BBox const &rhs, const short* olap) const;
00189    inline int mergable(BBox const &rhs, const short* olap) const
00190      {
00191        int flag = 0;
00192        flag = (rank == 3) ? flag || mergable(rhs, 2, olap[2]) : flag; 
00193        flag = (rank >= 2) ? flag || mergable(rhs, 1, olap[1]) : flag; 
00194        flag = (rank >= 1) ? flag || mergable(rhs, 0, olap[0]) : flag; 
00195        return flag;
00196      }
00197 
00198    /* Define the bounding box operators + and += (bounding box union) */
00199    inline BBox &operator += (Coords const &rhs)
00200      {
00201        if (empty()) { lb = rhs; ub = rhs; return(*this); }
00202        lb.min(rhs); ub.max(rhs); return(*this);
00203      }
00204    inline BBox operator + (Coords const &rhs) const
00205      { BBox bbox(*this); bbox += rhs; return(bbox); }
00206 
00207    inline BBox &operator += (BBox const &rhs)
00208      {
00209        if (empty()) return(*this = rhs);
00210        if (rhs.empty()) return(*this);
00211        lb.min(rhs.lb); ub.max(rhs.ub); return(*this);
00212      }
00213    inline BBox operator + (BBox const &rhs) const
00214      { BBox bbox(*this); bbox += rhs; return(bbox); }
00215 
00216    /* Define the intersection operators * and *= */
00217    inline BBox &operator *= (BBox const &rhs)
00218      { lb.max(rhs.lb); ub.min(rhs.ub); return(*this); }
00219    inline BBox operator * (BBox const &rhs) const
00220      { BBox both(*this); both.lb.max(rhs.lb); both.ub.min(rhs.ub); 
00221        return(both); }
00222    inline int intersects(BBox const &rhs) const
00223      { BBox both(*this); both.lb.max(rhs.lb); both.ub.min(rhs.ub); 
00224        return(!both.empty()); }
00225 
00226    /* Define the comparison operators == and != */ 
00227    inline int operator == (BBox const &rhs) const
00228      { return(((ub == rhs.ub) && (lb == rhs.lb)) || 
00229               (empty() && rhs.empty())); }
00230    inline int operator != (BBox const &rhs) const 
00231      { return(!(*this == rhs)); } 
00232 
00233    /* Member functions inside() return whether a Coords 
00234       is inside the region */
00235    inline int inside(const int i) const
00236      { return ( (i >= lb(0)) && (i <= ub(0)) ); }
00237 
00238    inline int inside(const int i, const int j) const
00239      { return ( ((i >= lb(0)) && (i <= ub(0)))
00240                && ((j >= lb(1)) && (j <= ub(1)))); }
00241 
00242    inline int inside(const int i, const int j, const int k) const
00243      { return ( ((i >= lb(0)) && (i <= ub(0)))
00244                && ((j >= lb(1)) && (j <= ub(1)))
00245                && ((k >= lb(2)) && (k <= ub(2)))); }
00246 
00247    inline int inside(const int *c) const
00248      { return ( !((rank <= 0) ||
00249                ((rank > 0) && (c[0] < lb(0) || c[0] > ub(0))) ||
00250                ((rank > 1) && (c[1] < lb(1) || c[1] > ub(1))) ||     
00251                ((rank > 2) && (c[2] < lb(2) || c[2] > ub(2)))
00252                 )) ; }
00253 
00254    inline int inside(Coords const &c) const
00255      { return (BBox::inside(c())); }
00256 
00257    /* Member functions interior() return whether a 
00258       Coords is interior (not on the edge) to the region */
00259    inline int interior(const int i) const
00260      { return ( (i > lb(0)) && (i < ub(0)) ); }
00261 
00262    inline int interior(const int i, const int j) const
00263      { return ( ((i > lb(0)) && (i < ub(0)))
00264                && ((j > lb(1)) && (j < ub(1)))); }
00265 
00266    inline int interior(const int i, const int j, const int k) const
00267      { return ( ((i > lb(0)) && (i < ub(0)))
00268                && ((j > lb(1)) && (j < ub(1)))
00269                && ((k > lb(2)) && (k < ub(2)))); }
00270 
00271    inline int interior(const int *c) const
00272      { return ( !((rank <= 0) ||
00273                ((rank > 0) && (c[0] <= lb(0) || c[0] >= ub(0))) ||
00274                ((rank > 1) && (c[1] <= lb(1) || c[1] >= ub(1))) ||     
00275                ((rank > 2) && (c[2] <= lb(2) || c[2] >= ub(2)))
00276                 )) ; }
00277    inline int interior(Coords const &c) const
00278      { return (BBox::interior(c())); }
00279 
00280    /* Get linear index for a point */
00281    /*$inline int index(const int i) const 
00282      { return (i/step(0)); }
00283    inline int index(const int i, const int j) const 
00284      { return(i/step(0)+((ub(0)-lb(0)+step(0))/step(0))*(j/step(1))); }
00285    inline int index(const int i, const int j, const int k) const
00286      { return(i/step(0)+((ub(0)-lb(0)+step(0))/step(0))*
00287               (j/step(1)+((ub(1)-lb(1)+step(1))/step(1))*k/step(2))); }$*/
00288 
00289    /* BBox comparision operators */
00290    inline int operator > (BBox const &rhs) const 
00291      { return( inside(rhs.upper()) && inside(rhs.lower()) ); } 
00292    inline int operator >= (BBox const &rhs) const 
00293      { return( (*this == rhs) || 
00294                (inside(rhs.upper()) && inside(rhs.lower())) ); } 
00295 
00296    inline int operator < (BBox const &rhs) const 
00297      { return( rhs.inside(ub) && rhs.inside(lb) ); } 
00298    inline int operator <= (BBox const &rhs) const 
00299      { return( (rhs == *this) || 
00300                (rhs.inside(ub) && rhs.inside(lb)) ); } 
00301 
00302    /* Member function accrete() (also grow()) which grows a region */
00303    inline void accrete(const int i)
00304      { if (!empty()) { lb -= step*i; ub += step*i; } }
00305    inline void grow(const int i)
00306      { if (!empty()) { lb -= step*i; ub += step*i; } }
00307 
00308    inline void accrete(Coords const &c)
00309      { if (!empty()) { lb -= c*step; ub += c*step; } }
00310    inline void grow(Coords const &c)
00311      { if (!empty()) { lb -= c*step; ub += c*step; } }
00312 
00313    inline void growbydim(const short* c)
00314      {
00315       if (empty()) return;
00316       if (rank > 0) { lb(0) -= (step(0)*c[0]); ub(0) += (step(0)*c[1]); }
00317       if (rank > 1) { lb(1) -= (step(1)*c[2]); ub(1) += (step(1)*c[3]); }
00318       if (rank > 2) { lb(2) -= (step(2)*c[4]); ub(2) += (step(2)*c[5]); }
00319      }
00320 
00321    inline void shrinkbydim(const short* c)
00322      {
00323       if (empty()) return;
00324       if (rank > 0) { lb(0) += (step(0)*c[0]); ub(0) -= (step(0)*c[1]); }
00325       if (rank > 1) { lb(1) += (step(1)*c[2]); ub(1) -= (step(1)*c[3]); }
00326       if (rank > 2) { lb(2) += (step(2)*c[4]); ub(2) -= (step(2)*c[5]); }
00327      }
00328 
00329    inline void growupper(const int i)
00330      { if (!empty()) { ub += step*i; } }
00331    inline void growlower(const int i)
00332      { if (!empty()) { lb += step*i; } }
00333 
00334    inline void growupper(Coords const &c)
00335      { if (!empty()) { ub += step*c; } }
00336    inline void growlower(Coords const &c)
00337      { if (!empty()) { lb += step*c; } }
00338 
00339    inline void growupper(const int d, const int i)
00340      { if (!empty()) { ub(d) += i*step(d); } }
00341    inline void growlower(const int d, const int i)
00342      { if (!empty()) { lb(d) += i*step(d); } }
00343 
00344    inline void growupperbydim(const short* c)
00345      {
00346       if (empty()) return;
00347       if (rank > 0) { ub(0) += (step(0)*c[0]); }
00348       if (rank > 1) { ub(1) += (step(1)*c[1]); }
00349       if (rank > 2) { ub(2) += (step(2)*c[2]); }
00350      }
00351    inline void growlowerbydim(const short* c)
00352      {
00353       if (empty()) return;
00354       if (rank > 0) { lb(0) += (step(0)*c[0]); }
00355       if (rank > 1) { lb(1) += (step(1)*c[1]); }
00356       if (rank > 2) { lb(2) += (step(2)*c[2]); }
00357      }
00358 
00359    inline void shrinkupperbydim(const short* c)
00360      {
00361       if (empty()) return;
00362       if (rank > 0) { lb(0) -= (step(0)*c[0]); }
00363       if (rank > 1) { lb(1) -= (step(1)*c[1]); }
00364       if (rank > 2) { lb(2) -= (step(2)*c[2]); }
00365      }
00366    inline void shrinklowerbydim(const short* c)
00367      {
00368       if (empty()) return;
00369       if (rank > 0) { lb(0) -= (step(0)*c[0]); }
00370       if (rank > 1) { lb(1) -= (step(1)*c[1]); }
00371       if (rank > 2) { lb(2) -= (step(2)*c[2]); }
00372      }
00373 
00374    inline void shift(const int c)
00375      { if (!empty()) { lb+=step*c ; ub+=step*c; } }
00376    inline void shift(Coords const &c)
00377      { if (!empty()) { lb+=step*c ; ub+=step*c; } }
00378    inline void shift(const int d, const int c)
00379      { if (!empty()) { lb(d)+=step(d)*c ; ub(d)+=step(d)*c; } }
00380     
00381    /* Coarsen a bbox */
00382    inline void coarsen(const int by) { 
00383      step *= by; 
00384      if (!empty()) { 
00385        if (rank > 0) { 
00386          if (lb(0)<0) lb(0) -= step(0)-1; 
00387          if (ub(0)<0) ub(0) -= step(0)-1; 
00388        }
00389        if (rank > 1) { 
00390          if (lb(1)<0) lb(1) -= step(1)-1; 
00391          if (ub(1)<0) ub(1) -= step(1)-1; 
00392        }
00393        if (rank > 2) { 
00394          if (lb(2)<0) lb(2) -= step(2)-1; 
00395          if (ub(2)<0) ub(2) -= step(2)-1; 
00396        }
00397      } 
00398      lb = (lb/step)*step; ub = (ub/step)*step;
00399    }
00400    inline void coarsen(Coords const &by) { 
00401      step *= by; 
00402      if (!empty()) { 
00403        if (rank>0 && by.rank>0) { 
00404          if (lb(0)<0) lb(0) -= step(0)-1; 
00405          if (ub(0)<0) ub(0) -= step(0)-1; 
00406        }
00407        if (rank>1 && by.rank>1) { 
00408          if (lb(1)<0) lb(1) -= step(1)-1; 
00409          if (ub(1)<0) ub(1) -= step(1)-1; 
00410        }
00411        if (rank>2 && by.rank>2) { 
00412          if (lb(2)<0) lb(2) -= step(2)-1; 
00413          if (ub(2)<0) ub(2) -= step(2)-1; 
00414        }
00415      } 
00416      lb = (lb/step)*step; ub = (ub/step)*step;
00417    }
00418    inline void coarsen(const int d, const int by) { 
00419      if (!empty()) { 
00420        step(d) *= by;
00421        if (lb(d)<0) lb(d) -= step(d)-1; 
00422        if (ub(d)<0) ub(d) -= step(d)-1; 
00423        lb(d) = (lb(d)/step(d))*step(d);
00424        ub(d) = (ub(d)/step(d))*step(d); 
00425      } 
00426    }   
00427 
00428    /* Refine a bbox - valid only for Cell-BBox's */
00429    inline void refine(const int by) { growupper(1); step /= by; growupper(-1); }
00430    inline void refine(Coords const &by) { growupper(1); step /= by; growupper(-1); }
00431 
00432    /* Refine a bbox - with explicit overlap parameter */
00433    inline void refine(const int by, const int olap) 
00434      { growupper(1); step /= by; growupper(-1); ub += (step*olap); }
00435    inline void refine(const int by, const short* olap) 
00436      { growupper(1); step /= by; growupper(-1); growupperbydim(olap); }
00437    inline void refine(const int d, const int by, const int olap) 
00438      { growupper(d,1); step(d) /= by; growupper(d,-1); ub(d) += (step(d)*olap); }
00439 };
00440 
00441 istream& operator >> (istream& s, BBox & bb);
00442 ostream& operator << (ostream& s, const BBox &bb);
00443 ifstream& operator >> (ifstream& s, BBox& bb);
00444 ofstream& operator << (ofstream& s, const BBox& bb);
00445 
00446 /* Query functions */
00447 inline Coords &upper(BBox &bb)
00448 { return (bb.upper()); }
00449 inline int upper(BBox &bb, const int i)
00450 { return (bb.upper(i)); }
00451 
00452 inline Coords &lower(BBox &bb)
00453 { return (bb.lower()); }
00454 inline int lower(BBox &bb, const int i)
00455 { return (bb.lower(i)); }
00456 
00457 inline Coords &stepsize(BBox &bb)
00458 { return (bb.stepsize()); }
00459 inline int stepsize(BBox &bb, const int i)
00460 { return (bb.stepsize(i)); }
00461 
00462 inline Coords extents(BBox &bb)
00463 { return (bb.extents()); }
00464 inline int extents(BBox &bb, const int i)
00465 { return (bb.extents(i)); }
00466 
00467 inline int size(BBox &bb)
00468 { return (bb.size()); }
00469 inline int inside(BBox &bb, Coords const &c)
00470 { return (bb.inside(c)); }
00471 
00472 /* Function accrete() increases or decreases the size of the region */
00473 inline BBox accrete(BBox const &bbox, Coords const &c)
00474   { const Coords& u = bbox.upper(); const Coords& l = bbox.lower(); 
00475     const Coords& s = bbox.stepsize();
00476     return ( (bbox.empty()) ? bbox : BBox(l-c*s, u+c*s, s) ); }
00477 inline BBox grow(BBox const &bbox, Coords const &c)
00478   { const Coords& u = bbox.upper(); const Coords& l = bbox.lower(); 
00479     const Coords& s = bbox.stepsize();
00480     return ( (bbox.empty()) ? bbox : BBox(l-c*s, u+c*s, s) ); }
00481 
00482 inline BBox accrete(BBox const &bbox, const int c)
00483   { const Coords& u = bbox.upper(); const Coords& l = bbox.lower(); 
00484     const Coords& s = bbox.stepsize();
00485     return ( (bbox.empty()) ? bbox : BBox(l-s*c, u+s*c, s) ); }
00486 inline BBox grow(BBox const &bbox, const int c)
00487   { const Coords& u = bbox.upper(); const Coords& l = bbox.lower(); 
00488     const Coords& s = bbox.stepsize();
00489     return ( (bbox.empty()) ? bbox : BBox(l-s*c, u+s*c, s) ); }
00490 
00491 BBox* accrete(BBox const *const bbox, const int n, const int c);
00492 BBox* grow(BBox const *const bbox, const int n, const int c);
00493 
00494 BBox* accrete(BBox const *const bbox, const int n, Coords const &c);
00495 BBox* grow(BBox const *const bbox, const int n, Coords const &c);
00496 
00497 inline BBox growupper(BBox const &bbox, const int c)
00498   { const Coords& u = bbox.upper(); const Coords& l = bbox.lower(); 
00499     const Coords& s = bbox.stepsize();
00500     return ( (bbox.empty()) ? bbox : BBox(l, u+s*c, s) ); }
00501 inline BBox growlower(BBox const &bbox, const int c)
00502   { const Coords& u = bbox.upper(); const Coords& l = bbox.lower(); 
00503     const Coords& s = bbox.stepsize();
00504     return ( (bbox.empty()) ? bbox : BBox(l+s*c, u, s) ); }
00505 
00506 inline BBox growupper(BBox const &bbox, const int d, const int c)
00507   {
00508    if (bbox.empty()) return(bbox);
00509    const Coords& l = bbox.lower(); const Coords& s = bbox.stepsize();
00510    Coords u = bbox.upper(); u(d) += c*s(d);
00511    return(BBox(l, u, s));
00512   }
00513 inline BBox growlower(BBox const &bbox, const int d, const int c)
00514   {
00515    if (bbox.empty()) return(bbox);
00516    const Coords& u = bbox.upper(); const Coords& s = bbox.stepsize();
00517    Coords l = bbox.lower(); l(d) += c*s(d);
00518    return(BBox(l, u, s));
00519   }
00520 
00521 inline BBox growbydim(BBox const &bbox, const short* c)      /* short c[2*rank] */
00522   {
00523    BBox bb(bbox);
00524    if (bb.empty()) return(bb);
00525    if (bb.rank > 0)
00526      {bb.lower(0) -= (bb.stepsize(0)*c[0]);bb.upper(0) += (bb.stepsize(0)*c[1]);}
00527    if (bb.rank > 1)
00528      {bb.lower(1) -= (bb.stepsize(1)*c[2]);bb.upper(1) += (bb.stepsize(1)*c[3]);}
00529    if (bb.rank > 2)
00530      {bb.lower(2) -= (bb.stepsize(2)*c[4]);bb.upper(2) += (bb.stepsize(2)*c[5]);}
00531    return bb;
00532   }
00533 inline BBox growupperbydim(BBox const &bbox, const short* c) /* short c[rank] */
00534   {
00535    BBox bb(bbox);
00536    if (bb.empty()) return(bb);
00537    if (bb.rank > 0)
00538      {bb.upper(0) += (bb.stepsize(0)*c[0]);}
00539    if (bb.rank > 1)
00540      {bb.upper(1) += (bb.stepsize(1)*c[1]);}
00541    if (bb.rank > 2)
00542      {bb.upper(2) += (bb.stepsize(2)*c[2]);}
00543    return bb;
00544   }
00545 inline BBox growlowerbydim(BBox const &bbox, const short* c) /* short c[rank] */
00546   {
00547    BBox bb(bbox);
00548    if (bb.empty()) return(bb);
00549    if (bb.rank > 0)
00550      {bb.lower(0) += (bb.stepsize(0)*c[0]);}
00551    if (bb.rank > 1)
00552      {bb.lower(1) += (bb.stepsize(1)*c[1]);}
00553    if (bb.rank > 2)
00554      {bb.lower(2) += (bb.stepsize(2)*c[2]);}
00555    return bb;
00556   }
00557 
00558 inline BBox shrinkbydim(BBox const &bbox, const short* c)    /* short c[2*rank] */
00559   {
00560    BBox bb(bbox);
00561    if (bb.empty()) return(bb);
00562    if (bb.rank > 0)
00563      {bb.lower(0) += (bb.stepsize(0)*c[0]);bb.upper(0) -= (bb.stepsize(0)*c[1]);}
00564    if (bb.rank > 1)
00565      {bb.lower(1) += (bb.stepsize(1)*c[2]);bb.upper(1) -= (bb.stepsize(1)*c[3]);}
00566    if (bb.rank > 2)
00567      {bb.lower(2) += (bb.stepsize(2)*c[4]);bb.upper(2) -= (bb.stepsize(2)*c[5]);}
00568    return bb;
00569   }
00570 inline BBox shrinkupperbydim(BBox const &bbox, const short* c) /* short c[rank] */
00571   {
00572    BBox bb(bbox);
00573    if (bb.empty()) return(bb);
00574    if (bb.rank > 0)
00575      {bb.upper(0) -= (bb.stepsize(0)*c[0]);}
00576    if (bb.rank > 1)
00577      {bb.upper(1) -= (bb.stepsize(1)*c[1]);}
00578    if (bb.rank > 2)
00579      {bb.upper(2) -= (bb.stepsize(2)*c[2]);}
00580    return bb;
00581   }
00582 inline BBox shrinklowerbydim(BBox const &bbox, const short* c) /* short c[rank] */
00583   {
00584    BBox bb(bbox);
00585    if (bb.empty()) return(bb);
00586    if (bb.rank > 0)
00587      {bb.lower(0) -= (bb.stepsize(0)*c[0]);}
00588    if (bb.rank > 1)
00589      {bb.lower(1) -= (bb.stepsize(1)*c[1]);}
00590    if (bb.rank > 2)
00591      {bb.lower(2) -= (bb.stepsize(2)*c[2]);}
00592    return bb;
00593   }
00594 
00595 /* Function shift() shifts the  space of the region */
00596 inline BBox shiftabs(BBox const &bb, const int c)
00597   { return(BBox(bb.lower()+c, bb.upper()+c, bb.stepsize())); }
00598 inline BBox shiftabs(BBox const &bb, Coords const &c)
00599   { return(BBox(bb.lower()+c, bb.upper()+c, bb.stepsize())); }
00600 
00601 inline BBox shift(BBox const &bb, const int c)
00602   { return(BBox(bb.lower()+bb.stepsize()*c, 
00603                 bb.upper()+bb.stepsize()*c,bb.stepsize())); }
00604 inline BBox shift(BBox const &bb, Coords const &c)
00605   { return(BBox(bb.lower()+c*bb.stepsize(), 
00606                 bb.upper()+c*bb.stepsize(),bb.stepsize())); }
00607 
00608 inline BBox shiftabs(BBox const &bbox, const int d, const int c)
00609   {
00610    if (bbox.empty()) return(bbox);
00611    Coords u = bbox.upper(); u(d) += c;
00612    Coords l = bbox.lower(); l(d) += c;
00613    return(BBox(l, u, bbox.stepsize()));
00614   }
00615 inline BBox shift(BBox const &bbox, const int d, const int c)
00616   {
00617    if (bbox.empty()) return(bbox);
00618    Coords u = bbox.upper(); u(d) += c*bbox.stepsize(d);
00619    Coords l = bbox.lower(); l(d) += c*bbox.stepsize(d);
00620    return(BBox(l, u, bbox.stepsize()));
00621   }
00622 
00623 /* Function coarsen() coarsens  the BBox by a given factor */
00624 inline BBox coarsen(BBox const &bbox, const int by) { 
00625   BBox bb(bbox);
00626   bb.coarsen(by);
00627   return (bbox.empty() ? bbox : bb); 
00628 }
00629 inline BBox coarsen(BBox const &bbox, Coords const by) {
00630   BBox bb(bbox);
00631   bb.coarsen(by);
00632   return (bbox.empty() ? bbox : bb); 
00633 }
00634 inline BBox coarsen(BBox const &bbox, const int d, const int by) {
00635   BBox bb(bbox);
00636   bb.coarsen(d,by);
00637   return (bbox.empty() ? bbox : bb); 
00638 }
00639 
00640 /* Refine a bbox - valid only for Cell-BBox's */
00641 inline BBox refine(const BBox& bbox, const int by) {   
00642   BBox bb(bbox);
00643   bb.refine(by);
00644   return (bbox.empty() ? bbox : bb); 
00645 }
00646 inline BBox refine(const BBox& bbox, const Coords& by) {
00647   BBox bb(bbox);
00648   bb.refine(by);
00649   return (bbox.empty() ? bbox : bb); 
00650 }
00651 
00652 /* Refine a bbox - with explicit overlap parameter */
00653 inline BBox refine(const BBox& bbox, const int by, const int olap) {   
00654   BBox bb(bbox);
00655   bb.refine(by,olap);
00656   return (bbox.empty() ? bbox : bb); 
00657 }
00658 inline BBox refine(const BBox& bbox, const int by, const short* olap) {
00659   BBox bb(bbox);
00660   bb.refine(by,olap);
00661   return (bbox.empty() ? bbox : bb); 
00662 }
00663 inline BBox refine(const BBox& bbox, const int d, const int by, const int olap) { 
00664   BBox bb(bbox);
00665   bb.refine(d,by,olap);
00666   return (bbox.empty() ? bbox : bb); 
00667 }
00668 
00669 #include "CoordsIterator.h"
00670 
00671 #endif


Quickstart     Users Guide     Programmers Reference     Installation      Examples     Download



AMROC Main      Home      Contact
last update: 06/01/04