#include "BarnesHutTree.hpp" #include "Node.hpp" #include <iostream> namespace nbody { using namespace std; BarnesHutTree::BarnesHutTree() { } BarnesHutTree::~BarnesHutTree() { } vector<Box> BarnesHutTree::splitBB(Node* node) { vector<Box> result; for (unsigned int i = 0; i < 8; i++) { Box current = node->getBB(); for (unsigned int j = 0; j < 3; j++) { double middle = current.getMin(j) + (current.getMax(j) - current.getMin(j)) / 2.0; if (i & (1 << j)) { current.setMin(j, middle); } else { current.setMax(j, middle); } } result.push_back(current); } return result; } int BarnesHutTree::numberOfChildren() { return 8; } void BarnesHutTree::build(vector<Body> bodies) { Node* current; this->clean(); if (bodies.empty()) return; //insert root node this->nodes->insertAfter(new Node(this)); current = this->nodes->next; //assign bodies to root node current->bodies = bodies; //setup proper bounding box current->extendBBforBodies(); current->extendBBtoCube(); current->afterSubtree = current->next; //iterate over existing boxes and split if it contains too much bodies while (current != this->nodes) { if (current->isSplitable()) { vector<Box> subboxes = this->splitBB(current); current->leaf = false; for (vector<Box>::iterator it = subboxes.begin(); it != subboxes.end(); it++) { Node* child = new Node(this); child->parent = current; child->bb = *it; child->bodies = it->copyBodies(current->bodies); current->insertAfter(child); child->nextSibling = current->next; current->next->prevSibling = child; if (it != subboxes.begin()) { child->afterSubtree = child->next; } else { child->afterSubtree = current->afterSubtree; } } current->bodies.clear(); } current = current->next; } } }