Vector 如何编码27矢量3';s转换为0-256的值?

Vector 如何编码27矢量3';s转换为0-256的值?,vector,types,geometry,mesh,voxel,Vector,Types,Geometry,Mesh,Voxel,我有27个类型为-1到1的3个值的组合: Vector3(0,0,0); Vector3(-1,0,0); Vector3(0,-1,0); Vector3(0,0,-1); Vector3(-1,-1,0); ... up to Vector3(0,1,1); Vector3(1,1,1); 我需要将它们转换为8位sbyte/字节数组,也需要将它们转换为8位sbyte/字节数组 一种解决方案是说256=X的第一个数字,第二个数字是Y,第三个数字是Z 所以 我更喜欢用一种更紧凑

我有27个类型为-1到1的3个值的组合:

 Vector3(0,0,0);
 Vector3(-1,0,0);
 Vector3(0,-1,0);
 Vector3(0,0,-1);
 Vector3(-1,-1,0);
 ... up to
 Vector3(0,1,1);
 Vector3(1,1,1);
我需要将它们转换为8位sbyte/字节数组,也需要将它们转换为8位sbyte/字节数组

一种解决方案是说256=X的第一个数字,第二个数字是Y,第三个数字是Z

所以

我更喜欢用一种更紧凑的方式来编码,也许是使用字节(我对此一无所知),因为上面的解决方案使用了很多乘法和圆函数来解码,你有什么建议吗?另一个选项是写入27,如果要将Vector3组合写入一个数组,则效率似乎很低

多亏了Evil Tak的指导,我稍微修改了代码,将0-1值添加到第一位,并将其调整为适用于unity3d:

function Pack4(x:int,y:int,z:int,w:int):sbyte {
var b: sbyte = 0;

b |= (x + 1) << 6; 
b |= (y + 1) << 4;
b |= (z + 1) << 2;
b |= (w + 1);   
return b;
}

function unPack4(b:sbyte):Vector4 {
var v : Vector4; 
v.x = ((b & 0xC0) >> 6) - 1;      //0xC0 == 1100 0000   
v.y = ((b & 0x30) >> 4) - 1;    // 0x30 == 0011 0000
v.z = ((b & 0xC) >> 2) - 1;     // 0xC  == 0000 1100
v.w = (b  & 0x3) - 1;            // 0x3  == 0000 0011
return v;
}
函数包4(x:int,y:int,z:int,w:int):sbyte{
变量b:sbyte=0;
b |=(x+1)>4)-1;//0x30==00110000
v、 z=((b&0xC)>>2)-1;//0xC==0000 1100
v、 w=(b&0x3)-1;//0x3==0000 0011
返回v;
}

一种方法是将每个向量的分量存储在字节的每2位中

将矢量分量值转换为2位存储形式和从2位存储形式转换矢量分量值,只需分别加1和减1即可

-1 (1111 1111 as a signed byte) <-> 00 (in binary)
 0 (0000 0000 in binary)        <-> 01 (in binary)
 1 (0000 0001 in binary)        <-> 10 (in binary)
将向量从字节形式解包如下:

byte Pack(Vector3<int> vector) {
    byte b = 0;
    b |= (vector.x + 1) << 4; 
    b |= (vector.y + 1) << 2;
    b |= (vector.z + 1);
    return b;
}
Vector3<int> Unpack(byte b) {
    Vector3<int> v = new Vector<int>();
    v.x = ((b & 0x30) >> 4) - 1;    // 0x30 == 0011 0000
    v.y = ((b & 0xC) >> 2) - 1;     // 0xC == 0000 1100
    v.z = (b & 0x3) - 1;     // 0x3 == 0000 0011
    return v;
}
Vector3解包(字节b){
Vector3 v=新向量();
v、 x=((b&0x30)>>4)-1;//0x30==00110000
v、 y=((b&0xC)>>2)-1;//0xC==0000 1100
v、 z=(b&0x3)-1;//0x3==0000 0011
返回v;
}
上述两种方法均假定输入有效,即
Pack
vector
的所有组件都是
-1
0
1
,并且
解包
b
的所有两位部分的(二进制)值都是
00
01
10


