Как реализовать сортировку координат по оси z для массовой вставки Quad-Tree — C++

Согласно улучшенным алгоритмам массовой загрузки для деревьев квадрантов, сортировка координат в Z-порядок перед вставкой приведет к ускорению пакетной вставки QuadTree.

Мне нужна реализация z-порядка на С++. У меня есть координаты x, y как double. Решение здесь, в Википедии, для Z-Order-Curves мне немного непонятно.

EDIT - предположения Координаты, которые у меня есть, находятся в координатах Google и представляют собой числа с плавающей запятой. В системе, которую мы в настоящее время разрабатываем, мы предполагаем, что любая большая часть (партия), которую нужно вставить, помещается в ОЗУ. Мы не предполагаем необходимости внешних операций сортировки с переключением между диском и памятью.

EDIT 2 в связи с тем, что Z-порядок работает только для целых чисел, я думаю, что хитрость заключается в умножении на 10, пока все данные не будут целыми числами. Как только я это сделаю, как выполнить z-порядок по точкам?


person Saher Ahwal    schedule 14.04.2014    source источник
comment
Насколько мне известно, Z-порядок не определен (или не может быть определен) в дробных координатах.   -  person harold    schedule 14.04.2014
comment
@harold, диагональный аргумент предполагает обратное.   -  person OmnipotentEntity    schedule 16.04.2014
comment
@harold см. редактирование. Простой трюк с масштабированием точек избавит от дробей.   -  person Saher Ahwal    schedule 16.04.2014
comment
@Saher, вы можете переосмыслить приведение к uint64_t и Z-порядку. Однако это либо неопределенное поведение, либо поведение, определенное реализацией.   -  person OmnipotentEntity    schedule 16.04.2014
comment
хорошо звучит хорошо, но как мне сделать z-порядок, я не уверен, что четко описан алгоритм, который я должен использовать для выполнения заказа. Спасибо   -  person Saher Ahwal    schedule 16.04.2014
comment
@Saher, я напишу что-нибудь об этом с версией переинтерпретации, которая избегает UB (я думаю ...)   -  person OmnipotentEntity    schedule 16.04.2014


Ответы (1)


Это непроверенный код, вы должны дважды проверить, работает ли он.

Кроме того, этот код почти наверняка не является переносимым и может даже иметь неопределенное поведение. Это, безусловно, поведение, определяемое реализацией, по крайней мере, но оно, вероятно, не указано... Мне нужно более внимательно прочитать правила, касающиеся reinterpret_cast в и из char*, чтобы знать наверняка.

#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
}
person OmnipotentEntity    schedule 16.04.2014
comment
Я запутался в отношении функции lessThanZOrderDouble? это принимает все координаты x и y, прямо как vector‹double› a и b? Если да, то как это выполняет сортировку, когда возвращает одно логическое значение для всего списка? - person Saher Ahwal; 16.04.2014
comment
Это функция меньшего размера, которую вы можете передать функции сортировки stl. - person OmnipotentEntity; 16.04.2014
comment
О, хорошо, так это функция сравнения? Но я думал, что функции сравнения принимают в качестве аргументов два значения, а не целые списки? Правильно? - person Saher Ahwal; 16.04.2014
comment
Для большей ясности я должен был использовать std::pair<double, double> для аргументов, потому что вы имеете дело только с двумя измерениями. Списки, переданные в функцию сравнения, являются вашими координатами. Вы сортируете список двойников, поэтому ваша функция сравнения должна принимать список двойников. - person OmnipotentEntity; 16.04.2014
comment
Большое спасибо за ответ. - person Saher Ahwal; 17.04.2014