void addBem(){ signal(SIGALRM,SIG_IGN); if(reverse==0) insertBody(Tail->prev,Tail); else insertBody(Head,Head->next); signal(SIGALRM,whileBem); }
void BHTree::insertBody(BHTree& node, const Body& b) { if(!node.hasBody && !node.isInternalNode) {//empty node node.body = b; node.hasBody = true; updateTotalAndCenterMass(node, b); } else if(node.isInternalNode) {//internal node //update total and center of mass updateTotalAndCenterMass(node, b); //recursively insert into correct quadrant BHTree& correctQuad = getCorrectQuadForBody(node, b); insertBody(correctQuad, b); } else { //external node that already contains a body //In order to avoid stack overflow when 2 bodies happen to be extrememly close to each other, //we will not try to subdivide a node further if the tree is already too deep. Instead we will simply update //the lowest nodes mass and center of mass with the new body (essentially just 'cramming' more than one body //into a single node) if(node.treeDepth < MAX_TREE_DEPTH) { node.subdivide(); Body& existingBody = node.body; node.hasBody = false; BHTree& correctQuadForNewBody = getCorrectQuadForBody(node, b); BHTree& correctQuadForExistingBody = getCorrectQuadForBody(node, existingBody); insertBody(correctQuadForNewBody, b); insertBody(correctQuadForExistingBody, existingBody); } else { std::cout << "MAX_TREE_DEPTH reached" << std::endl; } //update total and center of mass updateTotalAndCenterMass(node, b); } }
void BarnesHutTree::insertBody(const Body& body) { //If there's not a body there already, put the body there. if (m_bodyInTree.mass() == 0) { m_bodyInTree.set_mass(body.mass()); m_bodyInTree.set_xPosition(body.xPosition()); m_bodyInTree.set_yPosition(body.yPosition()); m_bodyInTree.set_zPosition(body.zPosition()); } //If there's already a body there, but it's not an external node //combine the two bodies and figure out which quadrant of the //tree it should be located in. Then recursively update the nodes below it. else if (isExternal() == false) { double newMass = m_bodyInTree.mass() + body.mass(); m_bodyInTree.set_xPosition((m_bodyInTree.xPosition()*m_bodyInTree.mass() + body.xPosition()*body.mass()) / newMass); m_bodyInTree.set_yPosition((m_bodyInTree.yPosition()*m_bodyInTree.mass() + body.yPosition()*body.mass()) / newMass); m_bodyInTree.set_zPosition((m_bodyInTree.zPosition()*m_bodyInTree.mass() + body.zPosition()*body.mass()) / newMass); m_bodyInTree.set_mass(m_bodyInTree.mass() + body.mass()); if (body.isInQuadrant(m_Quadrant.NWQuad())) { if (!m_NW) { m_NW = new BarnesHutTree(m_Quadrant.NWQuad()); } m_NW->insertBody(body); } else if (body.isInQuadrant(m_Quadrant.NEQuad())) { if (!m_NE) { m_NE = new BarnesHutTree(m_Quadrant.NEQuad()); } m_NE->insertBody(body); } else if (body.isInQuadrant(m_Quadrant.SWQuad())) { if (!m_SW) { m_SW = new BarnesHutTree(m_Quadrant.SWQuad()); } m_SW->insertBody(body); } else if (body.isInQuadrant(m_Quadrant.SEQuad())) { if (!m_SE) { m_SE = new BarnesHutTree(m_Quadrant.SEQuad()); }; m_SE->insertBody(body); }; } //If the node is external and contains one other body, create BHTrees //where the bodies should go, update the node, and end //(do not do anything recursively) else if (isExternal() == true) { //there is only one body in this tree if (m_bodyInTree.isInQuadrant(m_Quadrant.NWQuad())) { if (!m_NW) { m_NW = new BarnesHutTree(m_Quadrant.NWQuad()); }; m_NW->insertBody(m_bodyInTree); } else if (m_bodyInTree.isInQuadrant(m_Quadrant.NEQuad())) { if (!m_NE) { m_NE = new BarnesHutTree(m_Quadrant.NEQuad()); }; m_NE->insertBody(m_bodyInTree); } else if (m_bodyInTree.isInQuadrant(m_Quadrant.SWQuad())) { if (!m_SW) { m_SW = new BarnesHutTree(m_Quadrant.SWQuad()); }; m_SW->insertBody(m_bodyInTree); } else if (m_bodyInTree.isInQuadrant(m_Quadrant.SEQuad())) { if (!m_SE) { m_SE = new BarnesHutTree(m_Quadrant.SEQuad()); }; m_SE->insertBody(m_bodyInTree); } insertBody(body); } };