Quadtree implementation problematic due to class recursion!

Hi everbody,

I’m currently trying to implement a version of the Quadtree algorithm in OF for a project of mine.
I have trouble getting the class/object recursion to work properly. I’ve introduced unique pointers to circumvent an issue with infinite memory allocation, when declaring/instantiating the QuadTree class within itself.
The problem is, I’m kind of new to C++ (not coding in general) and still learning about memory management.

ofApp.h:

#pragma once

#include "ofMain.h"
#include "quadTree.h"

class ofApp : public ofBaseApp{

	public:
		void setup();
		void update();
		void draw();
    
    ofRectangle boundary;
    unique_ptr<QuadTree> qtree = nullptr;
    
};

ofApp.cpp:

#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){
    
    boundary = ofRectangle(200, 200, 200, 200);
    qtree = make_unique<QuadTree> (boundary, 4);
    
    for (int i = 0; i < 100; i++) {
        ofVec2f pt = ofVec2f(ofRandomWidth(), ofRandomHeight());
        qtree -> insert(pt);
    }
    
}

//--------------------------------------------------------------
void ofApp::update(){

}

//--------------------------------------------------------------
void ofApp::draw(){
    
    qtree -> draw();
    
}

quadTree.h:

#ifndef quadTree_h
#define quadTree_h

#include <stdio.h>
#include "ofMain.h"

class QuadTree {
    
public:
    QuadTree(ofRectangle _boundary, int _capacity);
    
    void subdivide();
    bool insert(ofVec2f _point);
    void draw();
    
    unique_ptr<QuadTree> north_east = nullptr;
    unique_ptr<QuadTree> north_west = nullptr;
    unique_ptr<QuadTree> south_east = nullptr;
    unique_ptr<QuadTree> south_west = nullptr;
    
private:
    ofRectangle boundary;
    int capacity;
    vector<ofVec2f> points;
    bool is_divided;

};

#endif

quadTree.cpp:

#include "quadTree.h"

QuadTree::QuadTree(ofRectangle _boundary, int _capacity) {
    boundary = _boundary;
    capacity = _capacity;
    is_divided = false;
}

void QuadTree::subdivide() {
    ofRectangle ne = ofRectangle(boundary.x + boundary.width / 2,
                                 boundary.y - boundary.height / 2,
                                 boundary.width / 2,
                                 boundary.height / 2);
    north_east = make_unique<QuadTree> (ne, capacity);
    ofRectangle nw = ofRectangle(boundary.x - boundary.width / 2,
                                 boundary.y - boundary.height / 2,
                                 boundary.width / 2,
                                 boundary.height / 2);
    north_west = make_unique<QuadTree> (nw, capacity);
    ofRectangle se = ofRectangle(boundary.x + boundary.width / 2,
                                 boundary.y + boundary.height / 2,
                                 boundary.width / 2,
                                 boundary.height / 2);
    south_east = make_unique<QuadTree> (se, capacity);
    ofRectangle sw = ofRectangle(boundary.x - boundary.width / 2,
                                 boundary.y + boundary.height / 2,
                                 boundary.width / 2,
                                 boundary.height / 2);
    south_west = make_unique<QuadTree> (sw, capacity);
    is_divided = true;
}

bool QuadTree::insert(ofVec2f _point) {
    
    if (!boundary.inside(_point.x, _point.y)) {
        return false;
    }
    
    if (points.size() < capacity) {
        points.push_back(_point);
        return true;
    } else {
        if (!is_divided) {
            subdivide();
        }
        if (north_east -> insert(_point)) {
            return true;
        } else if (north_west -> insert(_point)) {
            return true;
        } else if (south_east -> insert(_point)) {
            return true;
        } else if (south_west -> insert(_point)) {
            return true;
        }
    }
}

void QuadTree::draw() {
    ofSetColor(255);
    ofNoFill();
    ofSetRectMode(OF_RECTMODE_CENTER);
    ofDrawRectangle(boundary.x, boundary.y,
                    boundary.width * 2, boundary.height * 2);
    
    if (is_divided) {
        north_east -> draw();
        north_west -> draw();
        south_east -> draw();
        south_west -> draw();
    }
    
    for (int i = 0; i < points.size(); i++) {
        ofSetColor(255);
        ofFill();
        ofDrawCircle(points[i].y, points[i].y, 1);
    }
}

I’d be grateful for a couple of pointers to get this working (if possible). :wink:

Thanks.