示例#1
0
文件: Bem.c 项目: flack3r/Snake
void addBem(){	
	signal(SIGALRM,SIG_IGN);
	
	if(reverse==0)
		insertBody(Tail->prev,Tail);
	else
		insertBody(Head,Head->next);
	signal(SIGALRM,whileBem);
}
示例#2
0
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);
	}
};