关于莫顿编码计算过程

关于摩顿编码的计算

莫顿码的基本原理

莫顿码是一种将多维空间中的点坐标用一个一维的数值来表示,
通过利用莫顿编码的方式来讲空间中点所对应的空间关系用莫顿码值之间的相邻关系来近似表示。

莫顿编码的计算方式

 1.通过依次对多维空间中的点进行“迭代交叉计算”;
 2.通过利用查询表来计算对应的莫顿码;   
 在本篇博客中,我增添了对于二维几何和三维几何坐标所对应的莫顿码值的整个过程。
 一种是通过依次进行迭代计算多维空间中点对应的莫顿码,这种方法比较容易理解,但是相对
 查询表的计算复杂度相对较低。
 特别注意的是,在查询表的计算过程中,每个点所对应的莫顿码的查询表的计算过程
 应该与点所对应的几何精度相关。下面,我主要分为两部分来讲,
 一种是关于依次进行迭代计算莫顿码,另外一种是基于查询表来计算的。

基于点坐标的依次迭代计算

下面分别是二维几何坐标和三维几何坐标分别对应的莫顿码计算过程:

//二维几何坐标对应莫顿码的计算过程
//我们将attr_aps.raht_depth设置为24,也就是最大的几何坐标的几何精度
 for (int n = 0; n < voxelCount; n++) {
      const auto position = inputPointCloud[n];
      int x = int(position[0]);
      int y = int(position[1]);
      int z = int(position[2]);de
      long long mortonCode = 0;
      for (int b = 0; b < attr_aps.raht_depth; b++) {
        mortonCode|= (long long)((x >> b) & 1) << (2 * b + 1);
        mortonCode|= (long long)((y >> b) & 1) << (2 * b);
      }
}
//三维几何坐标对应莫顿码的计算过程
for (int n = 0; n < voxelCount; n++) {
      const auto position = inputPointCloud[n];
      int x = int(position[0]);
      int y = int(position[1]);
      int z = int(position[2]);de
      long long mortonCode = 0;
      for (int b = 0; b < attr_aps.raht_depth; b++) {
        mortonCode|= (long long)((x >> b) & 1) << (3 * b + 2);
        mortonCode|= (long long)((y >> b) & 1) << (3 * b + 1);
        mortonCode|= (long long)((z >> b) & 1) << (3 * b);
      }
}

在这里要特别注意的是,上面二维坐标的莫顿码编码顺序为yx,
三维坐标的莫顿码的编码顺序为zyx,也就是说莫顿码的编码顺序是按照由低位到高位的顺 序进行编码。但是莫顿编码的交叉顺序是按照由高位到低位的顺序,也就是二维的莫顿编码的交叉编码顺序为xy,三维莫顿编码的顺序是xyz.

基于莫顿查询表进行计算莫顿码

如下表所示,我们将分别计算二维坐标对应的莫顿码和三维坐标的莫顿码。

