1

我正在尝试使用 Morton 代码为给定的 (x,y,z) 生成唯一编码,其中 x,y,z 是双精度浮点数。我假设我可以使用类型转换将浮点数转换为整数并对这些整数运行 Morton 排序。例如考虑以下C++代码。(我现在不知道如何做同样的事情C

double x=-1.123456789123456E205;
int64_t i = reinterpret_cast<int64_t &>(x);
cout<<i<<endl;
output >>> i = -1548698869907112442

扩孔也是如此x,y。一旦我有了“重新解释”的值,我想将它们用作 Morton 编码的子程序。

我检查了上面的类型转换,它反向工作正常

double y = reinterpret_cast<double &>(i);
cout<<setprecision(16)<<y<<endl;
output>>-1.123456789123456e+205

我设法找到了一些 Morton 编码的代码,甚至在这个论坛上找到了一些代码,但没有一个用于int64_t3D。因此,我将需要论坛上专家的帮助,了解如何对int64_t整数进行编码和解码。

我设法对以下代码进行了逆向工程。不幸的是,有一些错误,当我运行解码部分时,我没有得到正确的数字。我将不胜感激任何帮助找出问题所在。

2D morton 代码编码/解码 64 位

#include <iostream>
#include <stdint.h>
#include<iomanip>

using namespace std;

uint64_t code_2D_M(double xd,double yd){

uint64_t x = reinterpret_cast<uint64_t& >(xd);
uint64_t y = reinterpret_cast<uint64_t& >(yd);

x = (x | (x << 16)) & 0x0000FFFF0000FFFF;
x = (x | (x << 8)) & 0x00FF00FF00FF00FF;
x = (x | (x << 4)) & 0x0F0F0F0F0F0F0F0F;
x = (x | (x << 2)) & 0x3333333333333333;
x = (x | (x << 1)) & 0x5555555555555555;

y = (y | (y << 16)) & 0x0000FFFF0000FFFF;
y = (y | (y << 8)) & 0x00FF00FF00FF00FF;
y = (y | (y << 4)) & 0x0F0F0F0F0F0F0F0F;
y = (y | (y << 2)) & 0x3333333333333333;
y = (y | (y << 1)) & 0x5555555555555555;

return x | (y << 1);

}


uint64_t code_3D_M(double xd,double yd,double zd){


uint64_t x = reinterpret_cast<uint64_t& >(xd);
uint64_t y = reinterpret_cast<uint64_t& >(yd);
uint64_t z = reinterpret_cast<uint64_t& >(zd);

x = (x | (x << 16)) & 0x0000FFFF0000FFFF;
x = (x | (x << 8)) & 0x00FF00FF00FF00FF;
x = (x | (x << 4)) & 0x0F0F0F0F0F0F0F0F;
x = (x | (x << 2)) & 0x3333333333333333;
x = (x | (x << 1)) & 0x5555555555555555;

y = (y | (y << 16)) & 0x0000FFFF0000FFFF;
y = (y | (y << 8)) & 0x00FF00FF00FF00FF;
y = (y | (y << 4)) & 0x0F0F0F0F0F0F0F0F;
y = (y | (y << 2)) & 0x3333333333333333;
y = (y | (y << 1)) & 0x5555555555555555;

z = (y | (y << 16)) & 0x0000FFFF0000FFFF;
z = (y | (y << 8)) & 0x00FF00FF00FF00FF;
z = (y | (y << 4)) & 0x0F0F0F0F0F0F0F0F;
z = (y | (y << 2)) & 0x3333333333333333;
z = (y | (y << 1)) & 0x5555555555555555;

return x | (y << 1) | (z << 2);

}

double decode_M(uint64_t x)
{
    x = x & 0x5555555555555555;
    x = (x | (x >> 1)) & 0x3333333333333333;
    x = (x | (x >> 2)) & 0x0F0F0F0F0F0F0F0F;
    x = (x | (x >> 4)) & 0x00FF00FF00FF00FF;
    x = (x | (x >> 8)) & 0x0000FFFF0000FFFF;
    x = (x | (x >> 16)) & 0xFFFFFFFFFFFFFFFF;
    return reinterpret_cast<double& >(x);
}


int main (void){

uint64_t  mort;
double  x,y,z;

// test input
x=2.123456789123459E205;
y=1.789789123456129E205;
z=9.999999912345779E205;

// echo the input
cout<<setprecision(17)<<x<<endl;
cout<<setprecision(17)<<y<<endl;
cout<<setprecision(17)<<z<<endl;

// encode 2D case
mort = code_2D_M(x,y);
//decode and print the results to see if all was fine
cout<<setprecision(17)<<decode_M(mort>>0)<<endl;
cout<<setprecision(17)<<decode_M(mort>>1)<<endl;

// encode 3D case
mort = code_3D_M(x,y,z);
//decode and print the results to see if all was fine
cout<<setprecision(17)<<decode_M(mort>>0)<<endl;
cout<<setprecision(17)<<decode_M(mort>>1)<<endl;
cout<<setprecision(17)<<decode_M(mort>>2)<<endl;



return 0;
}

我这样做是因为我不想将坐标存储为 3D 点 (x,y,z),而是存储为单个长整数并在需要时对其进行解码。通过这样做,我会将坐标存储数组的大小减小 3 倍。

4

0 回答 0