#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 (int i = 0; i < 8; i++) { Box current = node->getBB(); for (int j = 0; j < 3; j++) { double middle = node->getBB().getMin(j) + (node->getBB().getMax(j) - node->getBB().getMin(j)) / 2.0; if (i & (1 >> j)) { current.setMin(j, middle); } else { current.setMax(j, middle); } } result.push_back(current); } return result; } void BarnesHutTree::build(vector<Body> bodies) { TreeNode* current; unsigned long nodes = 0; this->clean(); if (bodies.empty()) return; this->nodes->insertAfter(new TreeNode(this)); current = this->nodes->next; current->bodies = bodies; current->extendBBforBodies(); current->extendBBtoCube(); while (current != this->nodes) { if (current->isSplitable()) { vector<Box> subboxes = this->splitBB(current); vector<Body> localBodies = current->getBodies(); TreeNode* after = current->next; 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); } for (TreeNode* child = current->next; child != after->prev; child = child->next) { child->afterSubtree = child->next; } after->prev->afterSubtree = after->afterSubtree; current->bodies.clear(); } current = current->next; } cout << "nodes " << nodes << endl; } }