node_geometry.h
Go to the documentation of this file.
00001 #ifndef MEGATREE_NODE_GEOMETRY_H
00002 #define MEGATREE_NODE_GEOMETRY_H
00003 
00004 #include <megatree/tree_common.h>
00005 #include <assert.h>
00006 #include <vector>
00007 
00008 
00009 namespace megatree
00010 {
00011 
00012 class NodeGeometry
00013 {
00014 public:
00015   NodeGeometry()
00016   {}
00017 
00018   NodeGeometry(const std::vector<double>& tree_center, double tree_size)
00019     : level(1)
00020   {
00021     assert(tree_center.size() == 3);
00022     for (int i = 0; i < 3; ++i) {
00023       lo[i] = tree_center[i] - tree_size / 2.0;
00024       hi[i] = tree_center[i] + tree_size / 2.0;
00025     }
00026   }
00027 
00028   NodeGeometry(const double tree_center[3], double tree_size)
00029     : level(1)
00030   {
00031     for (int i = 0; i < 3; ++i) {
00032       lo[i] = tree_center[i] - tree_size / 2.0;
00033       hi[i] = tree_center[i] + tree_size / 2.0;
00034     }
00035   }
00036   NodeGeometry(int _level, const double _lo[3], const double _hi[3])
00037     : level(_level)
00038   {
00039     lo[0] = _lo[0];  lo[1] = _lo[1];  lo[2] = _lo[2];
00040     hi[0] = _hi[0];  hi[1] = _hi[1];  hi[2] = _hi[2];
00041   }
00042 
00043   NodeGeometry(const NodeGeometry& ng)
00044   {
00045     lo[0] = ng.lo[0];  lo[1] = ng.lo[1];  lo[2] = ng.lo[2];
00046     hi[0] = ng.hi[0];  hi[1] = ng.hi[1];  hi[2] = ng.hi[2];
00047     level = ng.level;
00048   }
00049 
00050 
00051   // Fills the child NodeGeometry of child number 'to_child'
00052   NodeGeometry getChild(uint8_t to_child) const
00053   {
00054     NodeGeometry res;
00055     res.level = level + 1;
00056     
00057     double mid[] = {(lo[0] + hi[0]) / 2.0,
00058                     (lo[1] + hi[1]) / 2.0,
00059                     (lo[2] + hi[2]) / 2.0 };
00060 
00061     res.lo[0] = (to_child & (1 << X_BIT)) ? mid[0] : lo[0];
00062     res.hi[0] = (to_child & (1 << X_BIT)) ? hi[0]  : mid[0];
00063     res.lo[1] = (to_child & (1 << Y_BIT)) ? mid[1] : lo[1];
00064     res.hi[1] = (to_child & (1 << Y_BIT)) ? hi[1]  : mid[1];
00065     res.lo[2] = (to_child & (1 << Z_BIT)) ? mid[2] : lo[2];
00066     res.hi[2] = (to_child & (1 << Z_BIT)) ? hi[2]  : mid[2];
00067 
00068     return res;
00069   }
00070 
00071 
00072   // Fills the parent NodeGeometry, given that this NodeGeometry is
00073   // child 'from_child' of the parent.  This method may give
00074   // "incorrect" results because of floating point rounding error (in
00075   // other words,  `ng.getChild(0).getParent(0) == ng` may be false).
00076   NodeGeometry getParent(uint8_t from_child) const
00077   {
00078     NodeGeometry res;
00079     assert(level > 0);
00080     
00081     res.level = level - 1;
00082 
00083     double s[] = {hi[0] - lo[0], hi[1] - lo[1], hi[2] - lo[2]};
00084     
00085     res.lo[0] = (from_child & (1 << X_BIT)) ? lo[0] - s[0] : lo[0];
00086     res.hi[0] = (from_child & (1 << X_BIT)) ? hi[0]        : hi[0] + s[0];
00087     res.lo[1] = (from_child & (1 << Y_BIT)) ? lo[1] - s[1] : lo[1];
00088     res.hi[1] = (from_child & (1 << Y_BIT)) ? hi[1]        : hi[1] + s[1];
00089     res.lo[2] = (from_child & (1 << Z_BIT)) ? lo[2] - s[2] : lo[2];
00090     res.hi[2] = (from_child & (1 << Z_BIT)) ? hi[2]        : hi[2] + s[2];
00091 
00092     return res;
00093   }
00094 
00095 
00096   // Returns which child of this NodeGeometry would contain pnt.
00097   uint8_t whichChild(const double pnt[3]) const
00098   {
00099     double center[] = {(lo[0] + hi[0]) / 2.0,
00100                        (lo[1] + hi[1]) / 2.0,
00101                        (lo[2] + hi[2]) / 2.0 };
00102     return  (pnt[0] >= center[0]) << X_BIT | 
00103             (pnt[1] >= center[1]) << Y_BIT | 
00104             (pnt[2] >= center[2]) << Z_BIT;
00105   }
00106 
00107 
00108   // Returns the edge length of the node cell
00109   double getSize() const
00110   {
00111     return hi[0] - lo[0];
00112   }
00113   double getCenter(int i) const
00114   {
00115     return (hi[i] + lo[i]) / 2.0;
00116   }
00117 
00118   double getLo(int i) const { return lo[i]; }
00119   double getHi(int i) const { return hi[i]; }
00120 
00121   // Checks if a point is inside the bounds of the node geometry
00122   bool contains(const double pt[3]) const { return contains(pt[0], pt[1], pt[2]); }
00123   bool contains(const std::vector<double> &pt) const { return contains(pt[0], pt[1], pt[2]); }
00124   bool contains(double x, double y, double z) const
00125   {
00126     return
00127       lo[0] <= x && x < hi[0] &&
00128       lo[1] <= y && y < hi[1] &&
00129       lo[2] <= z && z < hi[2];
00130   }
00131 
00132   NodeGeometry& operator=(const NodeGeometry& ng)
00133   {
00134     level = ng.level;
00135     lo[0] = ng.lo[0];  lo[1] = ng.lo[1];  lo[2] = ng.lo[2];
00136     hi[0] = ng.hi[0];  hi[1] = ng.hi[1];  hi[2] = ng.hi[2];
00137     return *this;
00138   }
00139 
00140   unsigned int getLevel() const { return level; }
00141 
00142 private:
00143   double lo[3], hi[3];  // Minimum point and maximum point of this cell
00144   unsigned int level;
00145 };
00146 
00147 }
00148 
00149 #endif


megatree_core
Author(s): Stuart Glaser
autogenerated on Thu Nov 28 2013 11:30:23