我正在创建一个分块的QuadTree地形,我正在努力确保两个节点之间的细节差异不会超过一个级别。我当前的构造函数代码是这样的:
QuadNode::QuadNode(Rect area, QuadNode * p, QuadRoot * r)
{
Root = r;
Parent = p;
Level = p->Level + 1;
InitializeGeometry(area);
for(int iii = 0; iii < 4; iii++)
Children[iii] = 0;
for(int iii = 0; iii < 4; iii++)
{
if(QuadrantNeedsChild(iii))
Children[iii] = new QuadNode(GetRect(iii), this, Root);
}
}
这很好用。但是为了强制两个邻居节点之间的差异不超过一个级别,我试图将它添加到构造函数的末尾:
QuadNode * neighbour;
for(int direction = 0; direction < 4; direction++)
{
neighbour = FindNeighbour(direction);
if(neighbour)
{
while(Level - neighbour->Level > 1)
{
neighbour->Subdivide();
neighbour = FindNeighbour(direction);
//neighbour should now be a child of the previous neighbour
}
}
}
但是那个堆栈溢出了。我认为的一个原因是Children[iii] = new QuadNode(GetRect(iii), this, Root);
语句的赋值部分永远不会执行,而FindNeighbour()
要求将子代设置为找到正确的邻居。但我不认为这是唯一的问题,因为代码实际上从未到达第二行neighbour = FindNeighbour(direction);
,我不知道是什么导致了这一点。
如果我在树的基础创建之后在新函数中运行第二个代码片段它或多或少有效,但是它需要多次传递以确保新创建的节点本身不会创建级别差异&gt;因此,如果可能的话,我宁愿在构造函数中使用此代码。谁能想到实现这个目标的方法呢?
关于课程的一些注意事项,如果有帮助QuadrantNeedsChild(int quadrant)
确保水平从不超过8,所以我知道我不会太深入。 Subdivide()
只需在所有象限上运行Children[iii] = new QuadNode(GetRect(iii), this, Root);
。 FindNeighbour(int direction)
可以返回父级或祖先。例如,如果D正在寻找北邻居,那么如果B从未被细分为以下,它将获得其祖父母(整个图表):
- - - - - -
| | |
| A | B |
| | |
|- - - - - -|
| | D| |
| C |-----|
| | | |
- - - - - -
如果提供超出范围的象限,细分功能只会细分给定的象限或所有象限。
void QuadNode::Subdivide(int quadrant)
{
if(quadrant > -1 && quadrant < 4)
{
if(!Children[quadrant])
Children[quadrant] = new QuadNode(GetRect(quadrant), this, Root);
}
else
for(int iii = 0; iii < 4; iii++)
if(Children[iii] == 0)
Children[iii] = new QuadNode(GetRect(iii), this, Root);
}
答案 0 :(得分:2)
当构建节点的第一个子节点时,它是否找到它自己的父作为邻居,因为该父节点还没有子节点(第一个节点即将创建)? / p>
这会导致节点在其自己的父节点上调用Subdivide()
,这将构造一个新的子节点,它再次调用Subdivide()
,...
即使没有这个,在新级别上构建第一个节点将Subdivide()
所有它的邻居,它们将递归地细分这些邻居的所有邻居。这是它应该如何工作?对于最深层次,这将导致类似4 8 级别的递归。