У меня очень большое облако точек (> 100000 точек), в котором я хотел бы обнаруживать планарные расположения. Я решил использовать октодерево, чтобы разбить точки на очень маленькие плоские кластеры, а затем объединить соседние кластеры, которые находятся в одной плоскости.Я написал код на C ++, который быстро разбивает облако точек на небольшие плоские кластеры, но как эффективно объединить их, ускользает от меня ...
Моя Octree
реализация использует структуру указателей: есть OctreeNode
s с массивами OctreeNode* children[8]
, содержащими указатели на их дочерние узлы, или все NULL
указатели, если это листовой узел.
Сначала я думал, чтобы в каждом объекте OctreeNode
сохранялся указатель наPlane
объект.После первого разбиения точек каждый лист в октрее получит Plane
, представляющий наименьшие квадраты, подходящие ко всем точкам, содержащимся в листе.Затем я перебираю каждый листовой узел дерева.Для каждого конечного узла я проверяю каждый из его соседних конечных узлов: если плоскость соседа должна быть объединена с плоскостью текущего конечного узла, я вызываю Plane* newPlane = Plane::mergePlanes(this->plane, neighbor->plane);
, чтобы создать новую плоскость, которая представляет точки в обоих узлах.
Здесь я столкнулся с проблемой ... Сначала я подумал, что могу просто заменить обе плоскости новой плоскостью, то есть plane = newPlane; neighbor->plane = newPlane;
, и все будет сделано (утечка памяти в стороне; я справился с ними в реальномкод).К сожалению, это не работает на практике.После объединения нескольких плоскостей может быть несколько различных OctreeNode
, указывающих на один Plane
, и простая замена указателей в this->plane
и neighbor->plane
не заменяет КАЖДЫЙ указатель, указывающий на их старые плоскости.
Решение выглядело хакерским, даже когда я впервые его придумал, а теперь его недостатки еще более очевидны.Кто-нибудь может придумать способ исправить метод объединения, который я придумал, или придумать лучший способ?
Спасибо