由于该方法使用位运算符,因此速度快且效率高。如果您希望进一步压缩数据,也可以尝试使用2个未使用的位,并将处理过的每3个2位元素转换为一个向量。

一种方法是将每个向量的分量存储在字节的每2位中

将矢量分量值转换为2位存储形式和从2位存储形式转换矢量分量值,只需分别加1和减1即可

-1 (1111 1111 as a signed byte) <-> 00 (in binary)
 0 (0000 0000 in binary)        <-> 01 (in binary)
 1 (0000 0001 in binary)        <-> 10 (in binary)
将向量从字节形式解包如下:

byte Pack(Vector3<int> vector) {
    byte b = 0;
    b |= (vector.x + 1) << 4; 
    b |= (vector.y + 1) << 2;
    b |= (vector.z + 1);
    return b;
}
Vector3<int> Unpack(byte b) {
    Vector3<int> v = new Vector<int>();
    v.x = ((b & 0x30) >> 4) - 1;    // 0x30 == 0011 0000
    v.y = ((b & 0xC) >> 2) - 1;     // 0xC == 0000 1100
    v.z = (b & 0x3) - 1;     // 0x3 == 0000 0011
    return v;
}
Vector3解包(字节b){
Vector3 v=新向量();
v、 x=((b&0x30)>>4)-1;//0x30==00110000
v、 y=((b&0xC)>>2)-1;//0xC==0000 1100
v、 z=(b&0x3)-1;//0x3==0000 0011
返回v;
}
上述两种方法均假定输入有效,即
Pack
vector
的所有组件都是
-1
0
1
,并且
解包
b
的所有两位部分的(二进制)值都是
00
01
10


由于该方法使用位运算符,因此速度快且效率高。如果您希望进一步压缩数据,也可以尝试使用2个未使用的位,并将每3个处理过的两位元素转换为一个向量。

最简洁的方法是在基
3
中写入一个
27
位数(使用shift
-1->0
0->1
1->2

此数字的值范围为
0
3^27-1=7625597484987
,需要编码
43位,即
6个字节(和
5
备用位)

与压缩表示法相比,压缩表示法在一个字节中压缩了
4
两位数字(因此总共
7
bytes/
56


一个有趣的变体是将基本
3
数字按字节五乘五分组(因此数字
0
242
)。您仍然需要
6
字节(并且没有多余的位),但是字节的解码可以很容易地硬编码为
243
条目表。

最简洁的方法是在基
3
中写入
27
数字(使用移位
-1->0
0->1
1
2

此数字的值范围为
0
3^27-1=7625597484987
,需要编码
43位,即
6个字节(和
5
备用位)

与压缩表示法相比,压缩表示法在一个字节中压缩了
4
两位数字(因此总共
7
bytes/
56

一个有趣的变体是将基本
3
数字按字节五乘五分组(因此数字
0
242
)。您仍然需要
6
字节(并且没有备用位),但是字节的解码可以很容易地硬编码为
243
条目表

  • 我假设您的值是
    浮点
    非整数

    因此,与转换为整数类型相比,位操作不会提高太多速度。所以我用全范围下注会更好。我会为3D案例这样做:

    8 bit -> 256 values
    3D -> pow(256,1/3) = ~ 6.349 values per dimension
    6^3 = 216 < 256
    
    其思想是将
    转换为范围
    ,因此将
    +1.0
    *3.0
    而不是
    *6.0
    ,然后只需乘以最后的字节中的正确位置即可

    p
    的解包如下所示:

    x=p%6;x=(x/3.0)-1.0;p/=6;
    y=p%6;y=(y/3.0)-1.0;p/=6;
    z=p%6;z=(z/3.0)-1.0;
    
    通过这种方式,您可以从256个值中使用216,这比仅使用2位(4个值)要好得多。您的4D案例看起来很相似,只需使用
    3.0,6.0
    不同的常量
    floor(pow(256,1/4))=4
    ,因此使用
    2.0,4.0
    ,但要注意
    p=256
    时的案例,或者像公认的答案一样,使用每个维度2位和位方法

    如果你需要真正的速度,你可以选择