00001 #ifndef _BOX_H_ 00002 #define _BOX_H_ 00003 #include "SPACE.H" 00004 #include "Point.H" 00005 #include <iostream> 00006 extern bool reportMemory; 00007 extern unsigned long long int memory; 00008 00009 /// An interval in DIM dimensional space. 00010 /** 00011 A Box is a region specified by two corners, highCorner and lowCorner. In 2 dimensions, a Box is a rectangular region. In 3 dimensions, a Box is a rectangular prism, etc. 00012 */ 00013 class Box 00014 { 00015 public: 00016 00017 /// Default constructor. 00018 /** 00019 The Box's upper and lower corner default to (-1,-1,...,-1) and (0,0,...,0) respectively. The default size is -1 (empty). 00020 */ 00021 Box(); 00022 00023 /// Constructor for nontrivial Box using two Points. 00024 Box(const Point& a_lowCorner, 00025 const Point& a_highCorner); 00026 00027 /// Copy constructor. 00028 Box(const Box& a_Box); 00029 00030 /// Computes the intersection of the Box with a_rightBox. Box AND operation. 00031 /** 00032 Returns a new Box which is the intersection of *this and *a_rightBox. *this is unchanged 00033 */ 00034 Box operator&(const Box& a_rightBox) const; 00035 00036 /// Computes intersection of Box and a_rightBox in place. 00037 /** 00038 Modifies *this to be the intersection of *this and a_rightBox. 00039 */ 00040 void operator&=(const Box& a_rightBox); 00041 00042 /// Computes shifted Box by a_offset in direction a_direction. 00043 /** 00044 Does not change *this. Returns the shifted box. 00045 */ 00046 Box shift(int a_direction, 00047 int a_offset) const; 00048 00049 /// Computes a Box shifted according to the vector a_pt 00050 /** 00051 Does not change *this. Returns the shifted box. Each point is shifted by adding a_pt. 00052 */ 00053 Box shift(const Point& a_pt) const; 00054 00055 /// Grow in all of the coordinate directions by a_numpoints. 00056 /** 00057 Does not change *this. Returns the grown box. Returned Box satisfies: m_upperCorner_new = m_upperCorner_old + getOnes()*a_numpoints, m_lowerCorner_new = m_lowerCorner_old - getOnes()*a_numpoints. 00058 */ 00059 Box grow(int a_numpoints) const; 00060 00061 /// Grow in each coordinate direction by an amount given by the component of a_pt. 00062 /** 00063 Does not change *this. Returns the grown box. Returned Box satisfies: m_upperCorner_new = m_upperCorner_old + a_pt, m_lowerCorner_new = m_lowerCorner_old - a_pt. 00064 */ 00065 Box grow(const Point& a_pt) const; 00066 00067 /// coarsen in all of the coordinate directions by a_numpoints. 00068 /** 00069 does not change *this. returns the coarsened box 00070 */ 00071 Box coarsen(int a_numpoints) const; 00072 00073 /// coarsen in each coordinate direction by an amount given by the component of a_pt. 00074 /** 00075 does not change *this. returns the coarsened box 00076 */ 00077 Box coarsen(const Point& a_pt) const; 00078 00079 /// refine in all of the coordinate directions by a_numpoints. 00080 /** 00081 does not change *this. returns the refined box 00082 */ 00083 Box refine(int a_numpoints) const; 00084 00085 /// refine in each coordinate direction by an amount given by the component of a_pt. 00086 /** 00087 does not change *this. returns the refined box 00088 */ 00089 Box refine(const Point& a_pt) const; 00090 00091 /// refine in each coordinate direction by an amount given by the component of a_pt. 00092 /** 00093 does not change *this. returns the refined box 00094 */ 00095 Box refineCC(const Point& a_pt) const; 00096 00097 // refine in all of the coordinate directions by a_numpoints. 00098 /** 00099 does not change *this. returns the refined box 00100 */ 00101 Box refineCC(int a_nref) const; 00102 00103 /// Access a Box's lowCorner. 00104 /** 00105 Called by a constant Box. Returned object cannot be changed. 00106 */ 00107 inline const Point& getLowCorner() const {return m_lowCorner;}; 00108 00109 /// Access a Box's highCorner. 00110 /** 00111 Called by a constant Box. Returned object cannot be changed. 00112 */ 00113 inline const Point& getHighCorner() const {return m_highCorner;}; 00114 00115 /// Access a Box's lowCorner. 00116 /** 00117 Called by a non-constant Box. Returned object can be changed. 00118 */ 00119 inline const Point& getLowCorner() {return m_lowCorner;}; 00120 00121 /// Access a Box's highCorner. 00122 /** 00123 Called by a non-constant Box. Returned object can be changed. 00124 */ 00125 inline const Point& getHighCorner() {return m_highCorner;}; 00126 00127 //REDUNDANT (and not called anywhere in the code) 00128 // /// Computes a linear index corresponding to the input array. \todo Needs implementation. 00129 // int linearIndex(const Point& a_pt) const; 00130 00131 /// Computes the size, or "volume", of the Box. 00132 const int& sizeOf() const{return m_size;}; 00133 00134 /// Defines equality between Boxes. 00135 /** 00136 Two Boxes are considered equal if they have identical (==) lowCorner and highCorner 00137 */ 00138 bool operator==(const Box& a_rhsBox) const 00139 {return ((m_lowCorner == a_rhsBox.m_lowCorner) 00140 && (m_highCorner == a_rhsBox.m_highCorner));}; 00141 00142 /// Checks if the Box contains the Point a_pt. 00143 bool contains(const Point& a_pt) const; 00144 00145 /// Checks if the Box contains another Box a_rhs. 00146 bool contains(const Box& a_rhs) const{ 00147 return this->contains(a_rhs.m_lowCorner) && this->contains(a_rhs.m_highCorner); 00148 } 00149 00150 // REDUNDANT 00151 //*************************************************************************************************************** 00152 // /// Checks if the Box contains another Box which is augmented by a_extent. 00153 // /** 00154 // This function will test if the Box with lowCorner = a_rhs.m_lowerCorner + a_extent.m_lowerCorner and highCorner = // a_rhs.m_highCorner + a_extent.m_highCorner resides within *this. \todo Determine the purpose of this function 00155 // */ 00156 // bool contains(const Box& a_rhs, const Box& a_extent) 00157 // { 00158 // return this->contains(a_rhs.m_lowCorner +a_extent.m_lowCorner) && 00159 // this->contains(a_rhs.m_highCorner+a_extent.m_highCorner); 00160 // } 00161 //*************************************************************************************************************** 00162 00163 // REDUNDANT 00164 //*************************************************************************************************************** 00165 // /// Checks if the Box contains the Point a_pt. 00166 // bool hasPoint(const Point& a_point) const; 00167 //*************************************************************************************************************** 00168 00169 /// Finds periodic image of input that is contained in the Box. 00170 Point mod(const Point& a_pt) const; 00171 00172 /// Get linear index of a Point in a Box. 00173 /** 00174 Indices have values from 0 to m_size-1. 00175 */ 00176 inline unsigned int getIndex(const Point& a_pt) const; 00177 00178 /// Returns false if a_pt(k) > m_highCorner(k) for k in [0,Dim) 00179 inline bool notDone(const Point& a_pt) const; 00180 00181 /// Returns the number of points that lie along a Box's edge in direction a_dim. 00182 /** 00183 This is a measure of the "edge length" of the Box. Note that the value returned is the number of points along the Box's edge, NOT m_highCorner[a_dim] - m_lowCorner[a_dim]. 00184 */ 00185 unsigned int size(unsigned char a_dim) const 00186 { 00187 return m_highCorner[a_dim]-m_lowCorner[a_dim] + 1; 00188 } 00189 00190 /// iteration through the points in a Box. a_pt is incremented to the next point in the Box. 00191 /** 00192 Currently, increment only works when DIM <= 3. When calling increment on m_highCorner, the resulting Point will no longer be inside *this (contains() will return FALSE). 00193 */ 00194 void increment(Point& a_pt) const; 00195 00196 /// Get Point corresponding to a linear index in [0, ... sizeOf()-1] inside the Box 00197 Point getPoint(unsigned int k) const; 00198 00199 /// Prints the Box to the command line. 00200 void print() const; 00201 00202 /// Returns True if the Box has non-positive "volume" 00203 bool isEmpty() const 00204 {bool ret = (m_size < 1); return ret;}; 00205 00206 private: 00207 void recomputeSize(); ///< Used to reevaluate the size of the box when it is changed. 00208 Point m_lowCorner; ///< Point object containing the lower bounds of the Box. 00209 Point m_highCorner; ///< Point object containing the upper bounds of the Box. 00210 int m_size; ///< "Volume" of the box. 00211 }; 00212 00213 /// Defines "<<" operator for Boxes. Used for printing. 00214 ostream& operator<<(ostream& os, const Box& a_box); 00215 00216 /////======================IMPLEMENTATION=============================///// 00217 00218 inline bool Box::notDone(const Point& a_pt) const 00219 { 00220 bool retval = true; 00221 for(int idir = 0; idir < DIM; idir++) 00222 { 00223 retval = retval && (a_pt[idir] <= m_highCorner[idir]); 00224 } 00225 return retval; 00226 } 00227 inline unsigned int Box::getIndex(const Point& a_pt) const 00228 { 00229 unsigned int factor = 1; 00230 unsigned int linIndex = a_pt[0] - m_lowCorner[0]; 00231 for (unsigned char i = 1;i < DIM;i++) 00232 { 00233 factor = factor*(m_highCorner[i-1] - m_lowCorner[i-1]+1); 00234 linIndex = linIndex + (a_pt[i] - m_lowCorner[i])*factor; 00235 } 00236 return linIndex; 00237 }; 00238 inline int mymod(int i,int j) 00239 { 00240 if (i < 0) 00241 { 00242 int k = (-1-i)%j; 00243 return j-1-k; 00244 } 00245 else 00246 { 00247 return i%j; 00248 } 00249 }; 00250 void printPoint(const Point& a_pt); 00251 #endif