mortonid.txx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  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, uint8_t 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, uint8_t 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, uint8_t 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. if(i<0) i=0;
  53. m.depth=(uint8_t)i;
  54. return m;
  55. }
  56. inline MortonId MortonId::getAncestor(uint8_t ancestor_level) const{
  57. MortonId m=*this;
  58. m.depth=ancestor_level;
  59. UINT_T mask=(((UINT_T)1)<<(MAX_DEPTH))-(((UINT_T)1)<<(MAX_DEPTH-ancestor_level));
  60. m.x=(m.x & mask);
  61. m.y=(m.y & mask);
  62. m.z=(m.z & mask);
  63. return m;
  64. }
  65. inline MortonId MortonId::getDFD(uint8_t level) const{
  66. MortonId m=*this;
  67. m.depth=level;
  68. return m;
  69. }
  70. inline int MortonId::operator<(const MortonId& m) const{
  71. if(x==m.x && y==m.y && z==m.z) return depth<m.depth;
  72. UINT_T x_=(x^m.x);
  73. UINT_T y_=(y^m.y);
  74. UINT_T z_=(z^m.z);
  75. if((z_>x_ || ((z_^x_)<x_ && (z_^x_)<z_)) && (z_>y_ || ((z_^y_)<y_ && (z_^y_)<z_)))
  76. return z<m.z;
  77. if(y_>x_ || ((y_^x_)<x_ && (y_^x_)<y_))
  78. return y<m.y;
  79. return x<m.x;
  80. }
  81. inline int MortonId::operator>(const MortonId& m) const{
  82. if(x==m.x && y==m.y && z==m.z) return depth>m.depth;
  83. UINT_T x_=(x^m.x);
  84. UINT_T y_=(y^m.y);
  85. UINT_T z_=(z^m.z);
  86. if((z_>x_ || ((z_^x_)<x_ && (z_^x_)<z_)) && (z_>y_ || ((z_^y_)<y_ && (z_^y_)<z_)))
  87. return z>m.z;
  88. if((y_>x_ || ((y_^x_)<x_ && (y_^x_)<y_)))
  89. return y>m.y;
  90. return x>m.x;
  91. }
  92. inline int MortonId::operator==(const MortonId& m) const{
  93. return (x==m.x && y==m.y && z==m.z && depth==m.depth);
  94. }
  95. inline int MortonId::operator!=(const MortonId& m) const{
  96. return !(*this==m);
  97. }
  98. inline int MortonId::operator<=(const MortonId& m) const{
  99. return !(*this>m);
  100. }
  101. inline int MortonId::operator>=(const MortonId& m) const{
  102. return !(*this<m);
  103. }
  104. inline int MortonId::isAncestor(MortonId const & other) const {
  105. return other.depth>depth && other.getAncestor(depth)==*this;
  106. }
  107. }//end namespace