#include "BarnesHutTree.hpp" #include "TreeNode.hpp" #include <iostream> namespace nbody { using namespace std; BarnesHutTree::BarnesHutTree() { } BarnesHutTree::~BarnesHutTree() { } vector<Box> BarnesHutTree::splitBB(TreeNode* 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) { TreeNode* current; this->clean(); if (bodies.empty()) return; //insert root node this->nodes->insertAfter(new TreeNode(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->isCorrect()) { cout << "node before split incorrect" << endl; return; } if (current->isSplitable()) { vector<Box> subboxes = this->splitBB(current); current->leaf = false; for (vector<Box>::iterator it = subboxes.begin(); it != subboxes.end(); it++) { TreeNode* child = new TreeNode(this); child->bb = *it; //TODO: move bodies child->bodies = it->containedBodies(current->bodies); current->insertAfter(child); if (it != subboxes.begin()) { child->afterSubtree = child->next; } else { child->afterSubtree = current->afterSubtree; } } current->bodies.clear(); } current = current->next; } } }