DGtal  0.6.devel
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Morton.ih
1 
30 
31 // Inclusions
32 #include <iostream>
33 #include "DGtal/images/Morton.h"
35 
36 namespace DGtal
37  {
38 
39  template <typename HashKey, typename Point >
41  {
42  // @todo precomputation of the dilate masks
43  //myDilateMasks[0] = 25;
44  }
45 
46 
47  template <typename HashKey, typename Point >
48  void Morton<HashKey,Point>:: interleaveBits ( const Point & aPoint, HashKey & output ) const
49  {
50  //number of bits of the input integers (casted according to the hashkeysize)
51  // max of this with sizeof(Coordinate)*8
52  unsigned int coordSize = ( sizeof ( HashKey ) <<3 ) / dimension;
53 
54  output = 0;
55  for ( unsigned int i = 0; i < coordSize; ++i )
56  for ( unsigned int n = 0; n < dimension; ++n )
57  {
58  if ( ( aPoint[n] ) & ( static_cast<Coordinate> ( 1 ) << i ) )
59  output |= static_cast<Coordinate> ( 1 ) << (( i*dimension ) +n);
60  }
61  }
62 
63 
64  template <typename HashKey, typename Point >
65  HashKey Morton<HashKey,Point>::keyFromCoordinates ( const std::size_t treeDepth,
66  const Point & coordinates ) const
67  {
68  HashKey result = 0;
69 
70  interleaveBits ( coordinates, result );
71  // by convention, the root node has the key 0..01
72  // it makes it easy to determine the depth of a node by it's key (looking
73  // at the position of the most significant bit that is equal to 1)
74  result |= ( static_cast<HashKey> ( 1 ) << dimension*treeDepth );
75 
76  return result;
77  }
78 
79 
80 
81  template <typename HashKey, typename Point >
82  void Morton<HashKey,Point>::childrenKeys ( const HashKey key, HashKey* result ) const
83  {
84  HashKey keycopy = key;
85 
86  keycopy <<= dimension;
87  //generate a mask of the form 1..111000 with dimension "0"
88  HashKey mask = ( static_cast<HashKey> ( ~0 ) << dimension );
89  for ( std::size_t i = 0;
90  i < POW<2,dimension>::VALUE;
91  ++i )
92  {
93  result[i] = ( keycopy & mask ) |i;
94  }
95  }
96 
97  template <typename HashKey, typename Point >
98  void Morton<HashKey,Point>::brotherKeys ( const HashKey key, HashKey* result ) const
99  {
100  //generate a mask of the form 1..111000 with dimension "0"
101  HashKey mask = ( static_cast<HashKey> ( ~0 ) << dimension );
102  std::size_t j = 0;
103  for ( std::size_t i = 0; i < POW<2,dimension>::VALUE; ++i )
104  {
105  HashKey key2 = ( key & mask ) |i;
106  if ( key2 != key )
107  {
108  result[j] = key2;
109  ++j;
110  }
111  }
112  }
113 
114  template <typename HashKey, typename Point >
115  void Morton<HashKey,Point>::coordinatesFromKey ( const HashKey key, Point & coordinates ) const
116  {
117  HashKey akey = key;
118  //remove the first bit equal 1
119  for ( int i = ( sizeof ( HashKey ) <<3 )-1; i >= 0; --i )
120  if ( akey & Bits::mask<HashKey> ( i ) )
121  {
122  akey &= ~Bits::mask<HashKey> ( i );
123  break;
124  }
125 
126  //deinterleave the bits
127  for ( std::size_t i = 0; i < dimension; ++i )
128  {
129  coordinates[(Dimension)i] = 0;
130 
131  for ( std::size_t bitPos = 0; bitPos < ( sizeof ( HashKey ) <<3 ) / dimension; ++bitPos )
132  {
133  if ( akey & Bits::mask<HashKey> ( (unsigned int)(bitPos*dimension+i) ) )
134  {
135  coordinates[(Dimension)i] |= Bits::mask<HashKey> ( (unsigned int)bitPos );
136  }
137  }
138  }
139  }
140 
141 }