//二维莫顿码查询表
const uint32_t pcc::kMortonCode256_twoDimensions[256] = {
  0x00000000, 0x00000001, 0x00000004, 0x00000005, 0x00000010, 0x00000011,
  0x00000014, 0x00000015, 0x00000040, 0x00000041, 0x00000044, 0x00000045,
  0x00000050, 0x00000051, 0x00000054, 0x00000055, 0x00000100, 0x00000101,
  0x00000104, 0x00000105, 0x00000110, 0x00000111, 0x00000114, 0x00000115,
  0x00000140, 0x00000141, 0x00000144, 0x00000145, 0x00000150, 0x00000151,
  0x00000154, 0x00000155, 0x00000400, 0x00000401, 0x00000404, 0x00000405,
  0x00000410, 0x00000411, 0x00000414, 0x00000415, 0x00000440, 0x00000441,
  0x00000444, 0x00000445, 0x00000450, 0x00000451, 0x00000454, 0x00000455,
  0x00000500, 0x00000501, 0x00000504, 0x00000505, 0x00000510, 0x00000511,
  0x00000514, 0x00000515, 0x00000540, 0x00000541, 0x00000544, 0x00000545,
  0x00000550, 0x00000551, 0x00000554, 0x00000555, 0x00001000, 0x00001001,
  0x00001004, 0x00001005, 0x00001010, 0x00001011, 0x00001014, 0x00001015,
  0x00001040, 0x00001041, 0x00001044, 0x00001045, 0x00001050, 0x00001051,
  0x00001054, 0x00001055, 0x00001100, 0x00001101, 0x00001104, 0x00001105,
  0x00001110, 0x00001111, 0x00001114, 0x00001115, 0x00001140, 0x00001141,
  0x00001144, 0x00001145, 0x00001150, 0x00001151, 0x00001154, 0x00001155,
  0x00001400, 0x00001401, 0x00001404, 0x00001405, 0x00001410, 0x00001411,
  0x00001414, 0x00001415, 0x00001440, 0x00001441, 0x00001444, 0x00001445,
  0x00001450, 0x00001451, 0x00001454, 0x00001455, 0x00001500, 0x00001501,
  0x00001504, 0x00001505, 0x00001510, 0x00001511, 0x00001514, 0x00001515,
  0x00001540, 0x00001541, 0x00001544, 0x00001545, 0x00001550, 0x00001551,
  0x00001554, 0x00001555, 0x00004000, 0x00004001, 0x00004004, 0x00004005,
  0x00004010, 0x00004011, 0x00004014, 0x00004015, 0x00004040, 0x00004041,
  0x00004044, 0x00004045, 0x00004050, 0x00004051, 0x00004054, 0x00004055,
  0x00004100, 0x00004101, 0x00004104, 0x00004105, 0x00004110, 0x00004111,
  0x00004114, 0x00004115, 0x00004140, 0x00004141, 0x00004144, 0x00004145,
  0x00004150, 0x00004151, 0x00004154, 0x00004155, 0x00004400, 0x00004401,
  0x00004404, 0x00004405, 0x00004410, 0x00004411, 0x00004414, 0x00004415,
  0x00004440, 0x00004441, 0x00004444, 0x00004445, 0x00004450, 0x00004451,
  0x00004454, 0x00004455, 0x00004500, 0x00004501, 0x00004504, 0x00004505,
  0x00004510, 0x00004511, 0x00004514, 0x00004515, 0x00004540, 0x00004541,
  0x00004544, 0x00004545, 0x00004550, 0x00004551, 0x00004554, 0x00004555,
  0x00005000, 0x00005001, 0x00005004, 0x00005005, 0x00005010, 0x00005011,
  0x00005014, 0x00005015, 0x00005040, 0x00005041, 0x00005044, 0x00005045,
  0x00005050, 0x00005051, 0x00005054, 0x00005055, 0x00005100, 0x00005101,
  0x00005104, 0x00005105, 0x00005110, 0x00005111, 0x00005114, 0x00005115,
  0x00005140, 0x00005141, 0x00005144, 0x00005145, 0x00005150, 0x00005151,
  0x00005154, 0x00005155, 0x00005400, 0x00005401, 0x00005404, 0x00005405,
  0x00005410, 0x00005411, 0x00005414, 0x00005415, 0x00005440, 0x00005441,
  0x00005444, 0x00005445, 0x00005450, 0x00005451, 0x00005454, 0x00005455,
  0x00005500, 0x00005501, 0x00005504, 0x00005505, 0x00005510, 0x00005511,
  0x00005514, 0x00005515, 0x00005540, 0x00005541, 0x00005544, 0x00005545,
  0x00005550, 0x00005551, 0x00005554, 0x00005555};
  //三维莫顿码查询表
  const uint32_t pcc::kMortonCode256_threeDimensions[256] = {
  0x00000000, 0x00000001, 0x00000008, 0x00000009, 0x00000040, 0x00000041,
  0x00000048, 0x00000049, 0x00000200, 0x00000201, 0x00000208, 0x00000209,
  0x00000240, 0x00000241, 0x00000248, 0x00000249, 0x00001000, 0x00001001,
  0x00001008, 0x00001009, 0x00001040, 0x00001041, 0x00001048, 0x00001049,
  0x00001200, 0x00001201, 0x00001208, 0x00001209, 0x00001240, 0x00001241,
  0x00001248, 0x00001249, 0x00008000, 0x00008001, 0x00008008, 0x00008009,
  0x00008040, 0x00008041, 0x00008048, 0x00008049, 0x00008200, 0x00008201,
  0x00008208, 0x00008209, 0x00008240, 0x00008241, 0x00008248, 0x00008249,
  0x00009000, 0x00009001, 0x00009008, 0x00009009, 0x00009040, 0x00009041,
  0x00009048, 0x00009049, 0x00009200, 0x00009201, 0x00009208, 0x00009209,
  0x00009240, 0x00009241, 0x00009248, 0x00009249, 0x00040000, 0x00040001,
  0x00040008, 0x00040009, 0x00040040, 0x00040041, 0x00040048, 0x00040049,
  0x00040200, 0x00040201, 0x00040208, 0x00040209, 0x00040240, 0x00040241,
  0x00040248, 0x00040249, 0x00041000, 0x00041001, 0x00041008, 0x00041009,
  0x00041040, 0x00041041, 0x00041048, 0x00041049, 0x00041200, 0x00041201,
  0x00041208, 0x00041209, 0x00041240, 0x00041241, 0x00041248, 0x00041249,
  0x00048000, 0x00048001, 0x00048008, 0x00048009, 0x00048040, 0x00048041,
  0x00048048, 0x00048049, 0x00048200, 0x00048201, 0x00048208, 0x00048209,
  0x00048240, 0x00048241, 0x00048248, 0x00048249, 0x00049000, 0x00049001,
  0x00049008, 0x00049009, 0x00049040, 0x00049041, 0x00049048, 0x00049049,
  0x00049200, 0x00049201, 0x00049208, 0x00049209, 0x00049240, 0x00049241,
  0x00049248, 0x00049249, 0x00200000, 0x00200001, 0x00200008, 0x00200009,
  0x00200040, 0x00200041, 0x00200048, 0x00200049, 0x00200200, 0x00200201,
  0x00200208, 0x00200209, 0x00200240, 0x00200241, 0x00200248, 0x00200249,
  0x00201000, 0x00201001, 0x00201008, 0x00201009, 0x00201040, 0x00201041,
  0x00201048, 0x00201049, 0x00201200, 0x00201201, 0x00201208, 0x00201209,
  0x00201240, 0x00201241, 0x00201248, 0x00201249, 0x00208000, 0x00208001,
  0x00208008, 0x00208009, 0x00208040, 0x00208041, 0x00208048, 0x00208049,
  0x00208200, 0x00208201, 0x00208208, 0x00208209, 0x00208240, 0x00208241,
  0x00208248, 0x00208249, 0x00209000, 0x00209001, 0x00209008, 0x00209009,
  0x00209040, 0x00209041, 0x00209048, 0x00209049, 0x00209200, 0x00209201,
  0x00209208, 0x00209209, 0x00209240, 0x00209241, 0x00209248, 0x00209249,
  0x00240000, 0x00240001, 0x00240008, 0x00240009, 0x00240040, 0x00240041,
  0x00240048, 0x00240049, 0x00240200, 0x00240201, 0x00240208, 0x00240209,
  0x00240240, 0x00240241, 0x00240248, 0x00240249, 0x00241000, 0x00241001,
  0x00241008, 0x00241009, 0x00241040, 0x00241041, 0x00241048, 0x00241049,
  0x00241200, 0x00241201, 0x00241208, 0x00241209, 0x00241240, 0x00241241,
  0x00241248, 0x00241249, 0x00248000, 0x00248001, 0x00248008, 0x00248009,
  0x00248040, 0x00248041, 0x00248048, 0x00248049, 0x00248200, 0x00248201,
  0x00248208, 0x00248209, 0x00248240, 0x00248241, 0x00248248, 0x00248249,
  0x00249000, 0x00249001, 0x00249008, 0x00249009, 0x00249040, 0x00249041,
  0x00249048, 0x00249049, 0x00249200, 0x00249201, 0x00249208, 0x00249209,
  0x00249240, 0x00249241, 0x00249248, 0x00249249};

