Я создаю фрагментированный ландшафт 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);
строки, и я понятия не имею, чем это вызвано.
Если я запускаю этот второй фрагмент кода в новой функции после базового создания дерева, он более или менее работает, но тогда требуется несколько проходов, чтобы убедиться, что вновь созданные узлы сами не создают разницу уровней> 1. Итак, я ' Я бы предпочел иметь этот код в конструкторе, если это вообще возможно. Кто-нибудь может придумать способ достижения этого?
Несколько замечаний по классу на случай, если он поможет QuadrantNeedsChild(int quadrant)
гарантировать, что уровень никогда не превышает 8, так что я знаю, что я не слишком углубляюсь. Subdivide()
просто запускает Children[iii] = new QuadNode(GetRect(iii), this, Root);
во всех квадрантах. FindNeighbour(int direction)
может возвращать родителя или предка. Например, если D ищет северного соседа, он получит его прародителя (всю диаграмму), если B никогда не подразделялся следующим образом:
- - - - - -
| | |
| A | B |
| | |
|- - - - - -|
| | D| |
| C |-----|
| | | |
- - - - - -
Функция subdivide просто разделяет данный квадрант или все квадранты, если предоставляется квадрант вне диапазона.
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);
}
Subdivide
? - person jxh   schedule 15.06.2012