mortonid.txx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /**
  2. * \file mortonid.txx
  3. * \author Dhairya Malhotra, dhairya.malhotra@gmail.com
  4. * \date 2-11-2011
  5. * \brief This file contains implementation of the class MortonId.
  6. */
  7. namespace pvfmm{
  8. inline MortonId::MortonId():x(0), y(0), z(0), depth(0){}
  9. inline MortonId::MortonId(MortonId m, unsigned char depth_):x(m.x), y(m.y), z(m.z), depth(depth_){}
  10. template <class T>
  11. inline MortonId::MortonId(T x_f,T y_f, T z_f, unsigned char depth_): depth(depth_){
  12. UINT_T max_int=((UINT_T)1)<<(MAX_DEPTH);
  13. x=(UINT_T)floor(x_f*max_int);
  14. y=(UINT_T)floor(y_f*max_int);
  15. z=(UINT_T)floor(z_f*max_int);
  16. }
  17. template <class T>
  18. inline MortonId::MortonId(T* coord, unsigned char depth_): depth(depth_){
  19. UINT_T max_int=((UINT_T)1)<<(MAX_DEPTH);
  20. x=(UINT_T)floor(coord[0]*max_int);
  21. y=(UINT_T)floor(coord[1]*max_int);
  22. z=(UINT_T)floor(coord[2]*max_int);
  23. }
  24. template <class T>
  25. inline void MortonId::GetCoord(T* coord){
  26. UINT_T max_int=((UINT_T)1)<<(MAX_DEPTH);
  27. T s=1.0/((T)max_int);
  28. coord[0]=x*s;
  29. coord[1]=y*s;
  30. coord[2]=z*s;
  31. }
  32. inline unsigned int MortonId::GetDepth() const{
  33. return depth;
  34. }
  35. inline MortonId MortonId::NextId() const{
  36. MortonId m=*this;
  37. UINT_T mask=((UINT_T)1)<<(MAX_DEPTH-depth);
  38. int i;
  39. for(i=depth;i>=0;i--){
  40. m.x=(m.x^mask);
  41. if((m.x & mask))
  42. break;
  43. m.y=(m.y^mask);
  44. if((m.y & mask))
  45. break;
  46. m.z=(m.z^mask);
  47. if((m.z & mask))
  48. break;
  49. mask=(mask<<1);
  50. }
  51. m.depth=i;
  52. return m;
  53. }
  54. inline MortonId MortonId::getAncestor(unsigned char ancestor_level) const{
  55. MortonId m=*this;
  56. m.depth=ancestor_level;
  57. UINT_T mask=(((UINT_T)1)<<(MAX_DEPTH))-(((UINT_T)1)<<(MAX_DEPTH-ancestor_level));
  58. m.x=(m.x & mask);
  59. m.y=(m.y & mask);
  60. m.z=(m.z & mask);
  61. return m;
  62. }
  63. inline MortonId MortonId::getDFD(unsigned char level) const{
  64. MortonId m=*this;
  65. m.depth=level;
  66. return m;
  67. }
  68. inline int MortonId::operator<(const MortonId& m) const{
  69. if(x==m.x && y==m.y && z==m.z) return depth<m.depth;
  70. UINT_T x_=(x^m.x);
  71. UINT_T y_=(y^m.y);
  72. UINT_T z_=(z^m.z);
  73. if((z_>x_ || ((z_^x_)<x_ && (z_^x_)<z_)) && (z_>y_ || ((z_^y_)<y_ && (z_^y_)<z_)))
  74. return z<m.z;
  75. if(y_>x_ || ((y_^x_)<x_ && (y_^x_)<y_))
  76. return y<m.y;
  77. return x<m.x;
  78. }
  79. inline int MortonId::operator>(const MortonId& m) const{
  80. if(x==m.x && y==m.y && z==m.z) return depth>m.depth;
  81. UINT_T x_=(x^m.x);
  82. UINT_T y_=(y^m.y);
  83. UINT_T z_=(z^m.z);
  84. if((z_>x_ || ((z_^x_)<x_ && (z_^x_)<z_)) && (z_>y_ || ((z_^y_)<y_ && (z_^y_)<z_)))
  85. return z>m.z;
  86. if((y_>x_ || ((y_^x_)<x_ && (y_^x_)<y_)))
  87. return y>m.y;
  88. return x>m.x;
  89. }
  90. inline int MortonId::operator==(const MortonId& m) const{
  91. return (x==m.x && y==m.y && z==m.z && depth==m.depth);
  92. }
  93. inline int MortonId::operator!=(const MortonId& m) const{
  94. return !(*this==m);
  95. }
  96. inline int MortonId::operator<=(const MortonId& m) const{
  97. return !(*this>m);
  98. }
  99. inline int MortonId::operator>=(const MortonId& m) const{
  100. return !(*this<m);
  101. }
  102. inline int MortonId::isAncestor(MortonId const & other) const {
  103. return other.depth>depth && other.getAncestor(depth)==*this;
  104. }
  105. }//end namespace