如果我有一个数据集,其中键是3D中的点,由3个带符号的64位整数表示。我想使用(排序的)键值存储来存储它们,其中键只是字节数组(但我可以指定一个比较器)。我想我可以通过使用位交错将所有这些点转换为字节数组,就像在How to compute a 3D Morton number
中使用Z / Morton顺序一样除了获取单个点之外,没有Morton排序可以更简单地完成,我想进行范围搜索,我在一个与轴对齐的框中搜索。我将A和B分别定义为所有坐标最低的框角,以及所有坐标最高的对角。
现在我的问题是:
对于任何在逻辑上介于A和B之间的C点,C的Morton数是否也介于A和B的Morton数之间? (这不是莫顿的命令吗?)
如果1为否,A和B是否可以“舍入”到保证将包含C的值?
假设1或2是可能的,搜索返回也指向该框之外,我必须“后过滤”吗? “错误集”有多大(它取决于搜索的大小或位置)?
整数是否已签名会导致问题?如果是这样,是否有解决方法?
回顾一下,使用Morton Numbers只是实际问题的一种可能解决方案:当3D点必须映射到一维值时,如何有效地在3D整数空间中进行范围搜索?我希望通过使用min-key和max-key在数据库中执行单个范围选择来获得A和B之间的所有点,,理想情况下,在框外获得尽可能少的点尽可能。
答案 0 :(得分:7)
4)是的,这个标志会引起一个问题,但要解决这个问题很简单。
在创建Morton编号之前,将x,y和z的符号位与X进行异或。
为什么会这样(使用1维签名字节代替):
二进制中的-1是11111111
二进制中的0是00000000
二进制的1是00000001
您想要的顺序是-1,0,1,但当前的二进制顺序是0,1,-1。
-1 XOR 10000000 = 01111111
0 XOR 10000000 = 10000000
1 XOR 10000000 = 10000001
现在你的二进制订单是正确的
答案 1 :(得分:2)
好像我必须自己回答我的问题。答案将与z阶曲线相关,这就是我实际要求的。就我而言:
我所说的似乎并不清楚,所以我会做一点ASCII艺术......
2D中的基本Z阶(Morton阶)曲线如下所示(路径为A,B,C,D):
x 0 1
0 A B
1 C D
所以,A =(0,0)B =(0,1)C =(1,0)D =(1,1)
现在2D中的基本希尔伯特曲线就像这样(路径是A,B,C,D):
x 0 1
0 A D
1 B C
所以,A =(0,0)B =(1,0)C =(1,1)D =(0,1)
使用Z顺序(Morton顺序),曲线将从最低点A(0,0)开始,以最高点D(1,1)结束,同时覆盖其间的所有点。这使得范围搜索变得容易,并且它也可以在3D中工作。 3D框(0,0,0)到(1,1,1)中的所有点都在Morton订单代码(0,0,0)和(1,1,1)之间。
使用希尔伯特曲线,从(0,0)开始到(0,1)结束(在3D中可能相似)。因此,从Hilbert代码(0,0)到(1,1)执行范围查询将找不到所有点。
因此,如果我使用希尔伯特曲线来执行3D框(0,0,0)到(1,1,1)的范围查询(作为单个数据库查询),我需要一个函数告诉我应该用什么点作为第一点,我应该用什么点作为最后一点,因为(0,0,0)和(1,1,1)将不起作用。
那么,是否有这样的功能,你给你的8(用于3D)框坐标,它返回你的范围查询中使用的第一个和最后一个点?没有它,我不能用希尔伯特曲线来解决我的问题。
或者,在伪SQL中:
莫顿查询: SELECT键,数据FROM表WHERE(键> = Morton(最低(框)))AND(键< = Morton(最高(框)))
希尔伯特查询: SELECT键,数据FROM表WHERE(键> = Hilbert(XXX(方框)))AND(键< = Hilbert(YYY(方框)))
所以我需要XXX()和YYY()。
[编辑]这个答案的一部分是针对一些其他答案,告诉我使用希尔伯特曲线,但后来删除了他们的答案。
答案 2 :(得分:-1)
一般来说,尝试将3维减少到1维并不是很多。您可以尝试的方法:找到主轴(即通过您的点做一条线),然后将点投影到线上。这为您提供了每个点所需的一维值。当您将方框的角投射到线上并采用这些值的封闭间隔时,您将获得搜索范围。