Упорядочение Мортона в 3D, используя в качестве входных данных unit64_t

Я пытаюсь использовать код Мортона для создания уникальной кодировки для заданного (x,y,z), где x, y, z - числа с плавающей запятой двойной точности. Я предполагаю, что могу использовать приведение типов, чтобы преобразовать числа с плавающей точкой в ​​целые числа и выполнить упорядочение Мортона по этим целым числам. Например, рассмотрим следующее C++ код. (Я не знаю, как сделать то же самое в C)

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

И то же самое для расширения x,y, Как только у меня появятся "переосмысленные" значения, я бы хотел использовать их в качестве подпрограммы для кодирования Мортона.

Я проверил приведенное выше приведение типа, и он работал нормально в обратном порядке

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

Мне удалось найти некоторые коды для кодирования Мортона, даже некоторые из них на этом форуме, но ни один из них не использовал int64_t в 3D. Поэтому мне понадобится помощь экспертов на форуме, как кодировать и декодировать 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;
}

Я делаю это, потому что я хотел бы сохранить координаты не как трехмерную точку (x,y,z), а как одно длинное целое число и декодировать их при необходимости. Тем самым я уменьшу размер моего массива хранения координат в 3 раза.

0 ответов

Другие вопросы по тегам