mortonid.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. /**
  2. * \file mortonid.cpp
  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 <mortonid.hpp>
  8. #include <iostream>
  9. #include <cstdlib>
  10. #include <cmath>
  11. namespace pvfmm{
  12. void MortonId::NbrList(std::vector<MortonId>& nbrs, uint8_t level, int periodic) const{
  13. nbrs.clear();
  14. static int dim=3;
  15. static int nbr_cnt=(int)(pow(3.0,dim)+0.5);
  16. static UINT_T maxCoord=(((UINT_T)1)<<(MAX_DEPTH));
  17. UINT_T mask=maxCoord-(((UINT_T)1)<<(MAX_DEPTH-level));
  18. UINT_T pX=x & mask;
  19. UINT_T pY=y & mask;
  20. UINT_T pZ=z & mask;
  21. MortonId mid_tmp;
  22. mask=(((UINT_T)1)<<(MAX_DEPTH-level));
  23. for(int i=0; i<nbr_cnt; i++){
  24. INT_T dX = ((i/1)%3-1)*mask;
  25. INT_T dY = ((i/3)%3-1)*mask;
  26. INT_T dZ = ((i/9)%3-1)*mask;
  27. INT_T newX=(INT_T)pX+dX;
  28. INT_T newY=(INT_T)pY+dY;
  29. INT_T newZ=(INT_T)pZ+dZ;
  30. if(!periodic){
  31. if(newX>=0 && newX<(INT_T)maxCoord)
  32. if(newY>=0 && newY<(INT_T)maxCoord)
  33. if(newZ>=0 && newZ<(INT_T)maxCoord){
  34. mid_tmp.x=newX; mid_tmp.y=newY; mid_tmp.z=newZ;
  35. mid_tmp.depth=level;
  36. nbrs.push_back(mid_tmp);
  37. }
  38. }else{
  39. if(newX<0) newX+=maxCoord; if(newX>=(INT_T)maxCoord) newX-=maxCoord;
  40. if(newY<0) newY+=maxCoord; if(newY>=(INT_T)maxCoord) newY-=maxCoord;
  41. if(newZ<0) newZ+=maxCoord; if(newZ>=(INT_T)maxCoord) newZ-=maxCoord;
  42. mid_tmp.x=newX; mid_tmp.y=newY; mid_tmp.z=newZ;
  43. mid_tmp.depth=level;
  44. nbrs.push_back(mid_tmp);
  45. }
  46. }
  47. }
  48. std::vector<MortonId> MortonId::Children() const{
  49. static int dim=3;
  50. static int c_cnt=(1UL<<dim);
  51. static UINT_T maxCoord=(((UINT_T)1)<<(MAX_DEPTH));
  52. std::vector<MortonId> child(c_cnt);
  53. UINT_T mask=maxCoord-(((UINT_T)1)<<(MAX_DEPTH-depth));
  54. UINT_T pX=x & mask;
  55. UINT_T pY=y & mask;
  56. UINT_T pZ=z & mask;
  57. mask=(((UINT_T)1)<<(MAX_DEPTH-(depth+1)));
  58. for(int i=0; i<c_cnt; i++){
  59. child[i].x=pX+mask*((i/1)%2);
  60. child[i].y=pY+mask*((i/2)%2);
  61. child[i].z=pZ+mask*((i/4)%2);
  62. child[i].depth=(uint8_t)(depth+1);
  63. }
  64. return child;
  65. }
  66. std::ostream& operator<<(std::ostream& out, const MortonId & mid){
  67. double a=0;
  68. double s=1;
  69. for(int i=MAX_DEPTH;i>=0;i--){
  70. s=s*0.5; if(mid.z & (((UINT_T)1)<<i)) a+=s;
  71. s=s*0.5; if(mid.y & (((UINT_T)1)<<i)) a+=s;
  72. s=s*0.5; if(mid.x & (((UINT_T)1)<<i)) a+=s;
  73. }
  74. out<<"("<<(size_t)mid.x<<","<<(size_t)mid.y<<","<<(size_t)mid.z<<" - "<<a<<")";
  75. return out;
  76. }
  77. }//end namespace