I am currently creating a Quadtree, and I have found while debugging, that a method in my class is not changing the value of a particular integer.
Here is my code:
Quadrant.h
#ifndef QUADRANT_H
#define QUADRANT_H
#include "Point.h"
#include "Boundary.h"
#include <iostream>
struct Quadrant : Boundary
{
Quadrant(const Boundary& AABB);
void subdivide(std::vector<Quadrant>& m_quadrantStorage); //splits the quadrant into four children.
bool insert(Point* pointnode, std::vector<Quadrant>& m_quadrantStorage);
std::vector<Point*> fetchPoints();
int firstChildindex; //stores the index of its first child. since the children are contiguous in the base array, you can find them by firstchild + i while 0<=i<4
Point* firstpointnode = nullptr; //stores the beginning of a point list which are all in this current quadrant.
int count = 0;
bool subdivided = false;
};
#endif
Quadrant.cpp
#include "Quadrant.h"
#include "Globals.h"
#include <iostream>
Quadrant::Quadrant(const Boundary& AABB)
:Boundary(AABB)
{
}
bool Quadrant::insert(Point* pointnode, std::vector<Quadrant>& m_quadrantStorage)
{
if (!this->contains(pointnode->position)) return false; //if the point isnt within this boundary, forget about it.
else if (count < QCAPACITY && !subdivided){ //otherwise if it is contained, and it isnt full, we can insert to the end of the point list.
if (firstpointnode == nullptr) {
firstpointnode = pointnode;
firstpointnode->next = nullptr;
}
else {
Point* currentpointnode = firstpointnode;
while (currentpointnode->next != nullptr) //traversing to the end of this quadrant point list
{
currentpointnode = currentpointnode->next;
}
currentpointnode->next = pointnode; // currentpointnode is the last node in the list by this point.
currentpointnode->next->next = nullptr; //disassociating any ties that the point had with any other points, so it is the absolute end of the list.
}
count++;
return true;
}
else{
if(!subdivided){//or if the point is within the quadrant, is full, and it hasnt already subdivided, subdivide.
subdivided = true;
count = 0;
subdivide(m_quadrantStorage);
firstpointnode = nullptr;
}
for (int i = 0; i < 4; i++) {
if (m_quadrantStorage[firstChildindex + i].insert(pointnode, m_quadrantStorage)) return true;
//std::cout << i << std::endl;
}
}
return false;
}
void Quadrant::subdivide(std::vector<Quadrant>& m_quadrantStorage)
{
sf::Vector2f newhalfsize = halfsize / float(2);
firstChildindex = m_quadrantStorage.size();//children are contiguous in memory - nth child = firstChildindex + n for 0<=n<4
m_quadrantStorage.emplace_back(Boundary{ sf::Vector2f { centre.x + newhalfsize.x, centre.y - newhalfsize.y }, newhalfsize });
m_quadrantStorage.emplace_back(Boundary{ sf::Vector2f { centre.x + newhalfsize.x, centre.y + newhalfsize.y }, newhalfsize });
m_quadrantStorage.emplace_back(Boundary{ sf::Vector2f { centre.x - newhalfsize.x, centre.y + newhalfsize.y }, newhalfsize });
m_quadrantStorage.emplace_back(Boundary{ sf::Vector2f { centre.x - newhalfsize.x, centre.y - newhalfsize.y }, newhalfsize });
Point* currentpointnode = firstpointnode;
while (currentpointnode!= nullptr) //transferring all points from parent list to children.
{
for (int i = 0; i < 4; i++)
{
m_quadrantStorage[firstChildindex + i].insert(currentpointnode, m_quadrantStorage);
}
currentpointnode = currentpointnode->next;
}
firstpointnode = nullptr; // this parent does not have a point anymore, so it is nullptr.
subdivided = true;
}
std::vector<Point*> Quadrant::fetchPoints()
{
std::vector<Point*> vec;
if (firstpointnode == nullptr) return vec;
Point* currentNode = firstpointnode;
while (currentNode->next != nullptr)
{
vec.emplace_back(currentNode);
currentNode = currentNode->next;
}
return vec;
}
In the Visual Studio Watch, I see that the void Quadrant::subdivide(std::vector<Quadrant>& m_quadrantStorage) instantaneously changes the value of firstChildindex to 1, as intended, but after the line is executed, it changes to a random garbage value, then back to 0.
I really do not understand why this is happening.
Subdivide function called. The line which changes the value of firstChildindex has just executed, and now the value of firstChildindex is 1 as intended.
Now, the value of firstChildindex is -572662307
And now firstChildindex has a value of 0!!