如何实现四叉树批量插入坐标的z顺序排序 - C ++

时间:2014-04-14 03:55:02

标签: c++ bulkinsert z-order quadtree

根据Improved Bulk-Loading Algorithms for Quadtrees,在插入之前按z顺序排序坐标将导致QuadTree批量插入的加速。

我需要在C ++中实现z顺序。 我有x,y坐标double。维基百科中Z-Order-Curves的解决方案 对我来说有点不清楚。

编辑 - 假设 我拥有的坐标是谷歌坐标,是浮点数。 在我们目前开发的系统中,我们假设要插入的任何批量(批处理)都适合RAM。我们预计不需要在磁盘和内存之间进行外部排序操作。

编辑2 关于Z-order仅适用于整数这一事实,我认为诀窍是以10为因子倍数,直到所有数据都是整数。一旦我知道在点上执行z次序的方式是什么?

1 个答案:

答案 0 :(得分:1)

这是未经测试的代码,您应该仔细检查它是否有效。

此外,此代码几乎肯定不可移植,甚至可能是未定义的行为。它至少是实现定义的行为,但它可能没有明确规定......我必须更加仔细地阅读reinterpret_castchar*之间的规则,以确定无疑。

#include <cstdint>
#include <vector>

uint64_t reinterpretDoubleAsUInt(double d) {
  int const doubleSize = sizeof(double);
  char* array = reinterpret_cast<char*>(&d);
  uint64_t result = 0;
  for (auto i = 0; i < doubleSize; ++i) {
    result += (uint64_t)array[i] << (8*i);
  }

  return result;
}

bool lessThanZOrderDouble(std::vector<double> const& a, std::vector<double> const& b) {
  uint64_t j = 0;
  uint64_t x = 0;
  if (a.size() != b.size() || a.size() == 0) {
    throw std::exception();
  }

  int dimensions = a.size();

  for (auto i = 0; i < dimensions; ++i) {
    auto y = reinterpretDoubleAsUInt(a[i]) ^ reinterpretDoubleAsUInt(b[i]);
    if (x < y && x < (x ^ y)) {
      j = i;
      x = y;
    }
  }
  return (a[j] - b[j]) > 0;
}

int main() {
  // blank for compilation's sake
}