Vector 如何编码27矢量3';s转换为0-256的值?
我有27个类型为-1到1的3个值的组合: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 所以 我更喜欢用一种更紧凑
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位和位方法
如果你需要真正的速度,你可以选择