#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; unsigned long nodes = 0; 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); vector<Body> localBodies = current->getBodies(); TreeNode* after = current->next; current->leaf = false; for (vector<Box>::iterator bit = subboxes.begin(); bit != subboxes.end(); bit++) { TreeNode* child = new TreeNode(this); nodes++; child->bb = *bit; child->bodies = bit->containedBodies(localBodies); current->next->insertBefore(child); child->afterSubtree = (bit == subboxes.begin()) ? current->afterSubtree : child->next; } current->bodies.clear(); } current = current->next; } cout << "nodes " << nodes << endl; } }