vtf-logo

BBox.h

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

Generated on Fri Aug 24 13:00:28 2007 for AMROC's Hierachical Data Structures - by  doxygen 1.4.7