我们的计算会基于这个kMortonCode256【256】的这个查询表来计算对应的莫顿码,其基本原理是每次只处理一个数值的8位,也就是最大为256,后续依次进行按照该查询表中的内容进行计算。
二维莫顿码的计算(在这里我们的几何坐标最大数值为24bit):

//注意:在这里我们将x放在莫顿码的高位,y放在莫顿码的低位
for (int n = 0; n < voxelCount; n++) {
      const auto position = inputPointCloud[n];
      int x = int(position[0]);
      int y = int(position[1]);
      int z = int(position[2]);
      long long mortonCode = 0;
      mortonCode =kMortonCode256_twoDimensions[(x >> 16) & 0xFF]<<1 |
                  kMortonCode256_twoDimensions[(y >> 16) & 0xFF];
      mortonCode = mortonCode << 16 |
                   kMortonCode256_twoDimensions[(x >> 8) & 0xFF]<<1|
                   kMortonCode256_twoDimensions[(y >> 8) & 0xFF];
      mortonCode =mortonCode << 16 |
                  kMortonCode256_twoDimensions[x & 0xFF]<<1|
                  kMortonCode256_twoDimensions[y & 0xFF];
}

三维莫顿码的查询表计算过程

//注意在这里我们按照xyz由高到低的顺序进行莫顿编码
for (int n = 0; n < voxelCount; n++) {
      const auto position = inputPointCloud[n];
      int x = int(position[0]);
      int y = int(position[1]);
      int z = int(position[2]);
      long long mortonCode = 0;
      mortonCode = kMortonCode256_threeDimensions[(x >> 16) & 0xFF]<<2|
                   kMortonCode256_threeDimensions[(y >> 16) & 0xFF]<<1|
                   kMortonCode256_threeDimensions[(z >> 16) & 0xFF];
      mortonCode =mortonCode<< 24 |
                   kMortonCode256_threeDimensions[(x >> 8) & 0xFF]<<2|
                   kMortonCode256_threeDimensions[(y >> 8) & 0xFF]<<1| 
                   kMortonCode256_threeDimensions[(z >> 8) & 0xFF];
      mortonCode = mortonCode << 24 |
                   kMortonCode256_threeDimensions[x & 0xFF]<<2|
                   kMortonCode256_threeDimensions[y & 0xFF]|<<1
                   kMortonCode256_threeDimensions[z & 0xFF];
}

上面就是我们在分别计算二维坐标的莫顿码或者三维坐标的莫顿码时,两种不同计算的方式,依次进行迭代的计算过程相对容易理解,但是计算复杂度相对较高,而莫顿码查询表的计算方式相对较快,但是莫顿码查询表必须知道坐标的最大值,也就是所有坐标的最大几何精度,否则其计算的结果是有问题的。
比如我们上面计算的最大几何坐标的精度为24bit,一旦有超过24bit精度的数值,那么基于查询表计算得到的莫顿码就会出错。

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值