改进我的四叉树设计
Improving my quadtree design?
我有一个应用程序,用于显示和修改来自激光雷达文件的大量点云数据(每个文件高达几GB,有时同时加载)。在应用程序中,用户可以查看加载点的2D图像(从顶部),并选择要在另一个窗口中查看的配置文件(从侧面)。同样,这涉及数百万个点,它们使用OpenGL进行显示。
为了处理数据,还有一个四叉树库,它可以工作,但速度非常慢。它已经使用了一段时间,但最近激光雷达点格式发生了变化,LidarPoint对象需要添加一些属性(类成员),这导致它的大小增加,进而影响性能达到几乎不可用的水平(加载一个2GB文件需要5分钟)。
四叉树目前由指向PointBucket对象的指针组成,这些对象只是具有指定容量和定义边界(用于空间查询)的LidarPoint对象的数组。如果超过铲斗容量,它将分成四个铲斗。还有一种缓存系统,当点数据占用太多内存时,它会导致点存储桶转储到磁盘。如果需要的话,这些会被重新加载到内存中。最后,每个PointBucket都包含子数据块/分辨率级别,它们保存原始数据的第n个点,并在根据缩放级别显示数据时使用。这是因为一次显示几百万个点,虽然不需要这样的细节级别,但速度非常慢。
我希望你能从中得到一张照片。如果没有,请询问,我可以提供更多的细节或上传更多的代码。例如,这里是当前(和慢速)插入方法:
// Insert in QuadTree
bool QuadtreeNode::insert(LidarPoint newPoint)
{
// if the point dosen't belong in this subset of the tree return false
if (newPoint.getX() < minX_ || newPoint.getX() > maxX_ ||
newPoint.getY() < minY_ || newPoint.getY() > maxY_)
{
return false;
}
else
{
// if the node has overflowed and is a leaf
if ((numberOfPoints_ + 1) > capacity_ && leaf_ == true)
{
splitNode();
// insert the new point that caused the overflow
if (a_->insert(newPoint))
{
return true;
}
if (b_->insert(newPoint))
{
return true;
}
if (c_->insert(newPoint))
{
return true;
}
if (d_->insert(newPoint))
{
return true;
}
throw OutOfBoundsException("failed to insert new point into any
of the four child nodes, big problem");
}
// if the node falls within the boundary but this node not a leaf
if (leaf_ == false)
{
return false;
}
// if the node falls within the boundary and will not cause an overflow
else
{
// insert new point
if (bucket_ == NULL)
{
bucket_ = new PointBucket(capacity_, minX_, minY_, maxX_, maxY_,
MCP_, instanceDirectory_, resolutionBase_,
numberOfResolutionLevels_);
}
bucket_->setPoint(newPoint);
numberOfPoints_++;
return true;
}
}
}
// Insert in PointBucket (quadtree holds pointers to PointBuckets which hold the points)
void PointBucket::setPoint(LidarPoint& newPoint)
{
//for each sub bucket
for (int k = 0; k < numberOfResolutionLevels_; ++k)
{
// check if the point falls into this subbucket (always falls into the big one)
if (((numberOfPoints_[0] + 1) % int(pow(resolutionBase_, k)) == 0))
{
if (!incache_[k])
cache(true, k);
// Update max/min intensity/Z values for the bucket.
if (newPoint.getIntensity() > maxIntensity_)
maxIntensity_ = newPoint.getIntensity();
else if (newPoint.getIntensity() < minIntensity_)
minIntensity_ = newPoint.getIntensity();
if (newPoint.getZ() > maxZ_)
maxZ_ = newPoint.getZ();
else if (newPoint.getZ() < minZ_)
minZ_ = newPoint.getZ();
points_[k][numberOfPoints_[k]] = newPoint;
numberOfPoints_[k]++;
}
}
}
现在我的问题是,你能想出一种方法来改进这个设计吗?在处理大量不适合内存的数据时,有哪些通用策略?如何提高四叉树的效率?有没有一种方法可以加快点的渲染速度?
现在我的问题是,你能想出一种方法来改进这个设计吗?
是:不要将对象本身存储在四叉树中。将它们放入一个平面结构(数组、链表等)中,让四叉树只保留一个指向实际对象的指针。如果四叉树有一定的深度(在所有节点上),也可以将其展平。
- 在我的四叉树实现中遇到问题
- 打印二叉树中的常见元素
- 如何有效地修剪和合并四叉树中的节点?
- 我有两棵二叉树.我想在不更改输入树的情况下深度复制两个二叉树的结果
- 二叉树中的删除
- C++打印二叉树中的所有值
- 如何在C++的四叉树中存储 bmp 文件?
- 如何提高四叉树代码的性能以防止程序冻结
- 如何修复关卡顺序遍历问题(二叉树)的无限循环错误
- 细分四叉树而不带新运算符
- 如何在UE4 / c++中可视化我的四叉树
- 四叉树递归检索
- 查询四叉树会导致溢出
- 如何有效地将游戏对象存储在四叉树中
- 用于碰撞检测实现的四叉树
- 在基于四叉树的LOD地形上寻找示例
- 改进我的四叉树设计
- 如何在没有递归的情况下清除四叉树(也许使用队列?).
- c++中任何好的范围查询库(使用K-D树,四叉树或r语言 - 树)
- 四叉树和构造函数中的区域大小