mortonid.txx 3.5 KB

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