mortonid.txx 3.0 KB

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